icu 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: */