OLD | NEW |
| (Empty) |
1 /************************************************************************ | |
2 * COPYRIGHT: | |
3 * Copyright (c) 2000-2009, International Business Machines Corporation | |
4 * and others. All Rights Reserved. | |
5 ************************************************************************/ | |
6 /************************************************************************ | |
7 * Date Name Description | |
8 * 1/03/2000 Madhu Creation. | |
9 ************************************************************************/ | |
10 | |
11 #include "unicode/utypes.h" | |
12 | |
13 #if !UCONFIG_NO_TRANSLITERATION | |
14 | |
15 #include "ittrans.h" | |
16 #include "transapi.h" | |
17 #include "unicode/utypes.h" | |
18 #include "unicode/translit.h" | |
19 #include "unicode/unifilt.h" | |
20 #include "cpdtrans.h" | |
21 #include <string.h> | |
22 #include <stdio.h> | |
23 #include <stdlib.h> | |
24 #include "unicode/rep.h" | |
25 #include "unicode/locid.h" | |
26 #include "unicode/uniset.h" | |
27 | |
28 int32_t getInt(UnicodeString str) | |
29 { | |
30 char buffer[20]; | |
31 int len=str.length(); | |
32 if(len>=20) { | |
33 len=19; | |
34 } | |
35 str.extract(0, len, buffer, ""); | |
36 buffer[len]=0; | |
37 return atoi(buffer); | |
38 } | |
39 | |
40 //--------------------------------------------- | |
41 // runIndexedTest | |
42 //--------------------------------------------- | |
43 | |
44 void | |
45 TransliteratorAPITest::runIndexedTest(int32_t index, UBool exec, | |
46 const char* &name, char* /*par*/) { | |
47 switch (index) { | |
48 TESTCASE(0,TestgetInverse); | |
49 TESTCASE(1,TestgetID); | |
50 TESTCASE(2,TestGetDisplayName); | |
51 TESTCASE(3,TestTransliterate1); | |
52 TESTCASE(4,TestTransliterate2); | |
53 TESTCASE(5,TestTransliterate3); | |
54 TESTCASE(6,TestSimpleKeyboardTransliterator); | |
55 TESTCASE(7,TestKeyboardTransliterator1); | |
56 TESTCASE(8,TestKeyboardTransliterator2); | |
57 TESTCASE(9,TestKeyboardTransliterator3); | |
58 TESTCASE(10,TestGetAdoptFilter); | |
59 TESTCASE(11,TestClone); | |
60 TESTCASE(12,TestNullTransliterator); | |
61 TESTCASE(13,TestRegisterUnregister); | |
62 TESTCASE(14,TestUnicodeFunctor); | |
63 default: name = ""; break; | |
64 } | |
65 } | |
66 | |
67 | |
68 void TransliteratorAPITest::TestgetID() { | |
69 UnicodeString trans="Latin-Greek"; | |
70 UnicodeString ID; | |
71 UParseError parseError; | |
72 UErrorCode status = U_ZERO_ERROR; | |
73 Transliterator* t= Transliterator::createInstance(trans, UTRANS_FORWARD, par
seError, status); | |
74 if(t==0 || U_FAILURE(status)){ | |
75 dataerrln("FAIL: construction of Latin-Greek - %s",u_errorName(status))
; | |
76 return; | |
77 }else{ | |
78 ID= t->getID(); | |
79 if(ID != trans) | |
80 errln("FAIL: getID returned " + ID + " instead of Latin-Greek"); | |
81 delete t; | |
82 } | |
83 int i; | |
84 for (i=0; i<Transliterator::countAvailableIDs(); i++){ | |
85 status = U_ZERO_ERROR; | |
86 ID = (UnicodeString) Transliterator::getAvailableID(i); | |
87 if(ID.indexOf("Thai")>-1){ | |
88 continue; | |
89 } | |
90 t = Transliterator::createInstance(ID, UTRANS_FORWARD, parseError, statu
s); | |
91 if(t == 0){ | |
92 errln("FAIL: " + ID); | |
93 continue; | |
94 } | |
95 if(ID != t->getID()) | |
96 errln("FAIL: getID() returned " + t->getID() + " instead of " + ID); | |
97 delete t; | |
98 } | |
99 ID=(UnicodeString)Transliterator::getAvailableID(i); | |
100 if(ID != (UnicodeString)Transliterator::getAvailableID(0)){ | |
101 errln("FAIL: calling getAvailableID(index > coundAvailableIDs) should ma
ke index=0\n"); | |
102 } | |
103 | |
104 Transliterator* t1=Transliterator::createInstance("Latin-Devanagari", UTRANS
_FORWARD, parseError, status); | |
105 Transliterator* t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORW
ARD, parseError, status); | |
106 if(t1 ==0 || t2 == 0){ | |
107 errln("FAIL: construction"); | |
108 return; | |
109 } | |
110 Transliterator* t3=t1->clone(); | |
111 Transliterator* t4=t2->clone(); | |
112 | |
113 if(t1->getID() != t3->getID() || t2->getID() != t4->getID() || | |
114 t1->getID() == t4->getID() || t2->getID() == t3->getID() || | |
115 t1->getID()== t4->getID() ) | |
116 errln("FAIL: getID or clone failed"); | |
117 | |
118 | |
119 Transliterator* t5=Transliterator::createInstance("Latin-Devanagari", UTRANS
_FORWARD, parseError, status); | |
120 if(t5 == 0) | |
121 errln("FAIL: construction"); | |
122 else if(t1->getID() != t5->getID() || t5->getID() != t3->getID() || t1->getI
D() != t3->getID()) | |
123 errln("FAIL: getID or clone failed"); | |
124 | |
125 | |
126 delete t1; | |
127 delete t2; | |
128 delete t3; | |
129 delete t4; | |
130 delete t5; | |
131 } | |
132 | |
133 void TransliteratorAPITest::TestgetInverse() { | |
134 UErrorCode status = U_ZERO_ERROR; | |
135 UParseError parseError; | |
136 Transliterator* t1 = Transliterator::createInstance("Katakana-Latin", UT
RANS_FORWARD, parseError, status); | |
137 Transliterator* invt1 = Transliterator::createInstance("Latin-Katakana", UT
RANS_FORWARD, parseError, status); | |
138 Transliterator* t2 = Transliterator::createInstance("Latin-Devanagari",
UTRANS_FORWARD, parseError, status); | |
139 Transliterator* invt2 = Transliterator::createInstance("Devanagari-Latin",
UTRANS_FORWARD, parseError, status); | |
140 if(t1 == 0 || invt1 == 0 || t2 == 0 || invt2 == 0) { | |
141 dataerrln("FAIL: in instantiation - %s", u_errorName(status)); | |
142 return; | |
143 } | |
144 | |
145 Transliterator* inverse1=t1->createInverse(status); | |
146 Transliterator* inverse2=t2->createInverse(status); | |
147 if(inverse1->getID() != invt1->getID() || inverse2->getID() != invt2->getID
() | |
148 || inverse1->getID() == invt2->getID() || inverse2->getID() == invt1->ge
tID() ) | |
149 errln("FAIL: getInverse() "); | |
150 | |
151 UnicodeString TransID[]={ | |
152 "Halfwidth-Fullwidth", | |
153 "Fullwidth-Halfwidth", | |
154 "Greek-Latin" , | |
155 "Latin-Greek", | |
156 //"Arabic-Latin", // removed in 2.0 | |
157 //"Latin-Arabic", | |
158 "Katakana-Latin", | |
159 "Latin-Katakana", | |
160 //"Hebrew-Latin", // removed in 2.0 | |
161 //"Latin-Hebrew", | |
162 "Cyrillic-Latin", | |
163 "Latin-Cyrillic", | |
164 "Devanagari-Latin", | |
165 "Latin-Devanagari", | |
166 "Any-Hex", | |
167 "Hex-Any" | |
168 }; | |
169 for(uint32_t i=0; i<sizeof(TransID)/sizeof(TransID[0]); i=i+2){ | |
170 Transliterator *trans1=Transliterator::createInstance(TransID[i], UTRAN
S_FORWARD, parseError, status); | |
171 if(t1 == 0){ | |
172 errln("FAIL: in instantiation for" + TransID[i]); | |
173 continue; | |
174 } | |
175 Transliterator *inver1=trans1->createInverse(status); | |
176 if(inver1->getID() != TransID[i+1] ) | |
177 errln("FAIL :getInverse() for " + TransID[i] + " returned " + inver
1->getID() + " instead of " + TransID[i+1]); | |
178 delete inver1; | |
179 delete trans1; | |
180 } | |
181 delete t1; | |
182 delete t2; | |
183 delete invt1; | |
184 delete invt2; | |
185 delete inverse1; | |
186 delete inverse2; | |
187 | |
188 } | |
189 | |
190 void TransliteratorAPITest::TestClone(){ | |
191 Transliterator *t1, *t2, *t3, *t4; | |
192 UErrorCode status = U_ZERO_ERROR; | |
193 UParseError parseError; | |
194 t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseE
rror, status); | |
195 t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError,
status); | |
196 if(t1 == 0 || t2 == 0){ | |
197 dataerrln("FAIL: construction - %s", u_errorName(status)); | |
198 return; | |
199 } | |
200 t3=t1->clone(); | |
201 t4=t2->clone(); | |
202 | |
203 if(t1->getID() != t3->getID() || t2->getID() != t4->getID() ) | |
204 errln("FAIL: clone or getID failed"); | |
205 if(t1->getID()==t4->getID() || t2->getID()==t3->getID() || t1->getID()==t4-
>getID()) | |
206 errln("FAIL: clone or getID failed"); | |
207 | |
208 delete t1; | |
209 delete t2; | |
210 delete t3; | |
211 delete t4; | |
212 | |
213 } | |
214 | |
215 void TransliteratorAPITest::TestGetDisplayName() { | |
216 UnicodeString dispNames[]= { | |
217 //ID, displayName | |
218 //"CurlyQuotes-StraightQuotes" ,"CurlyQuotes to StraightQuotes", | |
219 "Any-Hex" ,"Any to Hex Escape", | |
220 "Halfwidth-Fullwidth" ,"Halfwidth to Fullwidth" , | |
221 //"Latin-Arabic" ,"Latin to Arabic" , | |
222 "Latin-Devanagari" ,"Latin to Devanagari" , | |
223 "Greek-Latin" ,"Greek to Latin" , | |
224 //"Arabic-Latin" ,"Arabic to Latin" , | |
225 "Hex-Any" ,"Hex Escape to Any", | |
226 "Cyrillic-Latin" ,"Cyrillic to Latin" , | |
227 "Latin-Greek" ,"Latin to Greek" , | |
228 "Latin-Katakana" ,"Latin to Katakana" , | |
229 //"Latin-Hebrew" ,"Latin to Hebrew" , | |
230 "Katakana-Latin" ,"Katakana to Latin" | |
231 }; | |
232 UnicodeString name=""; | |
233 Transliterator* t; | |
234 UnicodeString message; | |
235 UErrorCode status = U_ZERO_ERROR; | |
236 UParseError parseError; | |
237 | |
238 #if UCONFIG_NO_FORMATTING | |
239 logln("Skipping, UCONFIG_NO_FORMATTING is set\n"); | |
240 return; | |
241 #else | |
242 | |
243 for (uint32_t i=0; i<sizeof(dispNames)/sizeof(dispNames[0]); i=i+2 ) { | |
244 t = Transliterator::createInstance(dispNames[i+0], UTRANS_FORWARD, parse
Error, status); | |
245 if(t==0){ | |
246 dataerrln("FAIL: construction: " + dispNames[i+0] + " - " + u_error
Name(status)); | |
247 status = U_ZERO_ERROR; | |
248 continue; | |
249 } | |
250 t->getDisplayName(t->getID(), name); | |
251 message="Display name for ID:" + t->getID(); | |
252 // doTest(message, name, dispNames[i+1]); //!!! This will obviously fail
for any locale other than english and its children!!! | |
253 name=""; | |
254 t->getDisplayName(t->getID(), Locale::getUS(), name); | |
255 message.remove(); | |
256 message.append("Display name for on english locale ID:"); | |
257 message.append(t->getID()); | |
258 // message="Display name for on english locale ID:" + t->getID(); | |
259 doTest(message, name, dispNames[i+1]); | |
260 name=""; | |
261 | |
262 delete t; | |
263 } | |
264 #endif | |
265 | |
266 } | |
267 | |
268 void TransliteratorAPITest::TestTransliterate1(){ | |
269 | |
270 UnicodeString Data[]={ | |
271 //ID, input string, transliterated string | |
272 "Any-Hex", "hello", UnicodeString("\\u0068\\u0065\\u006C\\u0
06C\\u006F", "") , | |
273 "Hex-Any", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F",
""), "hello" , | |
274 "Latin-Devanagari",CharsToUnicodeString("bha\\u0304rata"), CharsToUnico
deString("\\u092D\\u093E\\u0930\\u0924") , | |
275 "Latin-Devanagari",UnicodeString("kra ksha khra gra cra dya dhya",""),
CharsToUnicodeString("\\u0915\\u094D\\u0930 \\u0915\\u094D\\u0936 \\u0916\\u094D
\\u0930 \\u0917\\u094D\\u0930 \\u091a\\u094D\\u0930 \\u0926\\u094D\\u092F \\u092
7\\u094D\\u092F") , | |
276 | |
277 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u09
24"), CharsToUnicodeString("bh\\u0101rata"), | |
278 // "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"),
CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042") , | |
279 // "Expanded-Contracted", CharsToUnicodeString("\\u0041\\u0300\\u0041\\u03
01\\u0042"), CharsToUnicodeString("\\u00C0\\u00C1\\u0042") , | |
280 //"Latin-Arabic", "aap", CharsTo
UnicodeString("\\u0627\\u06A4") , | |
281 //"Arabic-Latin", CharsToUnicodeString("\\u0627\\u06A4"),
"aap" | |
282 }; | |
283 | |
284 UnicodeString gotResult; | |
285 UnicodeString temp; | |
286 UnicodeString message; | |
287 Transliterator* t; | |
288 logln("Testing transliterate"); | |
289 UErrorCode status = U_ZERO_ERROR; | |
290 UParseError parseError; | |
291 | |
292 for(uint32_t i=0;i<sizeof(Data)/sizeof(Data[0]); i=i+3){ | |
293 t=Transliterator::createInstance(Data[i+0], UTRANS_FORWARD, parseError,
status); | |
294 if(t==0){ | |
295 dataerrln("FAIL: construction: " + Data[i+0] + " Error: " + u_error
Name(status)); | |
296 dataerrln("PreContext: " + prettify(parseError.preContext) + " PostC
ontext: " + prettify( parseError.postContext) ); | |
297 status = U_ZERO_ERROR; | |
298 continue; | |
299 } | |
300 gotResult = Data[i+1]; | |
301 t->transliterate(gotResult); | |
302 message=t->getID() + "->transliterate(UnicodeString, UnicodeString) for\
n\t Source:" + prettify(Data[i+1]); | |
303 doTest(message, gotResult, Data[i+2]); | |
304 | |
305 //doubt here | |
306 temp=Data[i+1]; | |
307 t->transliterate(temp); | |
308 message.remove(); | |
309 message.append(t->getID()); | |
310 message.append("->transliterate(Replaceable) for \n\tSource:"); | |
311 message.append(Data[i][1]); | |
312 doTest(message, temp, Data[i+2]); | |
313 | |
314 callEverything(t, __LINE__); | |
315 delete t; | |
316 } | |
317 } | |
318 | |
319 void TransliteratorAPITest::TestTransliterate2(){ | |
320 //testing tranliterate(String text, int start, int limit, StringBuffer resu
lt) | |
321 UnicodeString Data2[]={ | |
322 //ID, input string, start, limit, transliterated string | |
323 "Any-Hex", "hello! How are you?", "0", "5", UnicodeString("\\u
0068\\u0065\\u006C\\u006C\\u006F", ""), UnicodeString("\\u0068\\u0065\\u006C\\u0
06C\\u006F! How are you?", "") , | |
324 "Any-Hex", "hello! How are you?", "7", "12", UnicodeString("\\
u0048\\u006F\\u0077\\u0020\\u0061", ""), UnicodeString("hello! \\u0048\\u006F\\u
0077\\u0020\\u0061re you?", ""), | |
325 "Hex-Any", CharsToUnicodeString("\\u0068\\u0065\\u006C\\u006C\\
u006F\\u0021\\u0020"), "0", "5", "hello", "hello! " , | |
326 // "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"),
"1", "2", CharsToUnicodeString("\\u0041\\u0301"), CharsToUnicodeString(
"\\u00C0\\u0041\\u0301\\u0042") , | |
327 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u09
24"), "0", "1", "bha", CharsToUnicodeString("bha\\u093E\\u0930\\u0924") , | |
328 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u09
24"), "1", "2", CharsToUnicodeString("\\u0314\\u0101"), CharsToUnicodeString("\
\u092D\\u0314\\u0101\\u0930\\u0924") | |
329 | |
330 }; | |
331 logln("\n Testing transliterate(String, int, int, StringBuffer)"); | |
332 Transliterator* t; | |
333 UnicodeString gotResBuf; | |
334 UnicodeString temp; | |
335 int32_t start, limit; | |
336 UErrorCode status = U_ZERO_ERROR; | |
337 UParseError parseError; | |
338 | |
339 for(uint32_t i=0; i<sizeof(Data2)/sizeof(Data2[0]); i=i+6){ | |
340 t=Transliterator::createInstance(Data2[i+0], UTRANS_FORWARD, parseError,
status); | |
341 if(t==0){ | |
342 dataerrln("FAIL: construction: " + prettify(Data2[i+0]) + " - " + u_
errorName(status)); | |
343 continue; | |
344 } | |
345 start=getInt(Data2[i+2]); | |
346 limit=getInt(Data2[i+3]); | |
347 Data2[i+1].extractBetween(start, limit, gotResBuf); | |
348 t->transliterate(gotResBuf); | |
349 // errln("FAIL: calling transliterate on " + t->getID()); | |
350 doTest(t->getID() + ".transliterate(UnicodeString, int32_t, int32_t, Uni
codeString):(" + start + "," + limit + ") for \n\t source: " + prettify(Data2[i
+1]), gotResBuf, Data2[i+4]); | |
351 | |
352 temp=Data2[i+1]; | |
353 t->transliterate(temp, start, limit); | |
354 doTest(t->getID() + ".transliterate(Replaceable, int32_t, int32_t, ):("
+ start + "," + limit + ") for \n\t source: " + prettify(Data2[i+1]), temp, Dat
a2[i+5]); | |
355 status = U_ZERO_ERROR; | |
356 callEverything(t, __LINE__); | |
357 delete t; | |
358 t = NULL; | |
359 } | |
360 | |
361 status = U_ZERO_ERROR; | |
362 logln("\n Try calling transliterate with illegal start and limit values"); | |
363 t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, stat
us); | |
364 if(U_FAILURE(status)) { | |
365 errln("Error creating transliterator %s", u_errorName(status)); | |
366 delete t; | |
367 return; | |
368 } | |
369 gotResBuf = temp = "try start greater than limit"; | |
370 t->transliterate(gotResBuf, 10, 5); | |
371 if(gotResBuf == temp) { | |
372 logln("OK: start greater than limit value handled correctly"); | |
373 } else { | |
374 errln("FAIL: start greater than limit value returned" + gotResBuf); | |
375 } | |
376 | |
377 callEverything(t, __LINE__); | |
378 delete t; | |
379 | |
380 } | |
381 void TransliteratorAPITest::TestTransliterate3(){ | |
382 UnicodeString rs="This is the replaceable String"; | |
383 UnicodeString Data[] = { | |
384 "0", "0", "This is the replaceable String", | |
385 "2", "3", UnicodeString("Th\\u0069s is the replaceable String", ""), | |
386 "21", "23", UnicodeString("Th\\u0069s is the repl\\u0061\\u0063eable Str
ing", ""), | |
387 "14", "17", UnicodeString("Th\\u0069s is t\\u0068\\u0065\\u0020repl\\u00
61\\u0063eable String", ""), | |
388 }; | |
389 int start, limit; | |
390 UnicodeString message; | |
391 UParseError parseError; | |
392 UErrorCode status = U_ZERO_ERROR; | |
393 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD,
parseError, status); | |
394 if(U_FAILURE(status)) { | |
395 errln("Error creating transliterator %s", u_errorName(status)); | |
396 delete t; | |
397 return; | |
398 } | |
399 | |
400 if(t == 0) | |
401 errln("FAIL : construction"); | |
402 for(uint32_t i=0; i<sizeof(Data)/sizeof(Data[0]); i=i+3){ | |
403 start=getInt(Data[i+0]); | |
404 limit=getInt(Data[i+1]); | |
405 t->transliterate(rs, start, limit); | |
406 message=t->getID() + ".transliterate(ReplaceableString, start, limit):("
+start+","+limit+"):"; | |
407 doTest(message, rs, Data[i+2]); | |
408 } | |
409 delete t; | |
410 } | |
411 | |
412 void TransliteratorAPITest::TestSimpleKeyboardTransliterator(){ | |
413 logln("simple call to transliterate"); | |
414 UErrorCode status=U_ZERO_ERROR; | |
415 UParseError parseError; | |
416 Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD,
parseError, status); | |
417 if(t == 0) { | |
418 UnicodeString context; | |
419 | |
420 if (parseError.preContext[0]) { | |
421 context += (UnicodeString)" at " + parseError.preContext; | |
422 } | |
423 if (parseError.postContext[0]) { | |
424 context += (UnicodeString)" | " + parseError.postContext; | |
425 } | |
426 errln((UnicodeString)"FAIL: can't create Any-Hex, " + | |
427 (UnicodeString)u_errorName(status) + context); | |
428 return; | |
429 } | |
430 UTransPosition index={19,20,20,20}; | |
431 UnicodeString rs= "Transliterate this-''"; | |
432 UnicodeString insertion="abc"; | |
433 UnicodeString expected=UnicodeString("Transliterate this-'\\u0061\\u0062\\u0
063'", ""); | |
434 t->transliterate(rs, index, insertion, status); | |
435 if(U_FAILURE(status)) | |
436 errln("FAIL: " + t->getID()+ ".translitere(Replaceable, int[], UnicodeSt
ring, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | |
437 t->finishTransliteration(rs, index); | |
438 UnicodeString message="transliterate"; | |
439 doTest(message, rs, expected); | |
440 | |
441 logln("try calling transliterate with invalid index values"); | |
442 UTransPosition index1[]={ | |
443 //START, LIMIT, CURSOR | |
444 {10, 10, 12, 10}, //invalid since CURSOR>LIMIT valid:-START <= CURSOR
<= LIMIT | |
445 {17, 16, 17, 17}, //invalid since START>LIMIT valid:-0<=START<=LIMIT | |
446 {-1, 16, 14, 16}, //invalid since START<0 | |
447 {3, 50, 2, 50} //invalid since LIMIT>text.length() | |
448 }; | |
449 for(uint32_t i=0; i<sizeof(index1)/sizeof(index1[0]); i++){ | |
450 status=U_ZERO_ERROR; | |
451 t->transliterate(rs, index1[i], insertion, status); | |
452 if(status == U_ILLEGAL_ARGUMENT_ERROR) | |
453 logln("OK: invalid index values handled correctly"); | |
454 else | |
455 errln("FAIL: invalid index values didn't throw U_ILLEGAL_ARGUMENT_ER
ROR throw" + (UnicodeString)u_errorName(status)); | |
456 } | |
457 | |
458 delete t; | |
459 } | |
460 void TransliteratorAPITest::TestKeyboardTransliterator1(){ | |
461 UnicodeString Data[]={ | |
462 //insertion, buffer | |
463 "a", UnicodeString("\\u0061", "")
, | |
464 "bbb", UnicodeString("\\u0061\\u0062\\u0062\\u0062", "")
, | |
465 "ca", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061", "")
, | |
466 " ", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020"
, "") , | |
467 "", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020"
, "") , | |
468 | |
469 "a", UnicodeString("\\u0061", "")
, | |
470 "b", UnicodeString("\\u0061\\u0062", "")
, | |
471 "z", UnicodeString("\\u0061\\u0062\\u007A", "")
, | |
472 "", UnicodeString("\\u0061\\u0062\\u007A", "")
| |
473 | |
474 }; | |
475 UParseError parseError; | |
476 UErrorCode status = U_ZERO_ERROR; | |
477 Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD,
parseError, status); | |
478 if(U_FAILURE(status)) { | |
479 errln("Error creating transliterator %s", u_errorName(status)); | |
480 delete t; | |
481 return; | |
482 } | |
483 //keyboardAux(t, Data); | |
484 UTransPosition index={0, 0, 0, 0}; | |
485 UnicodeString s; | |
486 uint32_t i; | |
487 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode
)"); | |
488 for (i=0; i<10; i=i+2) { | |
489 UnicodeString log; | |
490 if (Data[i+0] != "") { | |
491 log = s + " + " + Data[i+0] + " -> "; | |
492 t->transliterate(s, index, Data[i+0], status); | |
493 if(U_FAILURE(status)){ | |
494 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t
[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | |
495 continue; | |
496 } | |
497 }else { | |
498 log = s + " => "; | |
499 t->finishTransliteration(s, index); | |
500 } | |
501 // Show the start index '{' and the cursor '|' | |
502 displayOutput(s, Data[i+1], log, index); | |
503 | |
504 } | |
505 | |
506 s=""; | |
507 status=U_ZERO_ERROR; | |
508 index.contextStart = index.contextLimit = index.start = index.limit = 0; | |
509 logln("Testing transliterate(Replaceable, int32_t, UChar, UErrorCode)"); | |
510 for(i=10; i<sizeof(Data)/sizeof(Data[0]); i=i+2){ | |
511 UnicodeString log; | |
512 if (Data[i+0] != "") { | |
513 log = s + " + " + Data[i+0] + " -> "; | |
514 UChar c=Data[i+0].charAt(0); | |
515 t->transliterate(s, index, c, status); | |
516 if(U_FAILURE(status)) | |
517 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t
[], UChar, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | |
518 continue; | |
519 }else { | |
520 log = s + " => "; | |
521 t->finishTransliteration(s, index); | |
522 } | |
523 // Show the start index '{' and the cursor '|' | |
524 displayOutput(s, Data[i+1], log, index); | |
525 } | |
526 | |
527 delete t; | |
528 } | |
529 | |
530 void TransliteratorAPITest::TestKeyboardTransliterator2(){ | |
531 UnicodeString Data[]={ | |
532 //insertion, buffer, index[START], index[LIMIT], index[CURSOR] | |
533 //data for Any-Hex | |
534 "abc", UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""
), "19", "20", "20", | |
535 "a", UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062
\\u0063-", ""), "2", "3", "2" , | |
536 "b", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061
\\u0062\\u0063-", ""), "0", "0", "0" , | |
537 "", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061
\\u0062\\u0063-", ""), "0", "0", "0" , | |
538 //data for Latin-Devanagiri | |
539 CharsToUnicodeString("a\\u0304"), CharsToUnicodeString("Hindi -\\u09
06-"), "6", "7", "6", | |
540 CharsToUnicodeString("ma\\u0304"), CharsToUnicodeString("Hindi -\\u09
06\\u092E\\u093E-"), "7", "8", "7", | |
541 CharsToUnicodeString("ra\\u0304"), CharsToUnicodeString("Hi\\u0930\\u
093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2", | |
542 CharsToUnicodeString(""), CharsToUnicodeString("Hi\\u0930\\u093End
i -\\u0906\\u092E\\u093E-"),"1", "2", "2" | |
543 //data for contracted-Expanded | |
544 // CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u030
1d here:"), "1", "2", "1" , | |
545 // CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u030
1d here:\\u0041\\u0300"), "11", "11", "11", | |
546 // "", CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"),
"11", "11", "11", | |
547 }; | |
548 Transliterator *t; | |
549 UnicodeString rs; | |
550 UnicodeString dataStr; | |
551 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode
)"); | |
552 UErrorCode status = U_ZERO_ERROR; | |
553 UParseError parseError; | |
554 rs="Initial String: add--"; | |
555 t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, stat
us); | |
556 if(t == 0) | |
557 dataerrln("FAIL : construction - %s", u_errorName(status)); | |
558 else { | |
559 keyboardAux(t, Data, rs, 0, 20); | |
560 delete t; | |
561 } | |
562 | |
563 rs="Hindi --"; | |
564 t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseEr
ror, status); | |
565 if(t == 0) | |
566 dataerrln("FAIL : construction - %s", u_errorName(status)); | |
567 else | |
568 keyboardAux(t, Data, rs, 20, 40); | |
569 | |
570 | |
571 // rs="Add here:"; | |
572 // t=Transliterator::createInstance("Contracted-Expanded"); | |
573 // keyboardAux(t, Data, rs, 35, 55); | |
574 | |
575 | |
576 delete t; | |
577 } | |
578 | |
579 void TransliteratorAPITest::TestKeyboardTransliterator3(){ | |
580 UnicodeString s="This is the main string"; | |
581 UnicodeString Data[] = { | |
582 "0", "0", "0", "This is the main string", | |
583 "1", "3", "2", UnicodeString("Th\\u0069s is the main string", ""), | |
584 "20", "21", "20", UnicodeString("Th\\u0069s is the mai\\u006E string",
"") | |
585 }; | |
586 | |
587 UErrorCode status=U_ZERO_ERROR; | |
588 UParseError parseError; | |
589 UTransPosition index={0, 0, 0, 0}; | |
590 logln("Testing transliterate(Replaceable, int32_t, UErrorCode)"); | |
591 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD,
parseError, status); | |
592 if(t == 0 || U_FAILURE(status)) { | |
593 errln("Error creating transliterator %s", u_errorName(status)); | |
594 delete t; | |
595 return; | |
596 } | |
597 for(uint32_t i=0; i<sizeof(Data)/sizeof(Data[0]); i=i+4){ | |
598 UnicodeString log; | |
599 index.contextStart=getInt(Data[i+0]); | |
600 index.contextLimit=index.limit=getInt(Data[i+1]); | |
601 index.start=getInt(Data[i+2]); | |
602 t->transliterate(s, index, status); | |
603 if(U_FAILURE(status)){ | |
604 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[],
UErrorCode)-->" + (UnicodeString)u_errorName(status)); | |
605 continue; | |
606 } | |
607 t->finishTransliteration(s, index); | |
608 log = s + " => "; | |
609 // Show the start index '{' and the cursor '|' | |
610 displayOutput(s, Data[i+3], log, index); | |
611 } | |
612 | |
613 delete t; | |
614 } | |
615 void TransliteratorAPITest::TestNullTransliterator(){ | |
616 UErrorCode status=U_ZERO_ERROR; | |
617 UnicodeString s("Transliterate using null transliterator"); | |
618 Transliterator *nullTrans=Transliterator::createInstance("Any-Null", UTRANS_
FORWARD, status); | |
619 int32_t transLimit; | |
620 int32_t start=0; | |
621 int32_t limit=s.length(); | |
622 UnicodeString replaceable=s; | |
623 transLimit=nullTrans->transliterate(replaceable, start, limit); | |
624 if(transLimit != limit){ | |
625 errln("ERROR: NullTransliterator->transliterate() failed"); | |
626 } | |
627 doTest((UnicodeString)"nulTrans->transliterate", replaceable, s); | |
628 replaceable.remove(); | |
629 replaceable.append(s); | |
630 UTransPosition index; | |
631 index.contextStart =start; | |
632 index.contextLimit = limit; | |
633 index.start = 0; | |
634 index.limit = limit; | |
635 nullTrans->finishTransliteration(replaceable, index); | |
636 if(index.start != limit){ | |
637 errln("ERROR: NullTransliterator->handleTransliterate() failed"); | |
638 } | |
639 doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable
, s); | |
640 callEverything(nullTrans, __LINE__); | |
641 delete nullTrans; | |
642 | |
643 | |
644 } | |
645 void TransliteratorAPITest::TestRegisterUnregister(){ | |
646 | |
647 UErrorCode status=U_ZERO_ERROR; | |
648 /* Make sure it doesn't exist */ | |
649 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) !=
NULL) { | |
650 errln("FAIL: TestA-TestB already registered\n"); | |
651 return; | |
652 } | |
653 /* Check inverse too | |
654 if (Transliterator::createInstance("TestA-TestB", | |
655 (UTransDirection)UTRANS_REVERSE) != NULL)
{ | |
656 errln("FAIL: TestA-TestB inverse already registered\n"); | |
657 return; | |
658 } | |
659 */ | |
660 status =U_ZERO_ERROR; | |
661 | |
662 /* Create it */ | |
663 UParseError parseError; | |
664 Transliterator *t = Transliterator::createFromRules("TestA-TestB", | |
665 "a<>b", | |
666 UTRANS_FORWARD, parseError, | |
667 status); | |
668 /* Register it */ | |
669 Transliterator::registerInstance(t); | |
670 | |
671 /* Now check again -- should exist now*/ | |
672 Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORW
ARD, status); | |
673 if (s == NULL) { | |
674 errln("FAIL: TestA-TestB not registered\n"); | |
675 return; | |
676 } | |
677 callEverything(s, __LINE__); | |
678 callEverything(t, __LINE__); | |
679 delete s; | |
680 | |
681 /* Check inverse too | |
682 s = Transliterator::createInstance("TestA-TestB", | |
683 (UTransDirection)UTRANS_REVERSE); | |
684 if (s == NULL) { | |
685 errln("FAIL: TestA-TestB inverse not registered\n"); | |
686 return; | |
687 } | |
688 delete s; | |
689 */ | |
690 | |
691 /*unregister the instance*/ | |
692 Transliterator::unregister("TestA-TestB"); | |
693 /* now Make sure it doesn't exist */ | |
694 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) !=
NULL) { | |
695 errln("FAIL: TestA-TestB isn't unregistered\n"); | |
696 return; | |
697 } | |
698 | |
699 } | |
700 | |
701 | |
702 int gTestFilter1ClassID = 0; | |
703 int gTestFilter2ClassID = 0; | |
704 int gTestFilter3ClassID = 0; | |
705 | |
706 /** | |
707 * Used by TestFiltering(). | |
708 */ | |
709 class TestFilter1 : public UnicodeFilter { | |
710 UClassID getDynamicClassID()const { return &gTestFilter1ClassID; } | |
711 virtual UnicodeFunctor* clone() const { | |
712 return new TestFilter1(*this); | |
713 } | |
714 virtual UBool contains(UChar32 c) const { | |
715 if(c==0x63 || c==0x61 || c==0x43 || c==0x41) | |
716 return FALSE; | |
717 else | |
718 return TRUE; | |
719 } | |
720 // Stubs | |
721 virtual UnicodeString& toPattern(UnicodeString& result, | |
722 UBool /*escapeUnprintable*/) const { | |
723 return result; | |
724 } | |
725 virtual UBool matchesIndexValue(uint8_t /*v*/) const { | |
726 return FALSE; | |
727 } | |
728 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} | |
729 }; | |
730 class TestFilter2 : public UnicodeFilter { | |
731 UClassID getDynamicClassID()const { return &gTestFilter2ClassID; } | |
732 virtual UnicodeFunctor* clone() const { | |
733 return new TestFilter2(*this); | |
734 } | |
735 virtual UBool contains(UChar32 c) const { | |
736 if(c==0x65 || c==0x6c) | |
737 return FALSE; | |
738 else | |
739 return TRUE; | |
740 } | |
741 // Stubs | |
742 virtual UnicodeString& toPattern(UnicodeString& result, | |
743 UBool /*escapeUnprintable*/) const { | |
744 return result; | |
745 } | |
746 virtual UBool matchesIndexValue(uint8_t /*v*/) const { | |
747 return FALSE; | |
748 } | |
749 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} | |
750 }; | |
751 class TestFilter3 : public UnicodeFilter { | |
752 UClassID getDynamicClassID()const { return &gTestFilter3ClassID; } | |
753 virtual UnicodeFunctor* clone() const { | |
754 return new TestFilter3(*this); | |
755 } | |
756 virtual UBool contains(UChar32 c) const { | |
757 if(c==0x6f || c==0x77) | |
758 return FALSE; | |
759 else | |
760 return TRUE; | |
761 } | |
762 // Stubs | |
763 virtual UnicodeString& toPattern(UnicodeString& result, | |
764 UBool /*escapeUnprintable*/) const { | |
765 return result; | |
766 } | |
767 virtual UBool matchesIndexValue(uint8_t /*v*/) const { | |
768 return FALSE; | |
769 } | |
770 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} | |
771 }; | |
772 | |
773 | |
774 void TransliteratorAPITest::TestGetAdoptFilter(){ | |
775 UErrorCode status = U_ZERO_ERROR; | |
776 UParseError parseError; | |
777 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD,
parseError, status); | |
778 if(t == 0 || U_FAILURE(status)) { | |
779 errln("Error creating transliterator %s", u_errorName(status)); | |
780 delete t; | |
781 return; | |
782 } | |
783 const UnicodeFilter *u=t->getFilter(); | |
784 if(u != NULL){ | |
785 errln("FAIL: getFilter failed. Didn't return null when the transliterato
r used no filtering"); | |
786 delete t; | |
787 return; | |
788 } | |
789 | |
790 UnicodeString got, temp, message; | |
791 UnicodeString data="ABCabcbbCBa"; | |
792 temp = data; | |
793 t->transliterate(temp); | |
794 t->adoptFilter(new TestFilter1); | |
795 | |
796 got = data; | |
797 t->transliterate(got); | |
798 UnicodeString exp=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a",
""); | |
799 message="transliteration after adoptFilter(a,A,c,C) "; | |
800 doTest(message, got, exp); | |
801 | |
802 logln("Testing round trip"); | |
803 t->adoptFilter((UnicodeFilter*)u); | |
804 if(t->getFilter() == NULL) | |
805 logln("OK: adoptFilter and getFilter round trip worked"); | |
806 else | |
807 errln("FAIL: adoptFilter or getFilter round trip failed"); | |
808 | |
809 got = data; | |
810 t->transliterate(got); | |
811 exp=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\
\u0043\\u0042\\u0061", ""); | |
812 message="transliteration after adopting null filter"; | |
813 doTest(message, got, exp); | |
814 message="adoptFilter round trip"; | |
815 doTest("adoptFilter round trip", got, temp); | |
816 | |
817 t->adoptFilter(new TestFilter2); | |
818 callEverything(t, __LINE__); | |
819 data="heelloe"; | |
820 exp=UnicodeString("\\u0068eell\\u006Fe", ""); | |
821 got = data; | |
822 t->transliterate(got); | |
823 message="transliteration using (e,l) filter"; | |
824 doTest("transliteration using (e,l) filter", got, exp); | |
825 | |
826 data="are well"; | |
827 exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", ""); | |
828 got = data; | |
829 t->transliterate(got); | |
830 doTest(message, got, exp); | |
831 | |
832 t->adoptFilter(new TestFilter3); | |
833 data="ho, wow!"; | |
834 exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", ""); | |
835 got = data; | |
836 t->transliterate(got); | |
837 message="transliteration using (o,w) filter"; | |
838 doTest("transliteration using (o,w) filter", got, exp); | |
839 | |
840 data="owl"; | |
841 exp=UnicodeString("ow\\u006C", ""); | |
842 got = data; | |
843 t->transliterate(got); | |
844 doTest("transliteration using (o,w) filter", got, exp); | |
845 | |
846 delete t; | |
847 | |
848 } | |
849 | |
850 | |
851 | |
852 void TransliteratorAPITest::keyboardAux(Transliterator *t, UnicodeString DATA[],
UnicodeString& s, int32_t begin, int32_t end) { | |
853 UTransPosition index={0, 0, 0, 0}; | |
854 UErrorCode status=U_ZERO_ERROR; | |
855 for (int32_t i=begin; i<end; i=i+5) { | |
856 UnicodeString log; | |
857 if (DATA[i+0] != "") { | |
858 log = s + " + " + DATA[i] + " -> "; | |
859 index.contextStart=getInt(DATA[i+2]); | |
860 index.contextLimit=index.limit=getInt(DATA[i+3]); | |
861 index.start=getInt(DATA[i+4]); | |
862 t->transliterate(s, index, DATA[i+0], status); | |
863 if(U_FAILURE(status)){ | |
864 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32
_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | |
865 continue; | |
866 } | |
867 log = s + " => "; | |
868 t->finishTransliteration(s, index); | |
869 } | |
870 // Show the start index '{' and the cursor '|' | |
871 displayOutput(s, DATA[i+1], log, index); | |
872 | |
873 } | |
874 } | |
875 | |
876 void TransliteratorAPITest::displayOutput(const UnicodeString& got, const Unicod
eString& expected, UnicodeString& log, UTransPosition& index){ | |
877 // Show the start index '{' and the cursor '|' | |
878 UnicodeString a, b, c, d, e; | |
879 got.extractBetween(0, index.contextStart, a); | |
880 got.extractBetween(index.contextStart, index.start, b); | |
881 got.extractBetween(index.start, index.limit, c); | |
882 got.extractBetween(index.limit, index.contextLimit, d); | |
883 got.extractBetween(index.contextLimit, got.length(), e); | |
884 log.append(a). | |
885 append((UChar)0x7b/*{*/). | |
886 append(b). | |
887 append((UChar)0x7c/*|*/). | |
888 append(c). | |
889 append((UChar)0x7c). | |
890 append(d). | |
891 append((UChar)0x7d/*}*/). | |
892 append(e); | |
893 if (got == expected) | |
894 logln("OK:" + prettify(log)); | |
895 else | |
896 errln("FAIL: " + prettify(log) + ", expected " + prettify(expected)); | |
897 } | |
898 | |
899 | |
900 /*Internal Functions used*/ | |
901 void TransliteratorAPITest::doTest(const UnicodeString& message, const UnicodeSt
ring& result, const UnicodeString& expected){ | |
902 if (prettify(result) == prettify(expected)) | |
903 logln((UnicodeString)"Ok: " + prettify(message) + " passed \"" + prettif
y(expected) + "\""); | |
904 else | |
905 dataerrln((UnicodeString)"FAIL:" + message + " failed Got-->" + prettif
y(result)+ ", Expected--> " + prettify(expected) ); | |
906 } | |
907 | |
908 | |
909 // | |
910 // callEverything call all of the const (non-destructive) methods on a | |
911 // transliterator, just to verify that they don't fail in som
e | |
912 // destructive way. | |
913 // | |
914 #define CEASSERT(a) {if (!(a)) { \ | |
915 errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); return; }} | |
916 | |
917 void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) { | |
918 Transliterator *clonedTR = tr->clone(); | |
919 CEASSERT(clonedTR != NULL); | |
920 | |
921 int32_t maxcl = tr->getMaximumContextLength(); | |
922 CEASSERT(clonedTR->getMaximumContextLength() == maxcl); | |
923 | |
924 UnicodeString id; | |
925 UnicodeString clonedId; | |
926 id = tr->getID(); | |
927 clonedId = clonedTR->getID(); | |
928 CEASSERT(id == clonedId); | |
929 | |
930 const UnicodeFilter *filter = tr->getFilter(); | |
931 const UnicodeFilter *clonedFilter = clonedTR->getFilter(); | |
932 if (filter == NULL || clonedFilter == NULL) { | |
933 // If one filter is NULL they better both be NULL. | |
934 CEASSERT(filter == clonedFilter); | |
935 } else { | |
936 CEASSERT(filter != clonedFilter); | |
937 } | |
938 | |
939 UnicodeString rules; | |
940 UnicodeString clonedRules; | |
941 rules = tr->toRules(rules, FALSE); | |
942 clonedRules = clonedTR->toRules(clonedRules, FALSE); | |
943 CEASSERT(rules == clonedRules); | |
944 | |
945 UnicodeSet sourceSet; | |
946 UnicodeSet clonedSourceSet; | |
947 tr->getSourceSet(sourceSet); | |
948 clonedTR->getSourceSet(clonedSourceSet); | |
949 CEASSERT(clonedSourceSet == sourceSet); | |
950 | |
951 UnicodeSet targetSet; | |
952 UnicodeSet clonedTargetSet; | |
953 tr->getTargetSet(targetSet); | |
954 clonedTR->getTargetSet(clonedTargetSet); | |
955 CEASSERT(targetSet == clonedTargetSet); | |
956 | |
957 UClassID classID = tr->getDynamicClassID(); | |
958 CEASSERT(classID == clonedTR->getDynamicClassID()); | |
959 CEASSERT(classID != 0); | |
960 | |
961 delete clonedTR; | |
962 } | |
963 | |
964 static const int MyUnicodeFunctorTestClassID = 0; | |
965 class MyUnicodeFunctorTestClass : public UnicodeFunctor { | |
966 public: | |
967 virtual UnicodeFunctor* clone() const {return NULL;} | |
968 static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTe
stClassID;} | |
969 virtual UClassID getDynamicClassID(void) const {return getStaticClassID();}; | |
970 virtual void setData(const TransliterationRuleData*) {} | |
971 }; | |
972 | |
973 void TransliteratorAPITest::TestUnicodeFunctor() { | |
974 MyUnicodeFunctorTestClass myClass; | |
975 if (myClass.toMatcher() != NULL) { | |
976 errln("FAIL: UnicodeFunctor::toMatcher did not return NULL"); | |
977 } | |
978 if (myClass.toReplacer() != NULL) { | |
979 errln("FAIL: UnicodeFunctor::toReplacer did not return NULL"); | |
980 } | |
981 } | |
982 | |
983 | |
984 #endif /* #if !UCONFIG_NO_TRANSLITERATION */ | |
OLD | NEW |