icu 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +20 -0
  6. data/README.md +69 -0
  7. data/Rakefile +38 -0
  8. data/benchmark/normalization.rb +106 -0
  9. data/benchmark/normalization_phrases.txt +1031 -0
  10. data/benchmark/normalization_result.txt +45 -0
  11. data/benchmark/normalization_wikip.txt +2838 -0
  12. data/ext/icu/extconf.rb +242 -0
  13. data/ext/icu/icu.c +18 -0
  14. data/ext/icu/icu.h +78 -0
  15. data/ext/icu/icu_charset_detector.c +192 -0
  16. data/ext/icu/icu_collator.c +138 -0
  17. data/ext/icu/icu_locale.c +852 -0
  18. data/ext/icu/icu_normalizer.c +122 -0
  19. data/ext/icu/icu_number_format.c +0 -0
  20. data/ext/icu/icu_spoof_checker.c +194 -0
  21. data/ext/icu/icu_transliterator.c +159 -0
  22. data/ext/icu/internal_encoding.c +38 -0
  23. data/ext/icu/internal_ustring.c +304 -0
  24. data/ext/icu/internal_utils.c +50 -0
  25. data/ext/icu/rb_errors.c +14 -0
  26. data/icu.gemspec +22 -0
  27. data/lib/icu.rb +6 -18
  28. data/lib/icu/charset_detector.rb +5 -0
  29. data/lib/icu/collator.rb +24 -0
  30. data/lib/icu/locale.rb +19 -0
  31. data/lib/icu/transliterator.rb +8 -0
  32. data/lib/icu/version.rb +3 -0
  33. data/spec/charset_detector_spec.rb +47 -0
  34. data/spec/collator_spec.rb +73 -0
  35. data/spec/locale_spec.rb +312 -0
  36. data/spec/normalizer_spec.rb +35 -0
  37. data/spec/spec_helper.rb +8 -0
  38. data/spec/spoof_checker_spec.rb +56 -0
  39. data/spec/transliterator_spec.rb +41 -0
  40. metadata +132 -55
  41. data/COPYING +0 -674
  42. data/COPYING.LESSER +0 -165
  43. data/README +0 -81
  44. data/ext/extconf.rb +0 -31
  45. data/ext/icu.c +0 -128
  46. data/ext/icu.h +0 -34
  47. data/ext/icu_locale.c +0 -330
  48. data/ext/icu_locale_country.c +0 -99
  49. data/ext/icu_locale_language.c +0 -99
  50. data/ext/icu_numeric.c +0 -161
  51. data/ext/icu_time.c +0 -391
  52. data/test/test_locale.rb +0 -73
  53. data/test/test_numeric.rb +0 -78
  54. data/test/test_time.rb +0 -75
