icu4r 0.1.3.2006.01.26 → 0.1.4.2006.05.29

Sign up to get free protection for your applications and to get access to all the features.
data/icu4r.c CHANGED
@@ -3,6 +3,8 @@ extern void initialize_calendar(void);
3
3
  extern void initialize_uregexp(void);
4
4
  extern void initialize_ucore_ext(void);
5
5
  extern void initialize_ubundle(void);
6
+ extern void initialize_converter(void);
7
+ extern void initialize_collator(void);
6
8
  void Init_icu4r (void) {
7
9
 
8
10
  initialize_ustring();
@@ -10,5 +12,7 @@ void Init_icu4r (void) {
10
12
  initialize_ucore_ext();
11
13
  initialize_ubundle();
12
14
  initialize_calendar();
15
+ initialize_converter();
16
+ initialize_collator();
13
17
 
14
18
  }
@@ -23,7 +23,7 @@ typedef struct {
23
23
  long len;
24
24
  long capa;
25
25
  UChar *ptr;
26
- char busy;
26
+ unsigned char busy;
27
27
  } ICUString ;
28
28
  #define USTRING(obj) ((ICUString *)DATA_PTR(obj))
29
29
  #define UREGEX(obj) ((ICURegexp *)DATA_PTR(obj))
@@ -5,9 +5,9 @@ class UCalendarTest < Test::Unit::TestCase
5
5
 
6
6
  def test_time_zones
7
7
  v = UCalendar.time_zones
8
- assert_equal(v.size, 577)
9
- assert_equal( UString, v[0].class)
10
- assert_equal("ACT".u, v[0] )
8
+ assert_kind_of(Array, v)
9
+ assert_kind_of(UString, v[0])
10
+ assert(v.include?("Europe/Kiev".u))
11
11
  end
12
12
 
13
13
  def test_default
@@ -15,7 +15,8 @@ class UCalendarTest < Test::Unit::TestCase
15
15
  UCalendar.default_tz ="Europe/Paris".u
16
16
  assert_equal( "Europe/Paris".u, UCalendar.default_tz)
17
17
  c = UCalendar.new
18
- assert_equal( "GMT+01:00".u, c.time_zone)
18
+ assert_equal( 3_600_000, c[:zone_offset])
19
+ # assert_equal( "GMT+01:00".u, c.time_zone("root")) # this should work also
19
20
  end
20
21
 
21
22
  def test_dst
@@ -106,4 +107,17 @@ class UCalendarTest < Test::Unit::TestCase
106
107
  assert(!c.eql?(d))
107
108
  assert(c == d)
108
109
  end
110
+
111
+ def test_parse_date
112
+ UCalendar.default_tz="UTC".u
113
+ t1 = UCalendar.parse("HH:mm:ss E dd/MM/yyyy z".u, "en", "20:15:01 Fri 13/01/2006 GMT+00".u)
114
+ assert_equal(2006, t1[:year])
115
+ assert_equal(0, t1[:month])
116
+ assert_equal(13, t1[:date])
117
+ assert_equal(20, t1[:hour_of_day])
118
+ assert_equal(15, t1[:minute])
119
+ assert_equal(01, t1[:second])
120
+ end
121
+
122
+
109
123
  end
@@ -0,0 +1,33 @@
1
+ require './icu4r'
2
+ require 'test/unit'
3
+ # these tests are ICU 3.4 dependent
4
+ class UCollatorTest < Test::Unit::TestCase
5
+ def test_strength
6
+ c = UCollator.new("root")
7
+ assert_equal(0, c.strcoll("a".u, "a".u))
8
+ assert_equal(1, c.strcoll("A".u, "a".u))
9
+ c.strength = UCollator::UCOL_SECONDARY
10
+ assert_equal(0, c.strcoll("A".u, "a".u))
11
+ end
12
+
13
+ def test_attrs
14
+ c = UCollator.new("root")
15
+ c[UCollator::UCOL_NUMERIC_COLLATION]= UCollator::UCOL_ON
16
+ ar = %w(100 10 20 30 200 300).map {|a| a.to_u }.sort {|a,b| c.strcoll(a,b)}.map {|s| s.to_s }
17
+ assert_equal(["10", "20", "30", "100", "200", "300"], ar)
18
+ c[UCollator::UCOL_NUMERIC_COLLATION]= UCollator::UCOL_OFF
19
+ ar = %w(100 10 20 30 200 300).map {|a| a.to_u }.sort {|a,b| c.strcoll(a,b)}.map {|s| s.to_s }
20
+ assert_equal( ["10", "100", "20", "200", "30", "300"], ar)
21
+ end
22
+
23
+ def test_sort_key
24
+ c = UCollator.new("root")
25
+ c[UCollator::UCOL_NUMERIC_COLLATION]= UCollator::UCOL_ON
26
+ ar = %w(100 10 20 30 200 300).sort_by {|a| c.sort_key(a.to_u) }
27
+ assert_equal(["10", "20", "30", "100", "200", "300"], ar)
28
+ c[UCollator::UCOL_NUMERIC_COLLATION]= UCollator::UCOL_OFF
29
+ ar = %w(100 10 20 30 200 300).sort_by {|a| c.sort_key(a.to_u) }
30
+ assert_equal( ["10", "100", "20", "200", "30", "300"], ar)
31
+ end
32
+
33
+ end
@@ -0,0 +1,72 @@
1
+ require './icu4r'
2
+ require 'test/unit'
3
+ # these tests are ICU 3.4 dependent
4
+ class UConverterTest < Test::Unit::TestCase
5
+
6
+ def test_a_new_and_name
7
+ c = UConverter.new("UTF8")
8
+ assert_kind_of( UConverter, c)
9
+ assert_equal('UTF-8', c.name)
10
+ end
11
+
12
+ def test_b_list_avail
13
+ a = UConverter.list_available
14
+ assert_kind_of(Array, a)
15
+ assert(a.include?("UTF-8"))
16
+ end
17
+
18
+ def test_c_all_names
19
+ a = UConverter.all_names
20
+ assert_kind_of(Array, a)
21
+ assert(a.include?("UTF-8"))
22
+ end
23
+
24
+ def test_d_std_names
25
+ a = UConverter.std_names("koi8r", "MIME")
26
+ assert_kind_of(Array, a)
27
+ assert(a.include?("KOI8-R"))
28
+ a = UConverter.std_names("cp1251", "IANA")
29
+ assert_kind_of(Array, a)
30
+ assert(a.include?("windows-1251"))
31
+ end
32
+
33
+ def test_e_convert_class_method
34
+ a_s = "\357\360\356\342\345\360\352\340 abcd"
35
+ u_s = UConverter.convert("utf8", "cp1251", a_s)
36
+ assert_equal("проверка abcd", u_s)
37
+ r_s = UConverter.convert("cp1251", "utf8", u_s)
38
+ assert_equal(r_s, a_s)
39
+ end
40
+
41
+ def test_f_to_from_u
42
+ c = UConverter.new("cp1251")
43
+ a_s = "\357\360\356\342\345\360\352\340 abcd"
44
+ u_s = c.to_u(a_s)
45
+ assert_kind_of(UString, u_s)
46
+ r_s = c.from_u(u_s)
47
+ assert_equal(r_s, a_s)
48
+ end
49
+
50
+ def test_g_convert_instance_method
51
+ c1 = UConverter.new("EUC-JP")
52
+ c2 = UConverter.new("Cp1251")
53
+ a_s = "\247\322\247\335\247\361!"
54
+ b_s = a_s * 1000
55
+ a1 = UConverter.convert("Cp1251", "EUC-JP", b_s)
56
+ a2 = c1.convert(c2, b_s)
57
+ assert_equal(a1.size, a2.size)
58
+ assert_equal(a2.size, 4 * 1000)
59
+ assert_equal(a1, a2)
60
+ assert_equal("\341\353\377!", c1.convert(c2, a_s))
61
+ end
62
+
63
+ def test_h_subst_chars
64
+ c1 = UConverter.new("US-ASCII")
65
+ assert_kind_of(String, c1.subst_chars)
66
+ c1.subst_chars="!"
67
+ assert_equal( "I!t!rn!ti!n!liz!ti!n", c1.from_u("Iñtërnâtiônàlizætiøn".u))
68
+ c1.subst_chars=" "
69
+ assert_equal( "I t rn ti n liz ti n", c1.from_u("Iñtërnâtiônàlizætiøn".u))
70
+ end
71
+
72
+ end
@@ -68,6 +68,19 @@ class UnicodeStringTest < Test::Unit::TestCase
68
68
  assert_equal( "hello".u.index('a'.u), nil)
69
69
  assert_equal( "hello".u.index(ure('[aeiou]'), -3), 4)
70
70
  assert_equal( "hello".u.rindex(ure('[aeiou]'), -2), 1)
71
+
72
+ assert_equal(1, S("hello").index(S("ell")))
73
+ assert_equal(2, S("hello").index(/ll./.U))
74
+
75
+ assert_equal(3, S("hello").index(S("l"), 3))
76
+ assert_equal(3, S("hello").index(/l./.U, 3))
77
+
78
+ assert_nil(S("hello").index(S("z"), 3))
79
+ assert_nil(S("hello").index(/z./.U, 3))
80
+
81
+ assert_nil(S("hello").index(S("z")))
82
+ assert_nil(S("hello").index(/z./.U))
83
+
71
84
  end
72
85
 
73
86
  def test_insert
@@ -245,12 +258,6 @@ class UnicodeStringTest < Test::Unit::TestCase
245
258
  assert_equal("Iñtërnâtiônàlizætiøn".u,v.norm_D.norm_KC)
246
259
  end
247
260
 
248
- def test_parse_date
249
- assert_equal(Time.local(2006,"jan",13,20,15,1),
250
- "HH:mm:ss E dd/MM/yyyy".u.parse_date("en", "20:15:01 Fri 13/01/2006".u))
251
- assert_equal(Time.local(2006, "jan", 18, 0, 0), "d MMMM, yyyy".u.parse_date("ar_SY", "١٨ كانون الثاني, ٢٠٠٦".u))
252
- end
253
-
254
261
  def test_scan
255
262
  a = "cruel world".u
256
263
  assert_equal(a.scan(/\w+/.U) ,["cruel".u , "world".u ])
@@ -258,21 +265,32 @@ class UnicodeStringTest < Test::Unit::TestCase
258
265
  assert_equal(a.scan(/(...)/.U) ,["cru".u , "el ".u , "wor".u ])
259
266
  assert_equal(a.scan(/(..)(..)/.U) ,[["cr".u , "ue".u ], ["l ".u , "wo".u ]] )
260
267
  end
261
-
268
+ def S(str)
269
+ str.to_u
270
+ end
262
271
  def test_split
263
- re = URegexp.new("[,:/]".u)
264
- assert_equal(["split test".u , "west".u , "best".u , "east".u ], re.split("split test,west:best/east".u, nil))
265
- assert_equal(["split test".u, "west:best/east".u], re.split("split test,west:best/east".u, 2))
272
+ re = URegexp.new("[,:/]".u)
273
+ assert_equal(["split test".u , "west".u , "best".u , "east".u ], re.split("split test,west:best/east".u, nil))
274
+ assert_equal(["split test".u, "west:best/east".u], re.split("split test,west:best/east".u, 2))
275
+ assert_equal([S("a"), S("b"), S("c")], S("a b\t c").split(S("\\s+")))
276
+ assert_equal([S(" a "), S(" b "), S(" c ")], S(" a | b | c ").split(S("\\|")))
277
+ assert_equal([S("a"), S("b"), S("c")], S("aXXbXXcXX").split(/X./.U))
278
+ assert_equal([S("a|b|c")], S("a|b|c").split(S('\|'), 1))
279
+ assert_equal([S("a"), S("b|c")], S("a|b|c").split(S('\|'), 2))
280
+ assert_equal([S("a"), S("b"), S("c")], S("a|b|c").split(S('\|'), 3))
281
+ assert_equal([S("a"), S("b"), S("c")], S("a|b|c|").split(S('\|'), -1))
282
+ assert_equal([S("a"), S("b"), S("c"), S("") ], S("a|b|c||").split(S('\|'), -1))
283
+ assert_equal([S("a"), S(""), S("b"), S("c")], S("a||b|c|").split(S('\|'), -1))
266
284
  end
267
285
 
286
+
268
287
  def test_strcoll
269
288
  assert_equal(0, UString::strcoll("a".u, "a".u))
270
- assert_equal(0, UString::strcoll("ой её".u, "ОИ ЕЕ".u, "ru", 0))
271
- assert_equal(0, UString::strcoll("ой её".u, "ОЙ ЕЁ".u, "ru", 1))
272
289
  assert_equal(-1, UString::strcoll("y".u, "k".u, "lv"))
273
290
  assert_equal(1, UString::strcoll("я".u, "а".u))
274
291
  assert_equal(1, UString::strcoll("я".u, "А".u, "ru"))
275
292
  assert_equal(0, UString::strcoll("İSTANBUL".u, "istanbul".u, "tr", 0))
293
+ assert_equal(0, UString::strcoll("ой её".u, "ОЙ ЕЁ".u, "ru", 1))
276
294
  end
277
295
 
278
296
  def test_gsub_block
@@ -378,4 +396,113 @@ class UnicodeStringTest < Test::Unit::TestCase
378
396
  "\320\275\320\270\321\207\320\265\320\263\320\276 \320\275\320\265 \321\200\320\260\320\261\320\276\321\202\320\260\320\265\321\202 :( ?")
379
397
  end
380
398
 
399
+ def test_nested_blocks
400
+ a = "Модифицируемые строки иногда напрягают :)".u
401
+ b = "".u
402
+ assert_nothing_raised {
403
+ a.scan(/./.U) { |s|
404
+ b = a.gsub(ure('и')) { |m|
405
+ t = m[0] + "".u
406
+ a.each_char { |c|
407
+ t << c if c == 'о' .u
408
+ }
409
+ t
410
+ }
411
+ }
412
+ }
413
+ assert_equal("Модиооофиоооциоооруемые строкиооо иоооногда напрягают :)".u, b)
414
+ end
415
+
416
+ def test_AREF # '[]'
417
+ assert_equal(S("A"), S("AooBar")[0])
418
+ assert_equal(S("B"), S("FooBaB")[-1])
419
+ assert_equal(nil, S("FooBar")[6])
420
+ assert_equal(nil, S("FooBar")[-7])
421
+
422
+ assert_equal(S("Foo"), S("FooBar")[0,3])
423
+ assert_equal(S("Bar"), S("FooBar")[-3,3])
424
+ assert_equal(S(""), S("FooBar")[6,2])
425
+ assert_equal(nil, S("FooBar")[-7,10])
426
+
427
+ assert_equal(S("Foo"), S("FooBar")[0..2])
428
+ assert_equal(S("Foo"), S("FooBar")[0...3])
429
+ assert_equal(S("Bar"), S("FooBar")[-3..-1])
430
+ assert_equal(S(""), S("FooBar")[6..2])
431
+ assert_equal(nil, S("FooBar")[-10..-7])
432
+
433
+ assert_equal(S("Foo"), S("FooBar")[/^F../.U])
434
+ assert_equal(S("Bar"), S("FooBar")[/..r$/.U])
435
+ assert_equal(nil, S("FooBar")[/xyzzy/.U])
436
+ assert_equal(nil, S("FooBar")[/plugh/.U])
437
+
438
+ assert_equal(S("Foo"), S("FooBar")[S("Foo")])
439
+ assert_equal(S("Bar"), S("FooBar")[S("Bar")])
440
+ assert_equal(nil, S("FooBar")[S("xyzzy")])
441
+ assert_equal(nil, S("FooBar")[S("plugh")])
442
+
443
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/.U, 1])
444
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/.U, 2])
445
+ assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/.U, 3])
446
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/.U, -1])
447
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/.U, -2])
448
+ assert_equal(nil, S("FooBar")[ure("([A-Z]..)([A-Z]..)"), -3])
449
+ end
450
+
451
+ def test_ASET # '[]='
452
+ s = S("FooBar")
453
+ s[0] = S('A')
454
+ assert_equal(S("AooBar"), s)
455
+
456
+ s[-1]= S('B')
457
+ assert_equal(S("AooBaB"), s)
458
+ assert_raise(IndexError) { s[-7] = S("xyz") }
459
+ assert_equal(S("AooBaB"), s)
460
+ s[0] = S("ABC")
461
+ assert_equal(S("ABCooBaB"), s)
462
+
463
+ s = S("FooBar")
464
+ s[0,3] = S("A")
465
+ assert_equal(S("ABar"),s)
466
+ s[0] = S("Foo")
467
+ assert_equal(S("FooBar"), s)
468
+ s[-3,3] = S("Foo")
469
+ assert_equal(S("FooFoo"), s)
470
+ assert_raise (IndexError) { s[7,3] = S("Bar") }
471
+ assert_raise (IndexError) { s[-7,3] = S("Bar") }
472
+
473
+ s = S("FooBar")
474
+ s[0..2] = S("A")
475
+ assert_equal(S("ABar"), s)
476
+ s[1..3] = S("Foo")
477
+ assert_equal(S("AFoo"), s)
478
+ s[-4..-4] = S("Foo")
479
+ assert_equal(S("FooFoo"), s)
480
+ assert_raise (RangeError) { s[7..10] = S("Bar") }
481
+ assert_raise (RangeError) { s[-7..-10] = S("Bar") }
482
+
483
+ s = S("FooBar")
484
+ s[/^F../.U]= S("Bar")
485
+ assert_equal(S("BarBar"), s)
486
+ s[/..r$/.U] = S("Foo")
487
+ assert_equal(S("BarFoo"), s)
488
+
489
+ s[/([A-Z]..)([A-Z]..)/.U, 1] = S("Foo")
490
+ assert_equal(S("FooFoo"), s)
491
+ s[/([A-Z]..)([A-Z]..)/.U, 2] = S("Bar")
492
+ assert_equal(S("FooBar"), s)
493
+ assert_raise (IndexError) { s[/([A-Z]..)([A-Z]..)/.U, 3] = "None" }
494
+ s[ure("([A-Z]..)([A-Z]..)"), -1] = S("Foo")
495
+ assert_equal(S("FooFoo"), s)
496
+ s[/([A-Z]..)([A-Z]..)/.U, -2] = S("Bar")
497
+ assert_equal(S("BarFoo"), s)
498
+ # assert_raise (IndexError) { s[/([A-Z]..)([A-Z]..)/.U, -3] = "None" }
499
+
500
+ s = S("FooBar")
501
+ s[S("Foo")] = S("Bar")
502
+ assert_equal(S("BarBar"), s)
503
+
504
+ s = S("a string")
505
+ s[0..s.size] = S("another string")
506
+ assert_equal(S("another string"), s)
507
+ end
381
508
  end