@@ -0,0 +1,122 @@
1
+ #include "icu.h"
2
+ #include "unicode/unorm2.h"
3
+
4
+ #define GET_NORMALIZER(_data) icu_normalizer_data* _data; \
5
+ TypedData_Get_Struct(self, icu_normalizer_data, &icu_normalizer_type, _data)
6
+
7
+ VALUE rb_cICU_Normalizer;
8
+ static ID ID_nfc;
9
+ static ID ID_nfkc;
10
+ static ID ID_nfkc_cf;
11
+ static ID ID_compose;
12
+ static ID ID_decompose;
13
+
14
+ typedef struct {
15
+ VALUE rb_instance;
16
+ int customized;
17
+ UNormalizer2* service;
18
+ } icu_normalizer_data;
19
+
20
+ static void normalizer_free(void* _this)
21
+ {
22
+ icu_normalizer_data* this = _this;
23
+ if (this->customized == TRUE) { // If it's not constructed instance, shall not to be closed.
24
+ unorm2_close(this->service);
25
+ }
26
+ }
27
+
28
+ static size_t normalizer_memsize(const void* _)
29
+ {
30
+ return sizeof(icu_normalizer_data);
31
+ }
32
+
33
+ static const rb_data_type_t icu_normalizer_type = {
34
+ "icu/normalizer",
35
+ {NULL, normalizer_free, normalizer_memsize,},
36
+ 0, 0,
37
+ RUBY_TYPED_FREE_IMMEDIATELY,
38
+ };
39
+
40
+ VALUE normalizer_alloc(VALUE self)
41
+ {
42
+ icu_normalizer_data* this;
43
+ return TypedData_Make_Struct(self, icu_normalizer_data, &icu_normalizer_type, this);
44
+ }
45
+
46
+ VALUE normalizer_initialize(int argc, VALUE* argv, VALUE self)
47
+ {
48
+ VALUE sym_name;
49
+ VALUE sym_mode;
50
+ rb_scan_args(argc, argv, "02", &sym_name, &sym_mode);
51
+ if (NIL_P(sym_name)) {
52
+ sym_name = ID2SYM(ID_nfc);
53
+ }
54
+ if (NIL_P(sym_mode)) {
55
+ sym_mode = ID2SYM(ID_decompose);
56
+ }
57
+ int mode = UNORM2_DECOMPOSE;
58
+ if (sym_mode == ID2SYM(ID_compose)) {
59
+ mode = UNORM2_COMPOSE;
60
+ }
61
+ GET_NORMALIZER(this);
62
+ this->rb_instance = self;
63
+ this->customized = FALSE;
64
+
65
+ UErrorCode status = U_ZERO_ERROR;
66
+ this->service = (UNormalizer2*)unorm2_getInstance(NULL,
67
+ rb_id2name(SYM2ID(sym_name)),
68
+ mode,
69
+ &status);
70
+ if (U_FAILURE(status)) {
71
+ icu_rb_raise_icu_error(status);
72
+ }
73
+
74
+ return self;
75
+ }
76
+
77
+ VALUE normalizer_normalize(VALUE self, VALUE rb_str)
78
+ {
79
+ StringValue(rb_str);
80
+ GET_NORMALIZER(this);
81
+ VALUE in = icu_ustring_from_rb_str(rb_str);
82
+ VALUE out = icu_ustring_init_with_capa_enc(RSTRING_LENINT(rb_str) * 2 + RUBY_C_STRING_TERMINATOR_SIZE, ICU_RUBY_ENCODING_INDEX);
83
+
84
+ UErrorCode status = U_ZERO_ERROR;
85
+ int retried = FALSE;
86
+ int32_t len;
87
+ do {
88
+ len = unorm2_normalize(this->service,
89
+ icu_ustring_ptr(in), icu_ustring_len(in),
90
+ icu_ustring_ptr(out), icu_ustring_capa(out),
91
+ &status);
92
+ if (!retried && status == U_BUFFER_OVERFLOW_ERROR) {
93
+ retried = TRUE;
94
+ icu_ustring_resize(out, len + RUBY_C_STRING_TERMINATOR_SIZE);
95
+ status = U_ZERO_ERROR;
96
+ } else if (U_FAILURE(status)) {
97
+ icu_rb_raise_icu_error(status);
98
+ } else { // retried == true && U_SUCCESS(status)
99
+ break;
100
+ }
101
+ } while (retried);
102
+
103
+ return icu_ustring_to_rb_enc_str_with_len(out, len);
104
+ }
105
+
106
+ void init_icu_normalizer(void)
107
+ {
108
+ ID_nfc = rb_intern("nfc");
109
+ ID_nfkc = rb_intern("nfkc");
110
+ ID_nfkc_cf = rb_intern("nfkc_cf");
111
+ ID_compose = rb_intern("compose");
112
+ ID_decompose = rb_intern("decompose");
113
+
114
+ rb_cICU_Normalizer = rb_define_class_under(rb_mICU, "Normalizer", rb_cObject);
115
+ rb_define_alloc_func(rb_cICU_Normalizer, normalizer_alloc);
116
+ rb_define_method(rb_cICU_Normalizer, "initialize", normalizer_initialize, -1);
117
+ rb_define_method(rb_cICU_Normalizer, "normalize", normalizer_normalize, 1);
118
+ }
119
+
120
+ #undef GET_NORMALIZER
121
+
122
+ /* vim: set expandtab sws=4 sw=4: */
File without changes
@@ -0,0 +1,194 @@
1
+ #include "icu.h"
2
+ #include "unicode/uspoof.h"
3
+
4
+ #define GET_SPOOF_CHECKER(_data) icu_spoof_checker_data* _data; \
5
+ TypedData_Get_Struct(self, icu_spoof_checker_data, &icu_spoof_checker_type, _data)
6
+
7
+ VALUE rb_cICU_SpoofChecker;
8
+ VALUE rb_mChecks;
9
+ VALUE rb_mRestrictionLevel;
10
+
11
+ typedef struct {
12
+ VALUE rb_instance;
13
+ USpoofChecker* service;
14
+ } icu_spoof_checker_data;
15
+
16
+ static void spoof_checker_free(void* _this)
17
+ {
18
+ icu_spoof_checker_data* this = _this;
19
+ uspoof_close(this->service);
20
+ }
21
+
22
+ static size_t spoof_checker_memsize(const void* _)
23
+ {
24
+ return sizeof(icu_spoof_checker_data);
25
+ }
26
+
27
+ static const rb_data_type_t icu_spoof_checker_type = {
28
+ "icu/spoof_checker",
29
+ {NULL, spoof_checker_free, spoof_checker_memsize,},
30
+ 0, 0,
31
+ RUBY_TYPED_FREE_IMMEDIATELY,
32
+ };
33
+
34
+ VALUE spoof_checker_alloc(VALUE self)
35
+ {
36
+ icu_spoof_checker_data* this;
37
+ return TypedData_Make_Struct(self, icu_spoof_checker_data, &icu_spoof_checker_type, this);
38
+ }
39
+
40
+ VALUE spoof_checker_initialize(VALUE self)
41
+ {
42
+ GET_SPOOF_CHECKER(this);
43
+ this->rb_instance = self;
44
+ this->service = FALSE;
45
+
46
+ UErrorCode status = U_ZERO_ERROR;
47
+ this->service = uspoof_open(&status);
48
+ if (U_FAILURE(status)) {
49
+ icu_rb_raise_icu_error(status);
50
+ }
51
+
52
+ return self;
53
+ }
54
+
55
+ static inline VALUE spoof_checker_get_restriction_level_internal(const icu_spoof_checker_data* this)
56
+ {
57
+ URestrictionLevel level = uspoof_getRestrictionLevel(this->service);
58
+ return INT2NUM(level);
59
+ }
60
+
61
+ VALUE spoof_checker_get_restriction_level(VALUE self)
62
+ {
63
+ GET_SPOOF_CHECKER(this);
64
+ return spoof_checker_get_restriction_level_internal(this);
65
+ }
66
+
67
+ VALUE spoof_checker_set_restriction_level(VALUE self, VALUE level)
68
+ {
69
+ GET_SPOOF_CHECKER(this);
70
+ uspoof_setRestrictionLevel(this->service, NUM2INT(level));
71
+ return spoof_checker_get_restriction_level_internal(this);
72
+ }
73
+
74
+ static inline VALUE spoof_checker_get_checks_internal(const icu_spoof_checker_data* this)
75
+ {
76
+ UErrorCode status = U_ZERO_ERROR;
77
+ int32_t checks = uspoof_getChecks(this->service, &status);
78
+ if (U_FAILURE(status)) {
79
+ icu_rb_raise_icu_error(status);
80
+ }
81
+ return INT2NUM(checks);
82
+ }
83
+
84
+ VALUE spoof_checker_get_checks(VALUE self)
85
+ {
86
+ GET_SPOOF_CHECKER(this);
87
+ return spoof_checker_get_checks_internal(this);
88
+ }
89
+
90
+ VALUE spoof_checker_set_checks(VALUE self, VALUE checks)
91
+ {
92
+ GET_SPOOF_CHECKER(this);
93
+
94
+ UErrorCode status = U_ZERO_ERROR;
95
+ uspoof_setChecks(this->service, NUM2INT(checks), &status);
96
+ if (U_FAILURE(status)) {
97
+ icu_rb_raise_icu_error(status);
98
+ }
99
+ return spoof_checker_get_checks_internal(this);
100
+ }
101
+
102
+ VALUE spoof_checker_confusable(VALUE self, VALUE str_a, VALUE str_b)
103
+ {
104
+ StringValue(str_a);
105
+ StringValue(str_b);
106
+ GET_SPOOF_CHECKER(this);
107
+
108
+ VALUE tmp_a = icu_ustring_from_rb_str(str_a);
109
+ VALUE tmp_b = icu_ustring_from_rb_str(str_b);
110
+ UErrorCode status = U_ZERO_ERROR;
111
+ int32_t result = uspoof_areConfusable(this->service,
112
+ icu_ustring_ptr(tmp_a),
113
+ icu_ustring_len(tmp_a),
114
+ icu_ustring_ptr(tmp_b),
115
+ icu_ustring_len(tmp_b),
116
+ &status);
117
+
118
+ return INT2NUM(result);
119
+ }
120
+
121
+ VALUE spoof_checker_get_skeleton(VALUE self, VALUE str)
122
+ {
123
+ StringValue(str);
124
+ GET_SPOOF_CHECKER(this);
125
+
126
+ VALUE in = icu_ustring_from_rb_str(str);
127
+ VALUE out = icu_ustring_init_with_capa_enc(icu_ustring_capa(in), ICU_RUBY_ENCODING_INDEX);
128
+ int retried = FALSE;
129
+ int32_t len_bytes;
130
+ UErrorCode status = U_ZERO_ERROR;
131
+ do {
132
+ // UTF-8 version does the conversion internally so we relies on UChar version here!
133
+ len_bytes = uspoof_getSkeleton(this->service, 0 /* deprecated */,
134
+ icu_ustring_ptr(in), icu_ustring_len(in),
135
+ icu_ustring_ptr(out), icu_ustring_capa(out),
136
+ &status);
137
+ if (!retried && status == U_BUFFER_OVERFLOW_ERROR) {
138
+ retried = TRUE;
139
+ icu_ustring_resize(out, len_bytes + RUBY_C_STRING_TERMINATOR_SIZE);
140
+ status = U_ZERO_ERROR;
141
+ } else if (U_FAILURE(status)) {
142
+ icu_rb_raise_icu_error(status);
143
+ } else { // retried == true && U_SUCCESS(status)
144
+ break;
145
+ }
146
+ } while (retried);
147
+
148
+ return icu_ustring_to_rb_enc_str_with_len(out, len_bytes);
149
+ }
150
+
151
+ #define DEFINE_SPOOF_ENUM_CONST(_MODULE, _NAME) rb_define_const(_MODULE, #_NAME, INT2NUM(USPOOF_##_NAME))
152
+
153
+ void init_icu_spoof_checker(void)
154
+ {
155
+ rb_cICU_SpoofChecker = rb_define_class_under(rb_mICU, "SpoofChecker", rb_cObject);
156
+ rb_mChecks = rb_define_module_under(rb_cICU_SpoofChecker, "Checks");
157
+ rb_mRestrictionLevel = rb_define_module_under(rb_cICU_SpoofChecker, "RestrictionLevel");
158
+ rb_include_module(rb_cICU_SpoofChecker, rb_mChecks);
159
+ rb_include_module(rb_cICU_SpoofChecker, rb_mRestrictionLevel);
160
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, SINGLE_SCRIPT_CONFUSABLE);
161
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, MIXED_SCRIPT_CONFUSABLE);
162
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, WHOLE_SCRIPT_CONFUSABLE);
163
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, CONFUSABLE);
164
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, ANY_CASE);
165
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, RESTRICTION_LEVEL);
166
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, SINGLE_SCRIPT);
167
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, INVISIBLE);
168
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, CHAR_LIMIT);
169
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, MIXED_NUMBERS);
170
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, ALL_CHECKS);
171
+ DEFINE_SPOOF_ENUM_CONST(rb_mChecks, AUX_INFO);
172
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, ASCII);
173
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, SINGLE_SCRIPT_RESTRICTIVE);
174
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, HIGHLY_RESTRICTIVE);
175
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, MODERATELY_RESTRICTIVE);
176
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, MINIMALLY_RESTRICTIVE);
177
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, UNRESTRICTIVE);
178
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, RESTRICTION_LEVEL_MASK);
179
+ DEFINE_SPOOF_ENUM_CONST(rb_mRestrictionLevel, UNDEFINED_RESTRICTIVE);
180
+
181
+ rb_define_alloc_func(rb_cICU_SpoofChecker, spoof_checker_alloc);
182
+ rb_define_method(rb_cICU_SpoofChecker, "initialize", spoof_checker_initialize, 0);
183
+ rb_define_method(rb_cICU_SpoofChecker, "restriction_level", spoof_checker_get_restriction_level, 0);
184
+ rb_define_method(rb_cICU_SpoofChecker, "restriction_level=", spoof_checker_set_restriction_level, 1);
185
+ rb_define_method(rb_cICU_SpoofChecker, "checks", spoof_checker_get_checks, 0);
186
+ rb_define_method(rb_cICU_SpoofChecker, "checks=", spoof_checker_set_checks, 1);
187
+ rb_define_method(rb_cICU_SpoofChecker, "confusable?", spoof_checker_confusable, 2);
188
+ rb_define_method(rb_cICU_SpoofChecker, "get_skeleton", spoof_checker_get_skeleton, 1);
189
+ }
190
+
191
+ #undef DEFINE_SPOOF_ENUM_CONST
192
+ #undef GET_SPOOF_CHECKER
193
+
194
+ /* vim: set expandtab sws=4 sw=4: */
@@ -0,0 +1,159 @@
1
+ #include "icu.h"
2
+ #include "unicode/utrans.h"
3
+
4
+ #define GET_TRANSLITERATOR(_data) icu_transliterator_data* _data; \
5
+ TypedData_Get_Struct(self, icu_transliterator_data, &icu_transliterator_type, _data)
6
+
7
+ VALUE rb_cICU_Transliterator;
8
+ static ID ID_forward;
9
+ static ID ID_reverse;
10
+
11
+ typedef struct {
12
+ VALUE rb_instance;
13
+ UTransliterator* service;
14
+ } icu_transliterator_data;
15
+
16
+ static void transliterator_free(void* _this)
17
+ {
18
+ icu_transliterator_data* this = _this;
19
+ utrans_close(this->service);
20
+ }
21
+
22
+ static size_t transliterator_memsize(const void* _)
23
+ {
24
+ return sizeof(icu_transliterator_data);
25
+ }
26
+
27
+ static const rb_data_type_t icu_transliterator_type = {
28
+ "icu/transliterator",
29
+ {NULL, transliterator_free, transliterator_memsize,},
30
+ 0, 0,
31
+ RUBY_TYPED_FREE_IMMEDIATELY,
32
+ };
33
+
34
+ VALUE transliterator_alloc(VALUE self)
35
+ {
36
+ icu_transliterator_data* this;
37
+ return TypedData_Make_Struct(self, icu_transliterator_data, &icu_transliterator_type, this);
38
+ }
39
+
40
+ VALUE transliterator_initialize(int argc, VALUE* argv, VALUE self)
41
+ {
42
+ GET_TRANSLITERATOR(this);
43
+ this->rb_instance = self;
44
+ this->service = NULL;
45
+
46
+ VALUE id;
47
+ VALUE direction;
48
+ VALUE rules;
49
+ rb_scan_args(argc, argv, "12", &id, &rules, &direction);
50
+ StringValue(id);
51
+ if (!NIL_P(rules)) {
52
+ StringValue(rules);
53
+ }
54
+ if (NIL_P(direction)) {
55
+ direction = ID2SYM(ID_forward);
56
+ } else {
57
+ // TODO: handle invalid direction
58
+ }
59
+
60
+ VALUE u_id = icu_ustring_from_rb_str(id);
61
+ UTransDirection u_direction = UTRANS_REVERSE;
62
+ if (SYM2ID(direction) == ID_forward) {
63
+ u_direction = UTRANS_FORWARD;
64
+ }
65
+ VALUE u_rules;
66
+ if (!NIL_P(rules)) {
67
+ u_rules = icu_ustring_from_rb_str(rules);
68
+ }
69
+ UParseError parser_error;
70
+ UErrorCode status = U_ZERO_ERROR;
71
+ this->service = utrans_openU(icu_ustring_ptr(u_id),
72
+ icu_ustring_len(u_id),
73
+ u_direction,
74
+ NIL_P(rules) ? NULL : icu_ustring_ptr(u_rules),
75
+ NIL_P(rules) ? 0 : icu_ustring_len(u_rules),
76
+ &parser_error, // TODO: should be possible to interpolate
77
+ &status);
78
+ if (U_FAILURE(status)) {
79
+ icu_rb_raise_icu_error(status);
80
+ }
81
+ if (this->service == NULL) {
82
+ rb_raise(rb_eICU_Error, "Transliterator can't be created.");
83
+ }
84
+
85
+ return self;
86
+ }
87
+
88
+ VALUE transliterator_transliterate(VALUE self, VALUE str)
89
+ {
90
+ StringValue(str);
91
+ GET_TRANSLITERATOR(this);
92
+
93
+ VALUE u_str = icu_ustring_from_rb_str(str);
94
+ UErrorCode status = U_ZERO_ERROR;
95
+ int32_t original_len = icu_ustring_len(u_str);
96
+ int32_t capa = icu_ustring_capa(u_str);
97
+ int32_t len;
98
+ int32_t limit;
99
+ int retried = FALSE;
100
+ do {
101
+ len = limit = original_len;
102
+
103
+ utrans_transUChars(this->service,
104
+ icu_ustring_ptr(u_str), &len, capa,
105
+ 0 /* always start from the beginning */, &limit,
106
+ &status);
107
+
108
+ if (!retried && status == U_BUFFER_OVERFLOW_ERROR) {
109
+ retried = TRUE;
110
+ u_str = icu_ustring_from_rb_str(str);
111
+ capa = len + RUBY_C_STRING_TERMINATOR_SIZE;
112
+ icu_ustring_resize(u_str, capa);
113
+ status = U_ZERO_ERROR;
114
+ } else if (U_FAILURE(status)) {
115
+ icu_rb_raise_icu_error(status);
116
+ } else { // retried == true && U_SUCCESS(status)
117
+ break;
118
+ }
119
+ } while (retried);
120
+
121
+ return icu_ustring_to_rb_enc_str_with_len(u_str, len);
122
+ }
123
+
124
+ VALUE transliterator_unicode_id(VALUE self)
125
+ {
126
+ GET_TRANSLITERATOR(this);
127
+
128
+ int32_t result_len = 0;
129
+ const UChar* result = utrans_getUnicodeID(this->service, &result_len);
130
+ VALUE str = icu_ustring_from_uchar_str(result, result_len);
131
+ VALUE rb_str = icu_ustring_to_rb_enc_str(str);
132
+ icu_ustring_clear_ptr(str);
133
+ return rb_str;
134
+ }
135
+
136
+ VALUE transliterator_available_ids(VALUE self)
137
+ {
138
+ UErrorCode status = U_ZERO_ERROR;
139
+ UEnumeration* open_ids = utrans_openIDs(&status);
140
+ return icu_enum_to_rb_ary(open_ids, status, 650);
141
+ }
142
+
143
+ void init_icu_transliterator(void)
144
+ {
145
+ ID_forward = rb_intern("forward");
146
+ ID_reverse = rb_intern("reverse");
147
+
148
+ rb_cICU_Transliterator = rb_define_class_under(rb_mICU, "Transliterator", rb_cObject);
149
+ rb_define_alloc_func(rb_cICU_Transliterator, transliterator_alloc);
150
+ rb_define_method(rb_cICU_Transliterator, "initialize", transliterator_initialize, -1);
151
+ rb_define_method(rb_cICU_Transliterator, "transliterate", transliterator_transliterate, 1);
152
+ rb_define_method(rb_cICU_Transliterator, "unicode_id", transliterator_unicode_id, 0);
153
+
154
+ rb_define_module_function(rb_cICU_Transliterator, "available_ids", transliterator_available_ids, 0);
155
+ }
156
+
157
+ #undef GET_TRANSLITERATOR
158
+
159
+ /* vim: set expandtab sws=4 sw=4: */