@@ -1,2 +1,2 @@
1
1
  #!/bin/sh
2
- rdoc -T ./tools/km.rb -c utf-8 README docs/FORMATTING docs/UNICODE_REGEXPS *.c
2
+ rdoc -T ./tools/km.rb -c utf-8 README docs/FORMATTING docs/UNICODE_REGEXPS *.c MIT-LICENSE
data/ubundle.c CHANGED
@@ -170,13 +170,20 @@ VALUE icu_bundle_open_direct(klass, package, locale)
170
170
  * URES_INT_VECTOR vectors of 32-bit integers. Array of fixnums
171
171
  *
172
172
  */
173
- VALUE icu_bundle_aref( bundle, key)
174
- VALUE bundle, key;
173
+ VALUE icu_bundle_aref( argc, argv, bundle)
174
+ int argc;
175
+ VALUE *argv;
176
+ VALUE bundle;
175
177
  {
176
178
  UErrorCode status = U_ZERO_ERROR;
177
179
  UResourceBundle * res , * orig;
178
- VALUE out;
179
-
180
+ VALUE out, tmp, locale_str;
181
+ VALUE key, locale_flag = Qfalse;
182
+ int return_locale = 0;
183
+ if( rb_scan_args(argc, argv, "11", &key, &locale_flag) )
184
+ {
185
+ if(Qtrue == locale_flag) return_locale = 1;
186
+ }
180
187
  Check_Type(key, T_STRING);
181
188
  orig = (UResourceBundle*)DATA_PTR(bundle);
182
189
 
@@ -186,6 +193,13 @@ VALUE icu_bundle_aref( bundle, key)
186
193
  rb_raise(rb_eArgError, u_errorName(status));
187
194
  }
188
195
  out = icu_bundle_read(res);
196
+ if( return_locale ) {
197
+ locale_str = rb_str_new2(ures_getLocale(res, &status));
198
+ tmp = rb_ary_new();
199
+ rb_ary_push(tmp, out);
200
+ rb_ary_push(tmp, locale_str);
201
+ out = tmp;
202
+ }
189
203
  ures_close(res);
190
204
  return out;
191
205
  }
@@ -202,7 +216,7 @@ VALUE icu_bundle_clone( bundle)
202
216
  }
203
217
  void initialize_ubundle(void) {
204
218
  rb_cUResourceBundle = rb_define_class("UResourceBundle", rb_cObject);
205
- rb_define_method(rb_cUResourceBundle, "[]", icu_bundle_aref, 1);
219
+ rb_define_method(rb_cUResourceBundle, "[]", icu_bundle_aref, -1);
206
220
  rb_define_method(rb_cUResourceBundle, "clone", icu_bundle_clone, 0);
207
221
  rb_define_singleton_method(rb_cUResourceBundle, "open", icu_bundle_open, 2);
208
222
  rb_define_singleton_method(rb_cUResourceBundle, "open_direct", icu_bundle_open_direct, 2);
data/uregex.c CHANGED
@@ -79,7 +79,7 @@ icu_reg_get_pattern(ptr, len)
79
79
  ICURegexp *ptr;
80
80
  int32_t *len;
81
81
  {
82
- UErrorCode error = 0;
82
+ UErrorCode error = U_ZERO_ERROR;
83
83
  *len = 0;
84
84
  return uregex_pattern(ptr->pattern, len, &error);
85
85
  }
@@ -206,28 +206,42 @@ icu_reg_split(self, str, limit)
206
206
  {
207
207
  VALUE splits;
208
208
  URegularExpression *theRegEx = UREGEX(self)->pattern;
209
- UErrorCode error = 0;
209
+ UErrorCode error = U_ZERO_ERROR;
210
210
  UChar * dest_buf, **dest_fields;
211
211
  int32_t limt, req_cap, total, i;
212
212
  Check_Class(str, rb_cUString);
213
213
  if (limit != Qnil)
214
214
  Check_Type(limit, T_FIXNUM);
215
- splits = rb_ary_new();
216
- dest_buf = ALLOCA_N(UChar, USTRING(str)->len * 2);
217
- dest_fields = ALLOCA_N(UChar *, USTRING(str)->len);
218
- limt = limit == Qnil ? USTRING(str)->len : FIX2INT(limit);
215
+ dest_buf = ALLOC_N(UChar, USTRING(str)->len * 2 + 2);
216
+ limt = (limit == Qnil ? USTRING(str)->len + 1 : FIX2INT(limit));
217
+ dest_fields = ALLOC_N(UChar *, limt);
219
218
  uregex_setText(theRegEx, USTRING(str)->ptr, USTRING(str)->len, &error);
220
- if (U_FAILURE(error))
219
+ if (U_FAILURE(error)) {
220
+ free(dest_buf);
221
+ free(dest_fields);
221
222
  rb_raise(rb_eArgError, u_errorName(error));
223
+ }
222
224
  req_cap = 0;
223
225
  total =
224
226
  uregex_split(theRegEx, dest_buf, USTRING(str)->len * 2, &req_cap,
225
227
  dest_fields, limt, &error);
226
- if (U_FAILURE(error))
228
+ if (U_BUFFER_OVERFLOW_ERROR == error) {
229
+ error = U_ZERO_ERROR;
230
+ REALLOC_N( dest_buf, UChar, req_cap);
231
+ total = uregex_split(theRegEx, dest_buf, req_cap, &req_cap, dest_fields, limt, &error);
232
+ }
233
+ if (U_FAILURE(error) ) {
234
+ free(dest_buf);
235
+ free(dest_fields);
227
236
  rb_raise(rb_eArgError, u_errorName(error));
228
-
237
+ }
238
+ splits = rb_ary_new();
229
239
  for (i = 0; i < total; i++)
230
240
  rb_ary_push(splits, icu_ustr_new2(dest_fields[i]));
241
+
242
+ free(dest_buf);
243
+ free(dest_fields);
244
+
231
245
  return splits;
232
246
  }
233
247
 
@@ -238,7 +252,7 @@ icu_reg_search(re, str, pos, reverse)
238
252
  long pos,
239
253
  reverse;
240
254
  {
241
- UErrorCode error = 0;
255
+ UErrorCode error = U_ZERO_ERROR;
242
256
  long cur_pos = 0;
243
257
  long start,
244
258
  last;
@@ -261,7 +275,7 @@ icu_reg_search(re, str, pos, reverse)
261
275
  if (reverse) {
262
276
  while (uregex_findNext(UREGEX(re)->pattern, &error)) {
263
277
  last = uregex_start(UREGEX(re)->pattern, 0, &error);
264
- error = 0;
278
+ error = U_ZERO_ERROR;
265
279
  if (reverse && last > pos)
266
280
  break;
267
281
  cur_pos = last;
@@ -271,6 +285,13 @@ icu_reg_search(re, str, pos, reverse)
271
285
  return -1;
272
286
  return cur_pos;
273
287
  }
288
+ long
289
+ icu_group_count(re)
290
+ VALUE re;
291
+ {
292
+ UErrorCode error = U_ZERO_ERROR;
293
+ return uregex_groupCount(UREGEX(re)->pattern, &error);
294
+ }
274
295
 
275
296
  VALUE
276
297
  icu_reg_nth_match(re, nth)
@@ -278,9 +299,14 @@ icu_reg_nth_match(re, nth)
278
299
  long nth;
279
300
  {
280
301
  URegularExpression *the_expr = UREGEX(re)->pattern;
281
- UErrorCode error = 0;
282
- long start = uregex_start(the_expr, nth, &error), end;
302
+ UErrorCode error = U_ZERO_ERROR;
303
+ long start, end;
283
304
  int32_t len;
305
+ if( nth < 0 ) {
306
+ nth += icu_group_count(re) + 1;
307
+ if(nth<=0) return Qnil;
308
+ }
309
+ start = uregex_start(the_expr, nth, &error);
284
310
  if (U_FAILURE(error)) {
285
311
  return Qnil;
286
312
  }
@@ -298,7 +324,11 @@ icu_reg_range(re, nth, start, end)
298
324
  long *end;
299
325
  {
300
326
  URegularExpression *the_expr = UREGEX(re)->pattern;
301
- UErrorCode error = 0;
327
+ UErrorCode error = U_ZERO_ERROR;
328
+ if(nth < 0) {
329
+ nth += icu_group_count(re) + 1;
330
+ if(nth <= 0) return Qnil;
331
+ }
302
332
  *start = uregex_start(the_expr, nth, &error);
303
333
  if (U_FAILURE(error))
304
334
  return Qnil;
@@ -321,7 +351,7 @@ icu_reg_match(re, str)
321
351
  VALUE re,
322
352
  str;
323
353
  {
324
- UErrorCode error = 0;
354
+ UErrorCode error = U_ZERO_ERROR;
325
355
  Check_Class(str, rb_cUString);
326
356
  uregex_setText(UREGEX(re)->pattern, USTRING(str)->ptr,
327
357
  USTRING(str)->len, &error);
@@ -362,20 +392,14 @@ icu_reg_eqq(re, str)
362
392
  }
363
393
 
364
394
 
365
- long
366
- icu_group_count(re)
367
- VALUE re;
368
- {
369
- UErrorCode error = 0;
370
- return uregex_groupCount(UREGEX(re)->pattern, &error);
371
- }
395
+
372
396
 
373
397
  int
374
398
  icu_reg_find_next(pat)
375
399
  VALUE pat;
376
400
  {
377
401
  URegularExpression *the_expr = UREGEX(pat)->pattern;
378
- UErrorCode error = 0;
402
+ UErrorCode error = U_ZERO_ERROR;
379
403
  return uregex_findNext(the_expr, &error);
380
404
  }
381
405
 
@@ -478,7 +502,7 @@ icu_reg_get_prematch(pat, prev_end)
478
502
  long prev_end;
479
503
  {
480
504
  URegularExpression *the_expr = UREGEX(pat)->pattern;
481
- UErrorCode error = 0;
505
+ UErrorCode error = U_ZERO_ERROR;
482
506
  int32_t len = 0;
483
507
  int32_t cur_start = uregex_start(the_expr, 0, &error);
484
508
  const UChar *temp = uregex_getText(the_expr, &len, &error);
@@ -599,7 +623,7 @@ icu_umatch_init( self, re)
599
623
 
600
624
  Check_Class(re, rb_cURegexp);
601
625
  the_regex = UREGEX(re)->pattern;
602
- count = uregex_groupCount(the_regex, &status);
626
+ count = icu_group_count(re);
603
627
  if (U_FAILURE(status)) {
604
628
  rb_raise(rb_eArgError, u_errorName(status));
605
629
  }