]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
b75a7d8f A |
3 | /******************************************************************** |
4 | * COPYRIGHT: | |
57a6839d | 5 | * Copyright (c) 1997-2014, International Business Machines Corporation and |
b75a7d8f A |
6 | * others. All Rights Reserved. |
7 | ********************************************************************/ | |
57a6839d | 8 | /* file name: cbiditst.c |
f3c0d7a5 | 9 | * encoding: UTF-8 |
b75a7d8f A |
10 | * tab size: 8 (not used) |
11 | * indentation:4 | |
12 | * | |
13 | * created on: 1999sep27 | |
46f4442e | 14 | * created by: Markus W. Scherer, updated by Matitiahu Allouche |
b75a7d8f A |
15 | */ |
16 | ||
17 | #include "cintltst.h" | |
18 | #include "unicode/utypes.h" | |
19 | #include "unicode/uchar.h" | |
20 | #include "unicode/ustring.h" | |
21 | #include "unicode/ubidi.h" | |
22 | #include "unicode/ushape.h" | |
b75a7d8f A |
23 | #include "cbiditst.h" |
24 | #include "cstring.h" | |
73c04bcf A |
25 | /* the following include is needed for sprintf */ |
26 | #include <stdio.h> | |
b75a7d8f | 27 | |
73c04bcf | 28 | #define MAXLEN MAX_STRING_LENGTH |
b75a7d8f A |
29 | |
30 | /* prototypes ---------------------------------------------------------------*/ | |
31 | ||
46f4442e | 32 | void addComplexTest(TestNode** root); |
374ca955 | 33 | |
46f4442e | 34 | static void testCharFromDirProp(void); |
b75a7d8f | 35 | |
46f4442e | 36 | static void testBidi(void); |
b75a7d8f | 37 | |
46f4442e | 38 | static void doTests(UBiDi *pBiDi, UBiDi *pLine, UBool countRunsFirst); |
b75a7d8f | 39 | |
46f4442e | 40 | static void doMisc(void); |
b75a7d8f | 41 | |
46f4442e A |
42 | static void doTest(UBiDi *pBiDi, int testNumber, const BiDiTestData *test, |
43 | int32_t lineStart, UBool countRunsFirst); | |
b75a7d8f | 44 | |
46f4442e | 45 | static void _testReordering(UBiDi *pBiDi, int testNumber); |
b75a7d8f | 46 | |
46f4442e | 47 | static void testInverse(void); |
b75a7d8f | 48 | |
46f4442e | 49 | static void _testManyInverseBidi(UBiDi *pBiDi, UBiDiLevel direction); |
b75a7d8f | 50 | |
46f4442e A |
51 | static void _testInverseBidi(UBiDi *pBiDi, const UChar *src, int32_t srcLength, |
52 | UBiDiLevel direction, UErrorCode *pErrorCode); | |
b75a7d8f | 53 | |
46f4442e | 54 | static void _testWriteReverse(void); |
b75a7d8f | 55 | |
46f4442e | 56 | static void _testManyAddedPoints(void); |
b75a7d8f | 57 | |
46f4442e A |
58 | static void _testMisc(void); |
59 | ||
60 | static void doArabicShapingTest(void); | |
61 | ||
62 | static void doLamAlefSpecialVLTRArabicShapingTest(void); | |
b75a7d8f | 63 | |
46f4442e | 64 | static void doTashkeelSpecialVLTRArabicShapingTest(void); |
b75a7d8f | 65 | |
46f4442e | 66 | static void doLOGICALArabicDeShapingTest(void); |
73c04bcf | 67 | |
46f4442e A |
68 | static void doArabicShapingTestForBug5421(void); |
69 | ||
51004dcb A |
70 | static void doArabicShapingTestForBug8703(void); |
71 | ||
72 | static void doArabicShapingTestForBug9024(void); | |
73 | ||
57a6839d A |
74 | static void _testPresentationForms(const UChar *in); |
75 | ||
76 | static void doArabicShapingTestForNewCharacters(void); | |
77 | ||
46f4442e A |
78 | static void testReorder(void); |
79 | ||
51004dcb A |
80 | static void testReorderArabicMathSymbols(void); |
81 | ||
46f4442e A |
82 | static void testFailureRecovery(void); |
83 | ||
84 | static void testMultipleParagraphs(void); | |
73c04bcf | 85 | |
729e4ab9 A |
86 | static void testGetBaseDirection(void); |
87 | ||
4388f060 A |
88 | static void testContext(void); |
89 | ||
90 | static void doTailTest(void); | |
91 | ||
b331163b | 92 | static void testBracketOverflow(void); |
3d1f044b | 93 | static void TestExplicitLevel0(void); |
b331163b | 94 | |
73c04bcf | 95 | /* new BIDI API */ |
46f4442e A |
96 | static void testReorderingMode(void); |
97 | static void testReorderRunsOnly(void); | |
98 | static void testStreaming(void); | |
99 | static void testClassOverride(void); | |
100 | static const char* inverseBasic(UBiDi *pBiDi, const char *src, int32_t srcLen, | |
73c04bcf A |
101 | uint32_t option, UBiDiLevel level, char *result); |
102 | static UBool assertRoundTrip(UBiDi *pBiDi, int32_t tc, int32_t outIndex, | |
103 | const char *srcChars, const char *destChars, | |
104 | const UChar *dest, int32_t destLen, int mode, | |
105 | int option, UBiDiLevel level); | |
106 | static UBool checkResultLength(UBiDi *pBiDi, const char *srcChars, | |
46f4442e | 107 | const char *destChars, |
73c04bcf A |
108 | int32_t destLen, const char *mode, |
109 | const char *option, UBiDiLevel level); | |
46f4442e A |
110 | static UBool checkMaps(UBiDi *pBiDi, int32_t stringIndex, const char *src, |
111 | const char *dest, const char *mode, const char* option, | |
112 | UBiDiLevel level, UBool forward); | |
73c04bcf | 113 | |
b75a7d8f A |
114 | /* helpers ------------------------------------------------------------------ */ |
115 | ||
116 | static const char *levelString="..............................................................."; | |
117 | ||
46f4442e | 118 | static void initCharFromDirProps(void); |
374ca955 | 119 | |
b75a7d8f | 120 | static UChar * |
73c04bcf | 121 | getStringFromDirProps(const uint8_t *dirProps, int32_t length, UChar *buffer); |
b75a7d8f | 122 | |
46f4442e | 123 | static void printUnicode(const UChar *s, int32_t length, const UBiDiLevel *levels); |
b75a7d8f A |
124 | |
125 | /* regression tests ---------------------------------------------------------*/ | |
126 | ||
b75a7d8f A |
127 | void |
128 | addComplexTest(TestNode** root) { | |
46f4442e A |
129 | addTest(root, testCharFromDirProp, "complex/bidi/TestCharFromDirProp"); |
130 | addTest(root, testBidi, "complex/bidi/TestBidi"); | |
131 | addTest(root, testInverse, "complex/bidi/TestInverse"); | |
132 | addTest(root, testReorder,"complex/bidi/TestReorder"); | |
133 | addTest(root, testFailureRecovery,"complex/bidi/TestFailureRecovery"); | |
134 | addTest(root, testMultipleParagraphs,"complex/bidi/TestMultipleParagraphs"); | |
135 | addTest(root, testReorderingMode, "complex/bidi/TestReorderingMode"); | |
136 | addTest(root, testReorderRunsOnly, "complex/bidi/TestReorderRunsOnly"); | |
137 | addTest(root, testStreaming, "complex/bidi/TestStreaming"); | |
138 | addTest(root, testClassOverride, "complex/bidi/TestClassOverride"); | |
4388f060 A |
139 | addTest(root, testGetBaseDirection, "complex/bidi/testGetBaseDirection"); |
140 | addTest(root, testContext, "complex/bidi/testContext"); | |
b331163b | 141 | addTest(root, testBracketOverflow, "complex/bidi/TestBracketOverflow"); |
3d1f044b | 142 | addTest(root, TestExplicitLevel0, "complex/bidi/TestExplicitLevel0"); |
73c04bcf | 143 | |
b75a7d8f A |
144 | addTest(root, doArabicShapingTest, "complex/arabic-shaping/ArabicShapingTest"); |
145 | addTest(root, doLamAlefSpecialVLTRArabicShapingTest, "complex/arabic-shaping/lamalef"); | |
146 | addTest(root, doTashkeelSpecialVLTRArabicShapingTest, "complex/arabic-shaping/tashkeel"); | |
147 | addTest(root, doLOGICALArabicDeShapingTest, "complex/arabic-shaping/unshaping"); | |
46f4442e | 148 | addTest(root, doArabicShapingTestForBug5421, "complex/arabic-shaping/bug-5421"); |
4388f060 | 149 | addTest(root, doTailTest, "complex/arabic-shaping/tailtest"); |
51004dcb A |
150 | addTest(root, doArabicShapingTestForBug8703, "complex/arabic-shaping/bug-8703"); |
151 | addTest(root, testReorderArabicMathSymbols, "complex/bidi/bug-9024"); | |
152 | addTest(root, doArabicShapingTestForBug9024, "complex/arabic-shaping/bug-9024"); | |
57a6839d | 153 | addTest(root, doArabicShapingTestForNewCharacters, "complex/arabic-shaping/shaping2"); |
b75a7d8f A |
154 | } |
155 | ||
374ca955 | 156 | static void |
46f4442e A |
157 | testCharFromDirProp(void) { |
158 | /* verify that the exemplar characters have the expected bidi classes */ | |
374ca955 A |
159 | int32_t i; |
160 | ||
46f4442e | 161 | log_verbose("\nEntering TestCharFromDirProp\n\n"); |
374ca955 A |
162 | initCharFromDirProps(); |
163 | ||
164 | for(i=0; i<U_CHAR_DIRECTION_COUNT; ++i) { | |
165 | if(u_charDirection(charFromDirProp[i])!=(UCharDirection)i) { | |
73c04bcf | 166 | log_err("\nu_charDirection(charFromDirProp[%d]=U+%04x)==%d!=%d\n", |
374ca955 A |
167 | i, charFromDirProp[i], u_charDirection(charFromDirProp[i]), i); |
168 | } | |
169 | } | |
46f4442e | 170 | log_verbose("\nExiting TestCharFromDirProp\n\n"); |
374ca955 A |
171 | } |
172 | ||
b75a7d8f | 173 | static void |
46f4442e | 174 | testBidi(void) { |
b75a7d8f A |
175 | UBiDi *pBiDi, *pLine=NULL; |
176 | UErrorCode errorCode=U_ZERO_ERROR; | |
177 | ||
46f4442e | 178 | log_verbose("\nEntering TestBidi\n\n"); |
b75a7d8f | 179 | |
73c04bcf | 180 | pBiDi=ubidi_openSized(MAXLEN, 0, &errorCode); |
b75a7d8f A |
181 | if(pBiDi!=NULL) { |
182 | pLine=ubidi_open(); | |
183 | if(pLine!=NULL) { | |
374ca955 A |
184 | doTests(pBiDi, pLine, FALSE); |
185 | doTests(pBiDi, pLine, TRUE); | |
b75a7d8f A |
186 | } else { |
187 | log_err("ubidi_open() returned NULL, out of memory\n"); | |
188 | } | |
189 | } else { | |
190 | log_err("ubidi_openSized() returned NULL, errorCode %s\n", myErrorName(errorCode)); | |
191 | } | |
46f4442e | 192 | doMisc(); |
b75a7d8f A |
193 | |
194 | if(pLine!=NULL) { | |
195 | ubidi_close(pLine); | |
196 | } | |
197 | if(pBiDi!=NULL) { | |
198 | ubidi_close(pBiDi); | |
199 | } | |
200 | ||
46f4442e | 201 | log_verbose("\nExiting TestBidi\n\n"); |
b75a7d8f A |
202 | } |
203 | ||
204 | static void | |
374ca955 | 205 | doTests(UBiDi *pBiDi, UBiDi *pLine, UBool countRunsFirst) { |
46f4442e | 206 | int testNumber; |
73c04bcf | 207 | UChar string[MAXLEN]; |
b75a7d8f A |
208 | UErrorCode errorCode; |
209 | int32_t lineStart; | |
210 | UBiDiLevel paraLevel; | |
211 | ||
46f4442e | 212 | for(testNumber=0; testNumber<bidiTestCount; ++testNumber) { |
b75a7d8f | 213 | errorCode=U_ZERO_ERROR; |
46f4442e A |
214 | getStringFromDirProps(tests[testNumber].text, tests[testNumber].length, string); |
215 | paraLevel=tests[testNumber].paraLevel; | |
73c04bcf | 216 | ubidi_setPara(pBiDi, string, -1, paraLevel, NULL, &errorCode); |
b75a7d8f A |
217 | if(U_SUCCESS(errorCode)) { |
218 | log_verbose("ubidi_setPara(tests[%d], paraLevel %d) ok, direction %d paraLevel=%d\n", | |
46f4442e A |
219 | testNumber, paraLevel, ubidi_getDirection(pBiDi), paraLevel); |
220 | lineStart=tests[testNumber].lineStart; | |
b75a7d8f | 221 | if(lineStart==-1) { |
46f4442e | 222 | doTest(pBiDi, testNumber, tests+testNumber, 0, countRunsFirst); |
b75a7d8f | 223 | } else { |
46f4442e | 224 | ubidi_setLine(pBiDi, lineStart, tests[testNumber].lineLimit, pLine, &errorCode); |
b75a7d8f A |
225 | if(U_SUCCESS(errorCode)) { |
226 | log_verbose("ubidi_setLine(%d, %d) ok, direction %d paraLevel=%d\n", | |
46f4442e A |
227 | lineStart, tests[testNumber].lineLimit, ubidi_getDirection(pLine), ubidi_getParaLevel(pLine)); |
228 | doTest(pLine, testNumber, tests+testNumber, lineStart, countRunsFirst); | |
b75a7d8f A |
229 | } else { |
230 | log_err("ubidi_setLine(tests[%d], %d, %d) failed with errorCode %s\n", | |
46f4442e | 231 | testNumber, lineStart, tests[testNumber].lineLimit, myErrorName(errorCode)); |
b75a7d8f A |
232 | } |
233 | } | |
234 | } else { | |
235 | log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n", | |
46f4442e | 236 | testNumber, paraLevel, myErrorName(errorCode)); |
b75a7d8f A |
237 | } |
238 | } | |
239 | } | |
73c04bcf | 240 | |
46f4442e | 241 | static const char columns[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
73c04bcf A |
242 | |
243 | #define TABLE_SIZE 256 | |
244 | static UBool tablesInitialized = FALSE; | |
245 | static UChar pseudoToUChar[TABLE_SIZE]; | |
246 | static uint8_t UCharToPseudo[TABLE_SIZE]; /* used for Unicode chars < 0x0100 */ | |
247 | static uint8_t UCharToPseud2[TABLE_SIZE]; /* used for Unicode chars >=0x0100 */ | |
248 | ||
249 | static void buildPseudoTables(void) | |
250 | /* | |
251 | The rules for pseudo-Bidi are as follows: | |
252 | - [ == LRE | |
253 | - ] == RLE | |
254 | - { == LRO | |
255 | - } == RLO | |
256 | ||
257 | - @ == LRM | |
258 | - & == RLM | |
259 | - A-F == Arabic Letters 0631-0636 | |
46f4442e A |
260 | - G-V == Hebrew letters 05d7-05e6 |
261 | - W-Z == Unassigned RTL 08d0-08d3 | |
0f5d89e8 A |
262 | Unicode 6.1 changes U+08A0..U+08FF from R to AL which works ok. |
263 | Unicode 11 adds U+08D3 ARABIC SMALL LOW WAW which has bc=NSM | |
264 | so we stop using Z in this test. | |
73c04bcf A |
265 | - 0-5 == western digits 0030-0035 |
266 | - 6-9 == Arabic-Indic digits 0666-0669 | |
267 | - ` == Combining Grave Accent 0300 (NSM) | |
268 | - ~ == Delete 007f (BN) | |
269 | - | == Paragraph Separator 2029 (B) | |
270 | - _ == Info Separator 1 001f (S) | |
271 | All other characters represent themselves as Latin-1, with the corresponding | |
272 | Bidi properties. | |
273 | */ | |
274 | { | |
275 | int i; | |
276 | UChar uchar; | |
277 | uint8_t c; | |
278 | /* initialize all tables to unknown */ | |
279 | for (i=0; i < TABLE_SIZE; i++) { | |
280 | pseudoToUChar[i] = 0xFFFD; | |
281 | UCharToPseudo[i] = '?'; | |
282 | UCharToPseud2[i] = '?'; | |
283 | } | |
284 | /* initialize non letters or digits */ | |
285 | pseudoToUChar[(uint8_t) 0 ] = 0x0000; UCharToPseudo[0x00] = (uint8_t) 0 ; | |
286 | pseudoToUChar[(uint8_t)' '] = 0x0020; UCharToPseudo[0x20] = (uint8_t)' '; | |
287 | pseudoToUChar[(uint8_t)'!'] = 0x0021; UCharToPseudo[0x21] = (uint8_t)'!'; | |
288 | pseudoToUChar[(uint8_t)'"'] = 0x0022; UCharToPseudo[0x22] = (uint8_t)'"'; | |
289 | pseudoToUChar[(uint8_t)'#'] = 0x0023; UCharToPseudo[0x23] = (uint8_t)'#'; | |
290 | pseudoToUChar[(uint8_t)'$'] = 0x0024; UCharToPseudo[0x24] = (uint8_t)'$'; | |
291 | pseudoToUChar[(uint8_t)'%'] = 0x0025; UCharToPseudo[0x25] = (uint8_t)'%'; | |
292 | pseudoToUChar[(uint8_t)'\'']= 0x0027; UCharToPseudo[0x27] = (uint8_t)'\''; | |
293 | pseudoToUChar[(uint8_t)'('] = 0x0028; UCharToPseudo[0x28] = (uint8_t)'('; | |
294 | pseudoToUChar[(uint8_t)')'] = 0x0029; UCharToPseudo[0x29] = (uint8_t)')'; | |
295 | pseudoToUChar[(uint8_t)'*'] = 0x002A; UCharToPseudo[0x2A] = (uint8_t)'*'; | |
296 | pseudoToUChar[(uint8_t)'+'] = 0x002B; UCharToPseudo[0x2B] = (uint8_t)'+'; | |
297 | pseudoToUChar[(uint8_t)','] = 0x002C; UCharToPseudo[0x2C] = (uint8_t)','; | |
298 | pseudoToUChar[(uint8_t)'-'] = 0x002D; UCharToPseudo[0x2D] = (uint8_t)'-'; | |
299 | pseudoToUChar[(uint8_t)'.'] = 0x002E; UCharToPseudo[0x2E] = (uint8_t)'.'; | |
300 | pseudoToUChar[(uint8_t)'/'] = 0x002F; UCharToPseudo[0x2F] = (uint8_t)'/'; | |
301 | pseudoToUChar[(uint8_t)':'] = 0x003A; UCharToPseudo[0x3A] = (uint8_t)':'; | |
302 | pseudoToUChar[(uint8_t)';'] = 0x003B; UCharToPseudo[0x3B] = (uint8_t)';'; | |
303 | pseudoToUChar[(uint8_t)'<'] = 0x003C; UCharToPseudo[0x3C] = (uint8_t)'<'; | |
304 | pseudoToUChar[(uint8_t)'='] = 0x003D; UCharToPseudo[0x3D] = (uint8_t)'='; | |
305 | pseudoToUChar[(uint8_t)'>'] = 0x003E; UCharToPseudo[0x3E] = (uint8_t)'>'; | |
306 | pseudoToUChar[(uint8_t)'?'] = 0x003F; UCharToPseudo[0x3F] = (uint8_t)'?'; | |
307 | pseudoToUChar[(uint8_t)'\\']= 0x005C; UCharToPseudo[0x5C] = (uint8_t)'\\'; | |
308 | /* initialize specially used characters */ | |
309 | pseudoToUChar[(uint8_t)'`'] = 0x0300; UCharToPseud2[0x00] = (uint8_t)'`'; /* NSM */ | |
310 | pseudoToUChar[(uint8_t)'@'] = 0x200E; UCharToPseud2[0x0E] = (uint8_t)'@'; /* LRM */ | |
311 | pseudoToUChar[(uint8_t)'&'] = 0x200F; UCharToPseud2[0x0F] = (uint8_t)'&'; /* RLM */ | |
312 | pseudoToUChar[(uint8_t)'_'] = 0x001F; UCharToPseudo[0x1F] = (uint8_t)'_'; /* S */ | |
313 | pseudoToUChar[(uint8_t)'|'] = 0x2029; UCharToPseud2[0x29] = (uint8_t)'|'; /* B */ | |
314 | pseudoToUChar[(uint8_t)'['] = 0x202A; UCharToPseud2[0x2A] = (uint8_t)'['; /* LRE */ | |
315 | pseudoToUChar[(uint8_t)']'] = 0x202B; UCharToPseud2[0x2B] = (uint8_t)']'; /* RLE */ | |
316 | pseudoToUChar[(uint8_t)'^'] = 0x202C; UCharToPseud2[0x2C] = (uint8_t)'^'; /* PDF */ | |
317 | pseudoToUChar[(uint8_t)'{'] = 0x202D; UCharToPseud2[0x2D] = (uint8_t)'{'; /* LRO */ | |
318 | pseudoToUChar[(uint8_t)'}'] = 0x202E; UCharToPseud2[0x2E] = (uint8_t)'}'; /* RLO */ | |
319 | pseudoToUChar[(uint8_t)'~'] = 0x007F; UCharToPseudo[0x7F] = (uint8_t)'~'; /* BN */ | |
320 | /* initialize western digits */ | |
321 | for (i = 0, uchar = 0x0030; i < 6; i++, uchar++) { | |
322 | c = (uint8_t)columns[i]; | |
323 | pseudoToUChar[c] = uchar; | |
324 | UCharToPseudo[uchar & 0x00ff] = c; | |
325 | } | |
326 | /* initialize Hindi digits */ | |
327 | for (i = 6, uchar = 0x0666; i < 10; i++, uchar++) { | |
328 | c = (uint8_t)columns[i]; | |
329 | pseudoToUChar[c] = uchar; | |
330 | UCharToPseud2[uchar & 0x00ff] = c; | |
331 | } | |
332 | /* initialize Arabic letters */ | |
333 | for (i = 10, uchar = 0x0631; i < 16; i++, uchar++) { | |
334 | c = (uint8_t)columns[i]; | |
335 | pseudoToUChar[c] = uchar; | |
336 | UCharToPseud2[uchar & 0x00ff] = c; | |
337 | } | |
338 | /* initialize Hebrew letters */ | |
46f4442e A |
339 | for (i = 16, uchar = 0x05D7; i < 32; i++, uchar++) { |
340 | c = (uint8_t)columns[i]; | |
341 | pseudoToUChar[c] = uchar; | |
342 | UCharToPseud2[uchar & 0x00ff] = c; | |
343 | } | |
344 | /* initialize Unassigned code points */ | |
345 | for (i = 32, uchar=0x08D0; i < 36; i++, uchar++) { | |
73c04bcf A |
346 | c = (uint8_t)columns[i]; |
347 | pseudoToUChar[c] = uchar; | |
348 | UCharToPseud2[uchar & 0x00ff] = c; | |
349 | } | |
350 | /* initialize Latin lower case letters */ | |
351 | for (i = 36, uchar = 0x0061; i < 62; i++, uchar++) { | |
352 | c = (uint8_t)columns[i]; | |
353 | pseudoToUChar[c] = uchar; | |
354 | UCharToPseudo[uchar & 0x00ff] = c; | |
355 | } | |
356 | tablesInitialized = TRUE; | |
357 | } | |
358 | ||
359 | /*----------------------------------------------------------------------*/ | |
360 | ||
46f4442e | 361 | static int pseudoToU16(const int length, const char * input, UChar * output) |
73c04bcf A |
362 | /* This function converts a pseudo-Bidi string into a UChar string. |
363 | It returns the length of the UChar string. | |
364 | */ | |
365 | { | |
366 | int i; | |
367 | if (!tablesInitialized) { | |
368 | buildPseudoTables(); | |
369 | } | |
370 | for (i = 0; i < length; i++) | |
371 | output[i] = pseudoToUChar[(uint8_t)input[i]]; | |
4388f060 | 372 | output[length] = 0; |
73c04bcf A |
373 | return length; |
374 | } | |
375 | ||
376 | /*----------------------------------------------------------------------*/ | |
377 | ||
46f4442e | 378 | static int u16ToPseudo(const int length, const UChar * input, char * output) |
73c04bcf A |
379 | /* This function converts a UChar string into a pseudo-Bidi string. |
380 | It returns the length of the pseudo-Bidi string. | |
381 | */ | |
382 | { | |
383 | int i; | |
384 | UChar uchar; | |
385 | if (!tablesInitialized) { | |
386 | buildPseudoTables(); | |
387 | } | |
388 | for (i = 0; i < length; i++) | |
389 | { | |
390 | uchar = input[i]; | |
391 | output[i] = uchar < 0x0100 ? UCharToPseudo[uchar] : | |
392 | UCharToPseud2[uchar & 0x00ff]; | |
393 | } | |
394 | output[length] = '\0'; | |
395 | return length; | |
396 | } | |
397 | ||
398 | static char * formatLevels(UBiDi *bidi, char *buffer) { | |
399 | UErrorCode ec = U_ZERO_ERROR; | |
400 | const UBiDiLevel* gotLevels = ubidi_getLevels(bidi, &ec); | |
340931cb | 401 | int32_t len = ubidi_getLength(bidi); |
73c04bcf | 402 | char c; |
340931cb | 403 | int32_t i, k; |
73c04bcf A |
404 | |
405 | if(U_FAILURE(ec)) { | |
406 | strcpy(buffer, "BAD LEVELS"); | |
407 | return buffer; | |
408 | } | |
409 | for (i=0; i<len; i++) { | |
410 | k = gotLevels[i]; | |
340931cb | 411 | if (k >= (int32_t)sizeof(columns)) |
73c04bcf A |
412 | c = '+'; |
413 | else | |
414 | c = columns[k]; | |
415 | buffer[i] = c; | |
416 | } | |
417 | buffer[len] = '\0'; | |
418 | return buffer; | |
419 | } | |
46f4442e A |
420 | static const char *reorderingModeNames[] = { |
421 | "UBIDI_REORDER_DEFAULT", | |
422 | "UBIDI_REORDER_NUMBERS_SPECIAL", | |
423 | "UBIDI_REORDER_GROUP_NUMBERS_WITH_R", | |
424 | "UBIDI_REORDER_RUNS_ONLY", | |
425 | "UBIDI_REORDER_INVERSE_NUMBERS_AS_L", | |
426 | "UBIDI_REORDER_INVERSE_LIKE_DIRECT", | |
427 | "UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL"}; | |
428 | ||
429 | static char *reorderingOptionNames(char *buffer, int options) { | |
430 | buffer[0] = 0; | |
431 | if (options & UBIDI_OPTION_INSERT_MARKS) { | |
432 | strcat(buffer, " UBIDI_OPTION_INSERT_MARKS"); | |
433 | } | |
434 | if (options & UBIDI_OPTION_REMOVE_CONTROLS) { | |
435 | strcat(buffer, " UBIDI_OPTION_REMOVE_CONTROLS"); | |
436 | } | |
437 | if (options & UBIDI_OPTION_STREAMING) { | |
438 | strcat(buffer, " UBIDI_OPTION_STREAMING"); | |
439 | } | |
440 | return buffer; | |
441 | } | |
442 | ||
443 | static void printCaseInfo(UBiDi *bidi, const char *src, const char *dst) | |
444 | /* src and dst are char arrays encoded as pseudo Bidi */ | |
445 | { | |
446 | /* Since calls to log_err with a \n within the pattern increment the | |
447 | * error count, new lines are issued via fputs, except when we want the | |
448 | * increment to happen. | |
449 | */ | |
450 | UErrorCode errorCode=U_ZERO_ERROR; | |
451 | int32_t i, length = ubidi_getProcessedLength(bidi); | |
452 | const UBiDiLevel *levels; | |
453 | char levelChars[MAXLEN]; | |
454 | UBiDiLevel lev; | |
455 | int32_t runCount; | |
456 | char buffer[100]; | |
457 | log_err("========================================"); fputs("\n", stderr); | |
458 | levels = ubidi_getLevels(bidi, &errorCode); | |
459 | if (U_FAILURE(errorCode)) { | |
460 | strcpy(levelChars, "BAD LEVELS"); | |
461 | } else { | |
462 | log_err("Processed length: %d", length); fputs("\n", stderr); | |
463 | for (i = 0; i < length; i++) { | |
464 | lev = levels[i]; | |
465 | if (lev < sizeof(columns)) { | |
466 | levelChars[i] = columns[lev]; | |
467 | } else { | |
468 | levelChars[i] = '+'; | |
469 | } | |
470 | } | |
471 | levelChars[length] = 0; | |
472 | } | |
473 | log_err("Levels: %s", levelChars); fputs("\n", stderr); | |
474 | log_err("Source: %s", src); fputs("\n", stderr); | |
475 | log_err("Result: %s", dst); fputs("\n", stderr); | |
476 | log_err("Direction: %d", ubidi_getDirection(bidi)); fputs("\n", stderr); | |
477 | log_err("paraLevel: %d", ubidi_getParaLevel(bidi)); fputs("\n", stderr); | |
478 | i = ubidi_getReorderingMode(bidi); | |
479 | log_err("reorderingMode: %d = %s", i, reorderingModeNames[i]); | |
480 | fputs("\n", stderr); | |
481 | i = ubidi_getReorderingOptions(bidi); | |
482 | log_err("reorderingOptions: %d = %s", i, reorderingOptionNames(buffer, i)); | |
483 | fputs("\n", stderr); | |
484 | runCount = ubidi_countRuns(bidi, &errorCode); | |
485 | if (U_FAILURE(errorCode)) { | |
486 | log_err( "BAD RUNS"); | |
487 | } else { | |
488 | log_err("Runs: %d => logicalStart.length/level: ", runCount); | |
489 | for (i = 0; i < runCount; i++) { | |
490 | UBiDiDirection dir; | |
491 | int32_t start, len; | |
492 | dir = ubidi_getVisualRun(bidi, i, &start, &len); | |
493 | log_err(" %d.%d/%d", start, len, dir); | |
494 | } | |
495 | } | |
496 | fputs("\n", stderr); | |
497 | } | |
498 | ||
499 | static UBool matchingPair(UBiDi *bidi, int32_t i, char c1, char c2) | |
500 | { | |
501 | /* No test for []{} since they have special meaning for pseudo Bidi */ | |
502 | static char mates1Chars[] = "<>()"; | |
503 | static char mates2Chars[] = "><)("; | |
504 | UBiDiLevel level; | |
505 | int k, len; | |
506 | ||
507 | if (c1 == c2) { | |
508 | return TRUE; | |
509 | } | |
510 | /* For UBIDI_REORDER_RUNS_ONLY, it would not be correct to check levels[i], | |
511 | so we use the appropriate run's level, which is good for all cases. | |
512 | */ | |
513 | ubidi_getLogicalRun(bidi, i, NULL, &level); | |
514 | if ((level & 1) == 0) { | |
515 | return FALSE; | |
516 | } | |
3d1f044b | 517 | len = (int)strlen(mates1Chars); |
46f4442e A |
518 | for (k = 0; k < len; k++) { |
519 | if ((c1 == mates1Chars[k]) && (c2 == mates2Chars[k])) { | |
520 | return TRUE; | |
521 | } | |
522 | } | |
523 | return FALSE; | |
524 | } | |
525 | ||
526 | static UBool checkWhatYouCan(UBiDi *bidi, const char *srcChars, const char *dstChars) | |
527 | /* srcChars and dstChars are char arrays encoded as pseudo Bidi */ | |
528 | { | |
529 | int32_t i, idx, logLimit, visLimit; | |
530 | UBool testOK, errMap, errDst; | |
531 | UErrorCode errorCode=U_ZERO_ERROR; | |
532 | int32_t visMap[MAXLEN]; | |
533 | int32_t logMap[MAXLEN]; | |
534 | char accumSrc[MAXLEN]; | |
535 | char accumDst[MAXLEN]; | |
536 | ubidi_getVisualMap(bidi, visMap, &errorCode); | |
537 | ubidi_getLogicalMap(bidi, logMap, &errorCode); | |
538 | if (U_FAILURE(errorCode)) { | |
539 | log_err("Error #1 invoking ICU within checkWhatYouCan\n"); | |
540 | return FALSE; | |
541 | } | |
542 | ||
543 | testOK = TRUE; | |
544 | errMap = errDst = FALSE; | |
545 | logLimit = ubidi_getProcessedLength(bidi); | |
546 | visLimit = ubidi_getResultLength(bidi); | |
547 | memset(accumSrc, '?', logLimit); | |
548 | memset(accumDst, '?', visLimit); | |
549 | ||
550 | for (i = 0; i < logLimit; i++) { | |
551 | idx = ubidi_getVisualIndex(bidi, i, &errorCode); | |
552 | if (idx != logMap[i]) { | |
553 | errMap = TRUE; | |
554 | } | |
555 | if (idx == UBIDI_MAP_NOWHERE) { | |
556 | continue; | |
557 | } | |
558 | if (idx >= visLimit) { | |
559 | continue; | |
560 | } | |
561 | accumDst[idx] = srcChars[i]; | |
562 | if (!matchingPair(bidi, i, srcChars[i], dstChars[idx])) { | |
563 | errDst = TRUE; | |
564 | } | |
565 | } | |
566 | accumDst[visLimit] = 0; | |
567 | if (U_FAILURE(errorCode)) { | |
568 | log_err("Error #2 invoking ICU within checkWhatYouCan\n"); | |
569 | return FALSE; | |
570 | } | |
571 | if (errMap) { | |
572 | if (testOK) { | |
573 | printCaseInfo(bidi, srcChars, dstChars); | |
574 | testOK = FALSE; | |
575 | } | |
576 | log_err("Mismatch between getLogicalMap() and getVisualIndex()\n"); | |
577 | log_err("Map :"); | |
578 | for (i = 0; i < logLimit; i++) { | |
579 | log_err(" %d", logMap[i]); | |
580 | } | |
581 | fputs("\n", stderr); | |
582 | log_err("Indexes:"); | |
583 | for (i = 0; i < logLimit; i++) { | |
584 | log_err(" %d", ubidi_getVisualIndex(bidi, i, &errorCode)); | |
585 | } | |
586 | fputs("\n", stderr); | |
587 | } | |
588 | if (errDst) { | |
589 | if (testOK) { | |
590 | printCaseInfo(bidi, srcChars, dstChars); | |
591 | testOK = FALSE; | |
592 | } | |
593 | log_err("Source does not map to Result\n"); | |
594 | log_err("We got: %s", accumDst); fputs("\n", stderr); | |
595 | } | |
596 | ||
597 | errMap = errDst = FALSE; | |
598 | for (i = 0; i < visLimit; i++) { | |
599 | idx = ubidi_getLogicalIndex(bidi, i, &errorCode); | |
600 | if (idx != visMap[i]) { | |
601 | errMap = TRUE; | |
602 | } | |
603 | if (idx == UBIDI_MAP_NOWHERE) { | |
604 | continue; | |
605 | } | |
606 | if (idx >= logLimit) { | |
607 | continue; | |
608 | } | |
609 | accumSrc[idx] = dstChars[i]; | |
610 | if (!matchingPair(bidi, idx, srcChars[idx], dstChars[i])) { | |
611 | errDst = TRUE; | |
612 | } | |
613 | } | |
614 | accumSrc[logLimit] = 0; | |
615 | if (U_FAILURE(errorCode)) { | |
616 | log_err("Error #3 invoking ICU within checkWhatYouCan\n"); | |
617 | return FALSE; | |
618 | } | |
619 | if (errMap) { | |
620 | if (testOK) { | |
621 | printCaseInfo(bidi, srcChars, dstChars); | |
622 | testOK = FALSE; | |
623 | } | |
624 | log_err("Mismatch between getVisualMap() and getLogicalIndex()\n"); | |
625 | log_err("Map :"); | |
626 | for (i = 0; i < visLimit; i++) { | |
627 | log_err(" %d", visMap[i]); | |
628 | } | |
629 | fputs("\n", stderr); | |
630 | log_err("Indexes:"); | |
631 | for (i = 0; i < visLimit; i++) { | |
632 | log_err(" %d", ubidi_getLogicalIndex(bidi, i, &errorCode)); | |
633 | } | |
634 | fputs("\n", stderr); | |
635 | } | |
636 | if (errDst) { | |
637 | if (testOK) { | |
638 | printCaseInfo(bidi, srcChars, dstChars); | |
639 | testOK = FALSE; | |
640 | } | |
641 | log_err("Result does not map to Source\n"); | |
642 | log_err("We got: %s", accumSrc); | |
643 | fputs("\n", stderr); | |
644 | } | |
645 | return testOK; | |
646 | } | |
73c04bcf | 647 | |
46f4442e A |
648 | static void |
649 | testReorder(void) { | |
b75a7d8f | 650 | static const char* const logicalOrder[] ={ |
73c04bcf A |
651 | "del(KC)add(K.C.&)", |
652 | "del(QDVT) add(BVDL)", | |
653 | "del(PQ)add(R.S.)T)U.&", | |
654 | "del(LV)add(L.V.) L.V.&", | |
655 | "day 0 R DPDHRVR dayabbr", | |
656 | "day 1 H DPHPDHDA dayabbr", | |
657 | "day 2 L DPBLENDA dayabbr", | |
658 | "day 3 J DPJQVM dayabbr", | |
659 | "day 4 I DPIQNF dayabbr", | |
660 | "day 5 M DPMEG dayabbr", | |
661 | "helloDPMEG", | |
0f5d89e8 | 662 | "hello WXY" |
b75a7d8f A |
663 | }; |
664 | static const char* const visualOrder[]={ | |
73c04bcf A |
665 | "del(CK)add(&.C.K)", |
666 | "del(TVDQ) add(LDVB)", | |
57a6839d A |
667 | "del(QP)add(S.R.)&.U(T", /* updated for Unicode 6.3 matching brackets */ |
668 | "del(VL)add(V.L.) &.V.L", /* updated for Unicode 6.3 matching brackets */ | |
73c04bcf A |
669 | "day 0 RVRHDPD R dayabbr", |
670 | "day 1 ADHDPHPD H dayabbr", | |
671 | "day 2 ADNELBPD L dayabbr", | |
672 | "day 3 MVQJPD J dayabbr", | |
673 | "day 4 FNQIPD I dayabbr", | |
674 | "day 5 GEMPD M dayabbr", | |
675 | "helloGEMPD", | |
0f5d89e8 | 676 | "hello YXW" |
b75a7d8f A |
677 | }; |
678 | static const char* const visualOrder1[]={ | |
73c04bcf A |
679 | ")K.C.&(dda)KC(led", |
680 | ")BVDL(dda )QDVT(led", | |
57a6839d A |
681 | "T(U.&).R.S(dda)PQ(led", /* updated for Unicode 6.3 matching brackets */ |
682 | "L.V.& ).L.V(dda)LV(led", /* updated for Unicode 6.3 matching brackets */ | |
73c04bcf A |
683 | "rbbayad R DPDHRVR 0 yad", |
684 | "rbbayad H DPHPDHDA 1 yad", | |
685 | "rbbayad L DPBLENDA 2 yad", | |
686 | "rbbayad J DPJQVM 3 yad", | |
687 | "rbbayad I DPIQNF 4 yad", | |
688 | "rbbayad M DPMEG 5 yad", | |
689 | "DPMEGolleh", | |
0f5d89e8 | 690 | "WXY olleh" |
b75a7d8f A |
691 | }; |
692 | ||
693 | static const char* const visualOrder2[]={ | |
73c04bcf A |
694 | "@)@K.C.&@(dda)@KC@(led", |
695 | "@)@BVDL@(dda )@QDVT@(led", | |
696 | "R.S.)T)U.&@(dda)@PQ@(led", | |
697 | "L.V.) L.V.&@(dda)@LV@(led", | |
698 | "rbbayad @R DPDHRVR@ 0 yad", | |
699 | "rbbayad @H DPHPDHDA@ 1 yad", | |
700 | "rbbayad @L DPBLENDA@ 2 yad", | |
701 | "rbbayad @J DPJQVM@ 3 yad", | |
702 | "rbbayad @I DPIQNF@ 4 yad", | |
703 | "rbbayad @M DPMEG@ 5 yad", | |
704 | "DPMEGolleh", | |
0f5d89e8 | 705 | "WXY@ olleh" |
b75a7d8f A |
706 | }; |
707 | static const char* const visualOrder3[]={ | |
73c04bcf A |
708 | ")K.C.&(KC)dda(led", |
709 | ")BVDL(ddaQDVT) (led", | |
710 | "R.S.)T)U.&(PQ)dda(led", | |
711 | "L.V.) L.V.&(LV)dda(led", | |
712 | "rbbayad DPDHRVR R 0 yad", | |
713 | "rbbayad DPHPDHDA H 1 yad", | |
714 | "rbbayad DPBLENDA L 2 yad", | |
715 | "rbbayad DPJQVM J 3 yad", | |
716 | "rbbayad DPIQNF I 4 yad", | |
717 | "rbbayad DPMEG M 5 yad", | |
46f4442e | 718 | "DPMEGolleh", |
0f5d89e8 | 719 | "WXY olleh" |
b75a7d8f A |
720 | }; |
721 | static const char* const visualOrder4[]={ | |
73c04bcf A |
722 | "del(add(CK(.C.K)", |
723 | "del( (TVDQadd(LDVB)", | |
724 | "del(add(QP(.U(T(.S.R", | |
725 | "del(add(VL(.V.L (.V.L", | |
726 | "day 0 R RVRHDPD dayabbr", | |
727 | "day 1 H ADHDPHPD dayabbr", | |
728 | "day 2 L ADNELBPD dayabbr", | |
729 | "day 3 J MVQJPD dayabbr", | |
730 | "day 4 I FNQIPD dayabbr", | |
731 | "day 5 M GEMPD dayabbr", | |
46f4442e | 732 | "helloGEMPD", |
0f5d89e8 | 733 | "hello YXW" |
b75a7d8f | 734 | }; |
73c04bcf | 735 | char formatChars[MAXLEN]; |
b75a7d8f A |
736 | UErrorCode ec = U_ZERO_ERROR; |
737 | UBiDi* bidi = ubidi_open(); | |
73c04bcf | 738 | int i; |
46f4442e A |
739 | |
740 | log_verbose("\nEntering TestReorder\n\n"); | |
741 | ||
b331163b | 742 | for(i=0;i<UPRV_LENGTHOF(logicalOrder);i++){ |
73c04bcf | 743 | int32_t srcSize = (int32_t)strlen(logicalOrder[i]); |
b75a7d8f | 744 | int32_t destSize = srcSize*2; |
73c04bcf A |
745 | UChar src[MAXLEN]; |
746 | UChar dest[MAXLEN]; | |
747 | char chars[MAXLEN]; | |
46f4442e | 748 | log_verbose("Testing L2V #1 for case %d\n", i); |
73c04bcf | 749 | pseudoToU16(srcSize,logicalOrder[i],src); |
b75a7d8f | 750 | ec = U_ZERO_ERROR; |
b75a7d8f A |
751 | ubidi_setPara(bidi,src,srcSize,UBIDI_DEFAULT_LTR ,NULL,&ec); |
752 | if(U_FAILURE(ec)){ | |
753 | log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n", | |
754 | i, UBIDI_DEFAULT_LTR, u_errorName(ec)); | |
755 | } | |
756 | /* try pre-flighting */ | |
757 | destSize = ubidi_writeReordered(bidi,dest,0,UBIDI_DO_MIRRORING,&ec); | |
758 | if(ec!=U_BUFFER_OVERFLOW_ERROR){ | |
759 | log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec)); | |
760 | }else if(destSize!=srcSize){ | |
761 | log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize,destSize); | |
762 | }else{ | |
763 | ec= U_ZERO_ERROR; | |
764 | } | |
765 | destSize=ubidi_writeReordered(bidi,dest,destSize+1,UBIDI_DO_MIRRORING,&ec); | |
73c04bcf | 766 | u16ToPseudo(destSize,dest,chars); |
b75a7d8f A |
767 | if(destSize!=srcSize){ |
768 | log_err("ubidi_writeReordered() destSize and srcSize do not match\n"); | |
73c04bcf A |
769 | }else if(strcmp(visualOrder[i],chars)!=0){ |
770 | log_err("ubidi_writeReordered() did not give expected results for UBIDI_DO_MIRRORING.\n" | |
771 | "Input : %s\nExpected: %s\nGot : %s\nLevels : %s\nAt Index: %d\n", | |
772 | logicalOrder[i],visualOrder[i],chars,formatLevels(bidi, formatChars),i); | |
b75a7d8f | 773 | } |
46f4442e | 774 | checkWhatYouCan(bidi, logicalOrder[i], chars); |
b75a7d8f | 775 | } |
73c04bcf | 776 | |
b331163b | 777 | for(i=0;i<UPRV_LENGTHOF(logicalOrder);i++){ |
73c04bcf | 778 | int32_t srcSize = (int32_t)strlen(logicalOrder[i]); |
b75a7d8f | 779 | int32_t destSize = srcSize*2; |
73c04bcf A |
780 | UChar src[MAXLEN]; |
781 | UChar dest[MAXLEN]; | |
782 | char chars[MAXLEN]; | |
46f4442e | 783 | log_verbose("Testing L2V #2 for case %d\n", i); |
73c04bcf | 784 | pseudoToU16(srcSize,logicalOrder[i],src); |
b75a7d8f | 785 | ec = U_ZERO_ERROR; |
b75a7d8f A |
786 | ubidi_setPara(bidi,src,srcSize,UBIDI_DEFAULT_LTR ,NULL,&ec); |
787 | if(U_FAILURE(ec)){ | |
788 | log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n", | |
789 | i, UBIDI_DEFAULT_LTR, u_errorName(ec)); | |
790 | } | |
791 | /* try pre-flighting */ | |
792 | destSize = ubidi_writeReordered(bidi,dest,0,UBIDI_DO_MIRRORING+UBIDI_OUTPUT_REVERSE,&ec); | |
793 | if(ec!=U_BUFFER_OVERFLOW_ERROR){ | |
794 | log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec)); | |
795 | }else if(destSize!=srcSize){ | |
796 | log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize,destSize); | |
797 | }else{ | |
798 | ec= U_ZERO_ERROR; | |
799 | } | |
800 | destSize=ubidi_writeReordered(bidi,dest,destSize+1,UBIDI_DO_MIRRORING+UBIDI_OUTPUT_REVERSE,&ec); | |
73c04bcf | 801 | u16ToPseudo(destSize,dest,chars); |
b75a7d8f A |
802 | if(destSize!=srcSize){ |
803 | log_err("ubidi_writeReordered() destSize and srcSize do not match\n"); | |
73c04bcf A |
804 | }else if(strcmp(visualOrder1[i],chars)!=0){ |
805 | log_err("ubidi_writeReordered() did not give expected results for UBIDI_DO_MIRRORING+UBIDI_OUTPUT_REVERSE.\n" | |
806 | "Input : %s\nExpected: %s\nGot : %s\nLevels : %s\nAt Index: %d\n", | |
807 | logicalOrder[i],visualOrder1[i],chars,formatLevels(bidi, formatChars),i); | |
b75a7d8f | 808 | } |
b75a7d8f A |
809 | } |
810 | ||
b331163b | 811 | for(i=0;i<UPRV_LENGTHOF(logicalOrder);i++){ |
73c04bcf | 812 | int32_t srcSize = (int32_t)strlen(logicalOrder[i]); |
b75a7d8f | 813 | int32_t destSize = srcSize*2; |
73c04bcf A |
814 | UChar src[MAXLEN]; |
815 | UChar dest[MAXLEN]; | |
816 | char chars[MAXLEN]; | |
46f4442e | 817 | log_verbose("Testing V2L #3 for case %d\n", i); |
73c04bcf | 818 | pseudoToU16(srcSize,logicalOrder[i],src); |
b75a7d8f | 819 | ec = U_ZERO_ERROR; |
b75a7d8f A |
820 | ubidi_setInverse(bidi,TRUE); |
821 | ubidi_setPara(bidi,src,srcSize,UBIDI_DEFAULT_LTR ,NULL,&ec); | |
b75a7d8f A |
822 | if(U_FAILURE(ec)){ |
823 | log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n", | |
824 | i, UBIDI_DEFAULT_LTR, u_errorName(ec)); | |
825 | } | |
826 | /* try pre-flighting */ | |
827 | destSize = ubidi_writeReordered(bidi,dest,0,UBIDI_INSERT_LRM_FOR_NUMERIC+UBIDI_OUTPUT_REVERSE,&ec); | |
828 | if(ec!=U_BUFFER_OVERFLOW_ERROR){ | |
829 | log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec)); | |
830 | }else{ | |
831 | ec= U_ZERO_ERROR; | |
832 | } | |
833 | destSize=ubidi_writeReordered(bidi,dest,destSize+1,UBIDI_INSERT_LRM_FOR_NUMERIC+UBIDI_OUTPUT_REVERSE,&ec); | |
73c04bcf A |
834 | u16ToPseudo(destSize,dest,chars); |
835 | if(strcmp(visualOrder2[i],chars)!=0){ | |
836 | log_err("ubidi_writeReordered() did not give expected results for UBIDI_INSERT_LRM_FOR_NUMERIC+UBIDI_OUTPUT_REVERSE.\n" | |
837 | "Input : %s\nExpected: %s\nGot : %s\nLevels : %s\nAt Index: %d\n", | |
838 | logicalOrder[i],visualOrder2[i],chars,formatLevels(bidi, formatChars),i); | |
b75a7d8f | 839 | } |
b75a7d8f A |
840 | } |
841 | /* Max Explicit level */ | |
b331163b | 842 | for(i=0;i<UPRV_LENGTHOF(logicalOrder);i++){ |
73c04bcf | 843 | int32_t srcSize = (int32_t)strlen(logicalOrder[i]); |
b75a7d8f | 844 | int32_t destSize = srcSize*2; |
73c04bcf A |
845 | UChar src[MAXLEN]; |
846 | UChar dest[MAXLEN]; | |
847 | char chars[MAXLEN]; | |
b75a7d8f | 848 | UBiDiLevel levels[UBIDI_MAX_EXPLICIT_LEVEL]={1,2,3,4,5,6,7,8,9,10}; |
46f4442e | 849 | log_verbose("Testing V2L #4 for case %d\n", i); |
73c04bcf | 850 | pseudoToU16(srcSize,logicalOrder[i],src); |
b75a7d8f | 851 | ec = U_ZERO_ERROR; |
b75a7d8f A |
852 | ubidi_setPara(bidi,src,srcSize,UBIDI_DEFAULT_LTR,levels,&ec); |
853 | if(U_FAILURE(ec)){ | |
854 | log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n", | |
855 | i, UBIDI_MAX_EXPLICIT_LEVEL, u_errorName(ec)); | |
856 | } | |
857 | /* try pre-flighting */ | |
858 | destSize = ubidi_writeReordered(bidi,dest,0,UBIDI_OUTPUT_REVERSE,&ec); | |
859 | if(ec!=U_BUFFER_OVERFLOW_ERROR){ | |
860 | log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec)); | |
861 | }else if(destSize!=srcSize){ | |
862 | log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize,destSize); | |
863 | }else{ | |
73c04bcf | 864 | ec = U_ZERO_ERROR; |
b75a7d8f A |
865 | } |
866 | destSize=ubidi_writeReordered(bidi,dest,destSize+1,UBIDI_OUTPUT_REVERSE,&ec); | |
73c04bcf | 867 | u16ToPseudo(destSize,dest,chars); |
b75a7d8f A |
868 | if(destSize!=srcSize){ |
869 | log_err("ubidi_writeReordered() destSize and srcSize do not match. Dest Size = %d Source Size = %d\n",destSize,srcSize ); | |
73c04bcf A |
870 | }else if(strcmp(visualOrder3[i],chars)!=0){ |
871 | log_err("ubidi_writeReordered() did not give expected results for UBIDI_OUTPUT_REVERSE.\n" | |
872 | "Input : %s\nExpected: %s\nGot : %s\nLevels : %s\nAt Index: %d\n", | |
873 | logicalOrder[i],visualOrder3[i],chars,formatLevels(bidi, formatChars),i); | |
b75a7d8f | 874 | } |
b75a7d8f | 875 | } |
b331163b | 876 | for(i=0;i<UPRV_LENGTHOF(logicalOrder);i++){ |
73c04bcf | 877 | int32_t srcSize = (int32_t)strlen(logicalOrder[i]); |
b75a7d8f | 878 | int32_t destSize = srcSize*2; |
73c04bcf A |
879 | UChar src[MAXLEN]; |
880 | UChar dest[MAXLEN]; | |
881 | char chars[MAXLEN]; | |
b75a7d8f | 882 | UBiDiLevel levels[UBIDI_MAX_EXPLICIT_LEVEL]={1,2,3,4,5,6,7,8,9,10}; |
46f4442e | 883 | log_verbose("Testing V2L #5 for case %d\n", i); |
73c04bcf | 884 | pseudoToU16(srcSize,logicalOrder[i],src); |
b75a7d8f | 885 | ec = U_ZERO_ERROR; |
b75a7d8f A |
886 | ubidi_setPara(bidi,src,srcSize,UBIDI_DEFAULT_LTR,levels,&ec); |
887 | if(U_FAILURE(ec)){ | |
888 | log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n", | |
889 | i, UBIDI_MAX_EXPLICIT_LEVEL, u_errorName(ec)); | |
890 | } | |
b75a7d8f A |
891 | /* try pre-flighting */ |
892 | destSize = ubidi_writeReordered(bidi,dest,0,UBIDI_DO_MIRRORING+UBIDI_REMOVE_BIDI_CONTROLS,&ec); | |
893 | if(ec!=U_BUFFER_OVERFLOW_ERROR){ | |
894 | log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec)); | |
b75a7d8f A |
895 | }else{ |
896 | ec= U_ZERO_ERROR; | |
897 | } | |
898 | destSize=ubidi_writeReordered(bidi,dest,destSize+1,UBIDI_DO_MIRRORING+UBIDI_REMOVE_BIDI_CONTROLS,&ec); | |
73c04bcf A |
899 | u16ToPseudo(destSize,dest,chars); |
900 | if(strcmp(visualOrder4[i],chars)!=0){ | |
901 | log_err("ubidi_writeReordered() did not give expected results for UBIDI_DO_MIRRORING+UBIDI_REMOVE_BIDI_CONTROLS.\n" | |
902 | "Input : %s\nExpected: %s\nGot : %s\nLevels : %s\nAt Index: %d\n", | |
903 | logicalOrder[i],visualOrder4[i],chars,formatLevels(bidi, formatChars),i); | |
b75a7d8f | 904 | } |
b75a7d8f A |
905 | } |
906 | ubidi_close(bidi); | |
46f4442e A |
907 | |
908 | log_verbose("\nExiting TestReorder\n\n"); | |
b75a7d8f A |
909 | } |
910 | ||
51004dcb A |
911 | static void |
912 | testReorderArabicMathSymbols(void) { | |
913 | static const UChar logicalOrder[][MAXLEN]={ | |
914 | /* Arabic mathematical Symbols 0x1EE00 - 0x1EE1B */ | |
57a6839d A |
915 | {0xD83B, 0xDE00, 0xD83B, 0xDE01, 0xD83B, 0xDE02, 0xD83B, 0xDE03, 0x20, |
916 | 0xD83B, 0xDE24, 0xD83B, 0xDE05, 0xD83B, 0xDE06, 0x20, | |
917 | 0xD83B, 0xDE07, 0xD83B, 0xDE08, 0xD83B, 0xDE09, 0x20, | |
918 | 0xD83B, 0xDE0A, 0xD83B, 0xDE0B, 0xD83B, 0xDE0C, 0xD83B, 0xDE0D, 0x20, | |
919 | 0xD83B, 0xDE0E, 0xD83B, 0xDE0F, 0xD83B, 0xDE10, 0xD83B, 0xDE11, 0x20, | |
920 | 0xD83B, 0xDE12, 0xD83B, 0xDE13, 0xD83B, 0xDE14, 0xD83B, 0xDE15, 0x20, | |
921 | 0xD83B, 0xDE16, 0xD83B, 0xDE17, 0xD83B, 0xDE18, 0x20, | |
51004dcb A |
922 | 0xD83B, 0xDE19, 0xD83B, 0xDE1A, 0xD83B, 0xDE1B}, |
923 | /* Arabic mathematical Symbols - Looped Symbols, 0x1EE80 - 0x1EE9B */ | |
57a6839d A |
924 | {0xD83B, 0xDE80, 0xD83B, 0xDE81, 0xD83B, 0xDE82, 0xD83B, 0xDE83, 0x20, |
925 | 0xD83B, 0xDE84, 0xD83B, 0xDE85, 0xD83B, 0xDE86, 0x20, | |
926 | 0xD83B, 0xDE87, 0xD83B, 0xDE88, 0xD83B, 0xDE89, 0x20, | |
927 | 0xD83B, 0xDE8B, 0xD83B, 0xDE8C, 0xD83B, 0xDE8D, 0x20, | |
928 | 0xD83B, 0xDE8E, 0xD83B, 0xDE8F, 0xD83B, 0xDE90, 0xD83B, 0xDE91, 0x20, | |
929 | 0xD83B, 0xDE92, 0xD83B, 0xDE93, 0xD83B, 0xDE94, 0xD83B, 0xDE95, 0x20, | |
930 | 0xD83B, 0xDE96, 0xD83B, 0xDE97, 0xD83B, 0xDE98, 0x20, | |
51004dcb A |
931 | 0xD83B, 0xDE99, 0xD83B, 0xDE9A, 0xD83B, 0xDE9B}, |
932 | /* Arabic mathematical Symbols - Double-struck Symbols, 0x1EEA1 - 0x1EEBB */ | |
57a6839d A |
933 | {0xD83B, 0xDEA1, 0xD83B, 0xDEA2, 0xD83B, 0xDEA3, 0x20, |
934 | 0xD83B, 0xDEA5, 0xD83B, 0xDEA6, 0x20, | |
935 | 0xD83B, 0xDEA7, 0xD83B, 0xDEA8, 0xD83B, 0xDEA9, 0x20, | |
936 | 0xD83B, 0xDEAB, 0xD83B, 0xDEAC, 0xD83B, 0xDEAD, 0x20, | |
937 | 0xD83B, 0xDEAE, 0xD83B, 0xDEAF, 0xD83B, 0xDEB0, 0xD83B, 0xDEB1, 0x20, | |
938 | 0xD83B, 0xDEB2, 0xD83B, 0xDEB3, 0xD83B, 0xDEB4, 0xD83B, 0xDEB5, 0x20, | |
939 | 0xD83B, 0xDEB6, 0xD83B, 0xDEB7, 0xD83B, 0xDEB8, 0x20, | |
51004dcb A |
940 | 0xD83B, 0xDEB9, 0xD83B, 0xDEBA, 0xD83B, 0xDEBB}, |
941 | /* Arabic mathematical Symbols - Initial Symbols, 0x1EE21 - 0x1EE3B */ | |
57a6839d A |
942 | {0xD83B, 0xDE21, 0xD83B, 0xDE22, 0x20, |
943 | 0xD83B, 0xDE27, 0xD83B, 0xDE29, 0x20, | |
944 | 0xD83B, 0xDE2A, 0xD83B, 0xDE2B, 0xD83B, 0xDE2C, 0xD83B, 0xDE2D, 0x20, | |
945 | 0xD83B, 0xDE2E, 0xD83B, 0xDE2F, 0xD83B, 0xDE30, 0xD83B, 0xDE31, 0x20, | |
946 | 0xD83B, 0xDE32, 0xD83B, 0xDE34, 0xD83B, 0xDE35, 0x20, | |
947 | 0xD83B, 0xDE36, 0xD83B, 0xDE37, 0x20, | |
51004dcb A |
948 | 0xD83B, 0xDE39, 0xD83B, 0xDE3B}, |
949 | /* Arabic mathematical Symbols - Tailed Symbols */ | |
57a6839d A |
950 | {0xD83B, 0xDE42, 0xD83B, 0xDE47, 0xD83B, 0xDE49, 0xD83B, 0xDE4B, 0x20, |
951 | 0xD83B, 0xDE4D, 0xD83B, 0xDE4E, 0xD83B, 0xDE4F, 0x20, | |
952 | 0xD83B, 0xDE51, 0xD83B, 0xDE52, 0xD83B, 0xDE54, 0xD83B, 0xDE57, 0x20, | |
51004dcb A |
953 | 0xD83B, 0xDE59, 0xD83B, 0xDE5B, 0xD83B, 0xDE5D, 0xD83B, 0xDE5F} |
954 | }; | |
955 | static const UChar visualOrder[][MAXLEN]={ | |
956 | /* Arabic mathematical Symbols 0x1EE00 - 0x1EE1B */ | |
57a6839d A |
957 | {0xD83B, 0xDE1B, 0xD83B, 0xDE1A, 0xD83B, 0xDE19, 0x20, |
958 | 0xD83B, 0xDE18, 0xD83B, 0xDE17, 0xD83B, 0xDE16, 0x20, | |
51004dcb A |
959 | 0xD83B, 0xDE15, 0xD83B, 0xDE14, 0xD83B, 0xDE13, 0xD83B, 0xDE12, 0x20, |
960 | 0xD83B, 0xDE11, 0xD83B, 0xDE10, 0xD83B, 0xDE0F, 0xD83B, 0xDE0E, 0x20, | |
961 | 0xD83B, 0xDE0D, 0xD83B, 0xDE0C, 0xD83B, 0xDE0B, 0xD83B, 0xDE0A, 0x20, | |
57a6839d A |
962 | 0xD83B, 0xDE09, 0xD83B, 0xDE08, 0xD83B, 0xDE07, 0x20, |
963 | 0xD83B, 0xDE06, 0xD83B, 0xDE05, 0xD83B, 0xDE24, 0x20, | |
51004dcb A |
964 | 0xD83B, 0xDE03, 0xD83B, 0xDE02, 0xD83B, 0xDE01, 0xD83B, 0xDE00}, |
965 | /* Arabic mathematical Symbols - Looped Symbols, 0x1EE80 - 0x1EE9B */ | |
57a6839d A |
966 | {0xD83B, 0xDE9B, 0xD83B, 0xDE9A, 0xD83B, 0xDE99, 0x20, |
967 | 0xD83B, 0xDE98, 0xD83B, 0xDE97, 0xD83B, 0xDE96, 0x20, | |
51004dcb A |
968 | 0xD83B, 0xDE95, 0xD83B, 0xDE94, 0xD83B, 0xDE93, 0xD83B, 0xDE92, 0x20, |
969 | 0xD83B, 0xDE91, 0xD83B, 0xDE90, 0xD83B, 0xDE8F, 0xD83B, 0xDE8E, 0x20, | |
57a6839d A |
970 | 0xD83B, 0xDE8D, 0xD83B, 0xDE8C, 0xD83B, 0xDE8B, 0x20, |
971 | 0xD83B, 0xDE89, 0xD83B, 0xDE88, 0xD83B, 0xDE87, 0x20, | |
972 | 0xD83B, 0xDE86, 0xD83B, 0xDE85, 0xD83B, 0xDE84, 0x20, | |
51004dcb A |
973 | 0xD83B, 0xDE83, 0xD83B, 0xDE82, 0xD83B, 0xDE81, 0xD83B, 0xDE80}, |
974 | /* Arabic mathematical Symbols - Double-struck Symbols, 0x1EEA1 - 0x1EEBB */ | |
57a6839d A |
975 | {0xD83B, 0xDEBB, 0xD83B, 0xDEBA, 0xD83B, 0xDEB9, 0x20, |
976 | 0xD83B, 0xDEB8, 0xD83B, 0xDEB7, 0xD83B, 0xDEB6, 0x20, | |
51004dcb A |
977 | 0xD83B, 0xDEB5, 0xD83B, 0xDEB4, 0xD83B, 0xDEB3, 0xD83B, 0xDEB2, 0x20, |
978 | 0xD83B, 0xDEB1, 0xD83B, 0xDEB0, 0xD83B, 0xDEAF, 0xD83B, 0xDEAE, 0x20, | |
57a6839d A |
979 | 0xD83B, 0xDEAD, 0xD83B, 0xDEAC, 0xD83B, 0xDEAB, 0x20, |
980 | 0xD83B, 0xDEA9, 0xD83B, 0xDEA8, 0xD83B, 0xDEA7, 0x20, | |
981 | 0xD83B, 0xDEA6, 0xD83B, 0xDEA5, 0x20, | |
51004dcb A |
982 | 0xD83B, 0xDEA3, 0xD83B, 0xDEA2, 0xD83B, 0xDEA1}, |
983 | /* Arabic mathematical Symbols - Initial Symbols, 0x1EE21 - 0x1EE3B */ | |
57a6839d A |
984 | {0xD83B, 0xDE3B, 0xD83B, 0xDE39, 0x20, |
985 | 0xD83B, 0xDE37, 0xD83B, 0xDE36, 0x20, | |
986 | 0xD83B, 0xDE35, 0xD83B, 0xDE34, 0xD83B, 0xDE32, 0x20, | |
51004dcb A |
987 | 0xD83B, 0xDE31, 0xD83B, 0xDE30, 0xD83B, 0xDE2F, 0xD83B, 0xDE2E, 0x20, |
988 | 0xD83B, 0xDE2D, 0xD83B, 0xDE2C, 0xD83B, 0xDE2B, 0xD83B, 0xDE2A, 0x20, | |
57a6839d | 989 | 0xD83B, 0xDE29, 0xD83B, 0xDE27, 0x20, |
51004dcb A |
990 | 0xD83B, 0xDE22, 0xD83B, 0xDE21}, |
991 | /* Arabic mathematical Symbols - Tailed Symbols */ | |
992 | {0xD83B, 0xDE5F, 0xD83B, 0xDE5D, 0xD83B, 0xDE5B, 0xD83B, 0xDE59, 0x20, | |
993 | 0xD83B, 0xDE57, 0xD83B, 0xDE54, 0xD83B, 0xDE52, 0xD83B, 0xDE51, 0x20, | |
57a6839d | 994 | 0xD83B, 0xDE4F, 0xD83B, 0xDE4E, 0xD83B, 0xDE4D, 0x20, |
51004dcb A |
995 | 0xD83B, 0xDE4B, 0xD83B, 0xDE49, 0xD83B, 0xDE47, 0xD83B, 0xDE42} |
996 | }; | |
997 | char formatChars[MAXLEN]; | |
998 | UErrorCode ec = U_ZERO_ERROR; | |
999 | UBiDi* bidi = ubidi_open(); | |
1000 | int i; | |
1001 | ||
1002 | log_verbose("\nEntering TestReorderArabicMathSymbols\n\n"); | |
1003 | ||
b331163b | 1004 | for(i=0;i<UPRV_LENGTHOF(logicalOrder);i++){ |
51004dcb A |
1005 | int32_t srcSize = u_strlen(logicalOrder[i]); |
1006 | int32_t destSize = srcSize*2; | |
1007 | UChar dest[MAXLEN]; | |
1008 | log_verbose("Testing L2V #1 for case %d\n", i); | |
1009 | ec = U_ZERO_ERROR; | |
1010 | ubidi_setPara(bidi,logicalOrder[i],srcSize,UBIDI_DEFAULT_LTR ,NULL,&ec); | |
1011 | if(U_FAILURE(ec)){ | |
1012 | log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n", | |
1013 | i, UBIDI_DEFAULT_LTR, u_errorName(ec)); | |
1014 | } | |
1015 | /* try pre-flighting */ | |
1016 | destSize = ubidi_writeReordered(bidi,dest,0,UBIDI_DO_MIRRORING,&ec); | |
1017 | if(ec!=U_BUFFER_OVERFLOW_ERROR){ | |
1018 | log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec)); | |
1019 | }else if(destSize!=srcSize){ | |
1020 | log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize,destSize); | |
1021 | }else{ | |
1022 | ec= U_ZERO_ERROR; | |
1023 | } | |
1024 | destSize=ubidi_writeReordered(bidi,dest,destSize+1,UBIDI_DO_MIRRORING,&ec); | |
1025 | if(destSize!=srcSize){ | |
1026 | log_err("ubidi_writeReordered() destSize and srcSize do not match\n"); | |
1027 | }else if(memcmp(dest, visualOrder[i], destSize*U_SIZEOF_UCHAR)!=0){ | |
1028 | log_err("ubidi_writeReordered() did not give expected results for UBIDI_DO_MIRRORING.\n" | |
1029 | "Input : %s\nExpected: %s\nGot : %s\nLevels : %s\nAt Index: %d\n", | |
1030 | logicalOrder[i],visualOrder[i],dest,formatLevels(bidi, formatChars),i); | |
1031 | } | |
1032 | } | |
1033 | ||
1034 | ubidi_close(bidi); | |
1035 | ||
1036 | log_verbose("\nExiting TestReorderArabicMathSymbols\n\n"); | |
1037 | } | |
1038 | ||
b75a7d8f | 1039 | static void |
46f4442e | 1040 | doTest(UBiDi *pBiDi, int testNumber, const BiDiTestData *test, int32_t lineStart, UBool countRunsFirst) { |
b75a7d8f A |
1041 | const uint8_t *dirProps=test->text+lineStart; |
1042 | const UBiDiLevel *levels=test->levels; | |
1043 | const uint8_t *visualMap=test->visualMap; | |
374ca955 | 1044 | int32_t i, len=ubidi_getLength(pBiDi), logicalIndex, runCount = 0; |
b75a7d8f A |
1045 | UErrorCode errorCode=U_ZERO_ERROR; |
1046 | UBiDiLevel level, level2; | |
1047 | ||
374ca955 A |
1048 | if (countRunsFirst) { |
1049 | log_verbose("Calling ubidi_countRuns() first.\n"); | |
1050 | ||
1051 | runCount = ubidi_countRuns(pBiDi, &errorCode); | |
1052 | ||
1053 | if(U_FAILURE(errorCode)) { | |
1054 | log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber, myErrorName(errorCode)); | |
1055 | return; | |
1056 | } | |
1057 | } else { | |
1058 | log_verbose("Calling ubidi_getLogicalMap() first.\n"); | |
1059 | } | |
1060 | ||
46f4442e | 1061 | _testReordering(pBiDi, testNumber); |
b75a7d8f A |
1062 | |
1063 | for(i=0; i<len; ++i) { | |
1064 | log_verbose("%3d %3d %.*s%-3s @%d\n", | |
1065 | i, ubidi_getLevelAt(pBiDi, i), ubidi_getLevelAt(pBiDi, i), levelString, | |
1066 | dirPropNames[dirProps[i]], | |
1067 | ubidi_getVisualIndex(pBiDi, i, &errorCode)); | |
1068 | } | |
1069 | ||
1070 | log_verbose("\n-----levels:"); | |
1071 | for(i=0; i<len; ++i) { | |
1072 | if(i>0) { | |
1073 | log_verbose(","); | |
1074 | } | |
1075 | log_verbose(" %d", ubidi_getLevelAt(pBiDi, i)); | |
1076 | } | |
1077 | ||
1078 | log_verbose("\n--reordered:"); | |
1079 | for(i=0; i<len; ++i) { | |
1080 | if(i>0) { | |
1081 | log_verbose(","); | |
1082 | } | |
1083 | log_verbose(" %d", ubidi_getVisualIndex(pBiDi, i, &errorCode)); | |
1084 | } | |
1085 | log_verbose("\n"); | |
1086 | ||
1087 | if(test->direction!=ubidi_getDirection(pBiDi)) { | |
1088 | log_err("ubidi_getDirection(tests[%d]): wrong direction %d\n", testNumber, ubidi_getDirection(pBiDi)); | |
1089 | } | |
1090 | ||
1091 | if(test->resultLevel!=ubidi_getParaLevel(pBiDi)) { | |
1092 | log_err("ubidi_getParaLevel(tests[%d]): wrong paragraph level %d\n", testNumber, ubidi_getParaLevel(pBiDi)); | |
1093 | } | |
1094 | ||
1095 | for(i=0; i<len; ++i) { | |
1096 | if(levels[i]!=ubidi_getLevelAt(pBiDi, i)) { | |
73c04bcf | 1097 | log_err("ubidi_getLevelAt(tests[%d], %d): wrong level %d, expected %d\n", testNumber, i, ubidi_getLevelAt(pBiDi, i), levels[i]); |
b75a7d8f A |
1098 | return; |
1099 | } | |
1100 | } | |
1101 | ||
1102 | for(i=0; i<len; ++i) { | |
1103 | logicalIndex=ubidi_getVisualIndex(pBiDi, i, &errorCode); | |
1104 | if(U_FAILURE(errorCode)) { | |
1105 | log_err("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber, i, myErrorName(errorCode)); | |
1106 | return; | |
1107 | } | |
1108 | if(visualMap[i]!=logicalIndex) { | |
1109 | log_err("ubidi_getVisualIndex(tests[%d], %d): wrong index %d\n", testNumber, i, logicalIndex); | |
1110 | return; | |
1111 | } | |
1112 | } | |
1113 | ||
374ca955 A |
1114 | if (! countRunsFirst) { |
1115 | runCount=ubidi_countRuns(pBiDi, &errorCode); | |
1116 | if(U_FAILURE(errorCode)) { | |
1117 | log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber, myErrorName(errorCode)); | |
1118 | return; | |
1119 | } | |
b75a7d8f A |
1120 | } |
1121 | ||
1122 | for(logicalIndex=0; logicalIndex<len;) { | |
1123 | level=ubidi_getLevelAt(pBiDi, logicalIndex); | |
1124 | ubidi_getLogicalRun(pBiDi, logicalIndex, &logicalIndex, &level2); | |
1125 | if(level!=level2) { | |
46f4442e A |
1126 | log_err("ubidi_getLogicalRun(tests[%d], run ending at index %d): " |
1127 | "wrong level %d instead of %d\n", | |
1128 | testNumber, logicalIndex, level, level2); | |
b75a7d8f A |
1129 | } |
1130 | if(--runCount<0) { | |
46f4442e A |
1131 | log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs " |
1132 | "compared to %d=ubidi_countRuns()\n", | |
1133 | testNumber, ubidi_countRuns(pBiDi, &errorCode)); | |
b75a7d8f A |
1134 | return; |
1135 | } | |
1136 | } | |
1137 | if(runCount!=0) { | |
46f4442e A |
1138 | log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs " |
1139 | "compared to %d=ubidi_getRunCount()\n", | |
1140 | testNumber, ubidi_countRuns(pBiDi, &errorCode)); | |
b75a7d8f A |
1141 | return; |
1142 | } | |
1143 | ||
1144 | log_verbose("\n\n"); | |
1145 | } | |
1146 | ||
1147 | static void | |
46f4442e | 1148 | _testReordering(UBiDi *pBiDi, int testNumber) { |
b75a7d8f | 1149 | int32_t |
73c04bcf A |
1150 | logicalMap1[MAXLEN], logicalMap2[MAXLEN], logicalMap3[MAXLEN], |
1151 | visualMap1[MAXLEN], visualMap2[MAXLEN], visualMap3[MAXLEN], visualMap4[MAXLEN]; | |
b75a7d8f | 1152 | UErrorCode errorCode=U_ZERO_ERROR; |
73c04bcf A |
1153 | const UBiDiLevel *levels; |
1154 | int32_t i, length=ubidi_getLength(pBiDi), | |
1155 | destLength=ubidi_getResultLength(pBiDi); | |
b75a7d8f A |
1156 | int32_t runCount, visualIndex, logicalStart, runLength; |
1157 | UBool odd; | |
1158 | ||
1159 | if(length<=0) { | |
1160 | return; | |
1161 | } | |
1162 | ||
1163 | /* get the logical and visual maps from the object */ | |
1164 | ubidi_getLogicalMap(pBiDi, logicalMap1, &errorCode); | |
1165 | if(U_FAILURE(errorCode)) { | |
1166 | log_err("ubidi_getLogicalMap(tests[%d]): error %s\n", testNumber, myErrorName(errorCode)); | |
1167 | return; | |
1168 | } | |
1169 | ||
1170 | ubidi_getVisualMap(pBiDi, visualMap1, &errorCode); | |
b75a7d8f A |
1171 | if(U_FAILURE(errorCode)) { |
1172 | log_err("ubidi_getVisualMap(tests[%d]): error %s\n", testNumber, myErrorName(errorCode)); | |
1173 | return; | |
1174 | } | |
1175 | ||
1176 | /* invert them both */ | |
1177 | ubidi_invertMap(logicalMap1, visualMap2, length); | |
73c04bcf | 1178 | ubidi_invertMap(visualMap1, logicalMap2, destLength); |
b75a7d8f A |
1179 | |
1180 | /* get them from the levels array, too */ | |
73c04bcf | 1181 | levels=ubidi_getLevels(pBiDi, &errorCode); |
b75a7d8f A |
1182 | |
1183 | if(U_FAILURE(errorCode)) { | |
1184 | log_err("ubidi_getLevels(tests[%d]): error %s\n", testNumber, myErrorName(errorCode)); | |
1185 | return; | |
1186 | } | |
1187 | ||
1188 | ubidi_reorderLogical(levels, length, logicalMap3); | |
1189 | ubidi_reorderVisual(levels, length, visualMap3); | |
1190 | ||
1191 | /* get the visual map from the runs, too */ | |
1192 | runCount=ubidi_countRuns(pBiDi, &errorCode); | |
1193 | if(U_FAILURE(errorCode)) { | |
1194 | log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber, myErrorName(errorCode)); | |
1195 | return; | |
1196 | } | |
b75a7d8f | 1197 | log_verbose("\n----%2d runs:", runCount); |
b75a7d8f A |
1198 | visualIndex=0; |
1199 | for(i=0; i<runCount; ++i) { | |
73c04bcf A |
1200 | odd=(UBool)ubidi_getVisualRun(pBiDi, i, &logicalStart, &runLength); |
1201 | log_verbose(" (%c @%d[%d])", odd ? 'R' : 'L', logicalStart, runLength); | |
1202 | if(UBIDI_LTR==odd) { | |
b75a7d8f A |
1203 | do { /* LTR */ |
1204 | visualMap4[visualIndex++]=logicalStart++; | |
1205 | } while(--runLength>0); | |
1206 | } else { | |
1207 | logicalStart+=runLength; /* logicalLimit */ | |
1208 | do { /* RTL */ | |
1209 | visualMap4[visualIndex++]=--logicalStart; | |
1210 | } while(--runLength>0); | |
1211 | } | |
1212 | } | |
73c04bcf | 1213 | log_verbose("\n"); |
b75a7d8f A |
1214 | |
1215 | /* print all the maps */ | |
1216 | log_verbose("logical maps:\n"); | |
1217 | for(i=0; i<length; ++i) { | |
1218 | log_verbose("%4d", logicalMap1[i]); | |
1219 | } | |
1220 | log_verbose("\n"); | |
1221 | for(i=0; i<length; ++i) { | |
1222 | log_verbose("%4d", logicalMap2[i]); | |
1223 | } | |
1224 | log_verbose("\n"); | |
1225 | for(i=0; i<length; ++i) { | |
1226 | log_verbose("%4d", logicalMap3[i]); | |
1227 | } | |
1228 | ||
1229 | log_verbose("\nvisual maps:\n"); | |
73c04bcf | 1230 | for(i=0; i<destLength; ++i) { |
b75a7d8f A |
1231 | log_verbose("%4d", visualMap1[i]); |
1232 | } | |
1233 | log_verbose("\n"); | |
73c04bcf | 1234 | for(i=0; i<destLength; ++i) { |
b75a7d8f A |
1235 | log_verbose("%4d", visualMap2[i]); |
1236 | } | |
1237 | log_verbose("\n"); | |
1238 | for(i=0; i<length; ++i) { | |
1239 | log_verbose("%4d", visualMap3[i]); | |
1240 | } | |
1241 | log_verbose("\n"); | |
1242 | for(i=0; i<length; ++i) { | |
1243 | log_verbose("%4d", visualMap4[i]); | |
1244 | } | |
1245 | log_verbose("\n"); | |
1246 | ||
1247 | /* check that the indexes are the same between these and ubidi_getLogical/VisualIndex() */ | |
1248 | for(i=0; i<length; ++i) { | |
1249 | if(logicalMap1[i]!=logicalMap2[i]) { | |
73c04bcf | 1250 | log_err("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap2[i] at i=%d\n", testNumber, i); |
b75a7d8f A |
1251 | break; |
1252 | } | |
1253 | if(logicalMap1[i]!=logicalMap3[i]) { | |
73c04bcf | 1254 | log_err("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap3[i] at i=%d\n", testNumber, i); |
b75a7d8f A |
1255 | break; |
1256 | } | |
1257 | ||
1258 | if(visualMap1[i]!=visualMap2[i]) { | |
73c04bcf | 1259 | log_err("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap2[i] at i=%d\n", testNumber, i); |
b75a7d8f A |
1260 | break; |
1261 | } | |
1262 | if(visualMap1[i]!=visualMap3[i]) { | |
73c04bcf | 1263 | log_err("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap3[i] at i=%d\n", testNumber, i); |
b75a7d8f A |
1264 | break; |
1265 | } | |
1266 | if(visualMap1[i]!=visualMap4[i]) { | |
73c04bcf | 1267 | log_err("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap4[i] at i=%d\n", testNumber, i); |
b75a7d8f A |
1268 | break; |
1269 | } | |
1270 | ||
1271 | if(logicalMap1[i]!=ubidi_getVisualIndex(pBiDi, i, &errorCode)) { | |
73c04bcf | 1272 | log_err("bidi reordering error in tests[%d]: logicalMap1[i]!=ubidi_getVisualIndex(i) at i=%d\n", testNumber, i); |
b75a7d8f A |
1273 | break; |
1274 | } | |
1275 | if(U_FAILURE(errorCode)) { | |
73c04bcf | 1276 | log_err("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber, i, myErrorName(errorCode)); |
b75a7d8f A |
1277 | break; |
1278 | } | |
1279 | if(visualMap1[i]!=ubidi_getLogicalIndex(pBiDi, i, &errorCode)) { | |
73c04bcf | 1280 | log_err("bidi reordering error in tests[%d]: visualMap1[i]!=ubidi_getLogicalIndex(i) at i=%d\n", testNumber, i); |
b75a7d8f A |
1281 | break; |
1282 | } | |
1283 | if(U_FAILURE(errorCode)) { | |
73c04bcf | 1284 | log_err("ubidi_getLogicalIndex(tests[%d], %d): error %s\n", testNumber, i, myErrorName(errorCode)); |
b75a7d8f A |
1285 | break; |
1286 | } | |
1287 | } | |
1288 | } | |
1289 | ||
340931cb | 1290 | #define RETURN_IF_BAD_ERRCODE(x) UPRV_BLOCK_MACRO_BEGIN { \ |
46f4442e A |
1291 | if (U_FAILURE(errorCode)) { \ |
1292 | log_err("\nbad errorCode %d at %s\n", errorCode, (x)); \ | |
1293 | return; \ | |
1294 | } \ | |
340931cb | 1295 | } UPRV_BLOCK_MACRO_END |
46f4442e | 1296 | |
b331163b | 1297 | #define STRING_TEST_CASE(s) { (s), UPRV_LENGTHOF(s) } |
729e4ab9 A |
1298 | |
1299 | static void testGetBaseDirection(void) { | |
1300 | UBiDiDirection dir; | |
1301 | int i; | |
1302 | ||
1303 | /* Test Data */ | |
1304 | static const UChar | |
1305 | /*Mixed Start with L*/ | |
1306 | stringMixedEnglishFirst[]={ 0x61, 0x627, 0x32, 0x6f3, 0x61, 0x34, 0 }, | |
1307 | /*Mixed Start with AL*/ | |
1308 | stringMixedArabicFirst[]={ 0x661, 0x627, 0x662, 0x6f3, 0x61, 0x664, 0 }, | |
1309 | /*Mixed Start with R*/ | |
1310 | stringMixedHebrewFirst[]={ 0x05EA, 0x627, 0x662, 0x6f3, 0x61, 0x664, 0 }, | |
1311 | /*All AL (Arabic. Persian)*/ | |
1312 | stringPersian[]={0x0698, 0x067E, 0x0686, 0x06AF, 0}, | |
1313 | /*All R (Hebrew etc.)*/ | |
1314 | stringHebrew[]={0x0590, 0x05D5, 0x05EA, 0x05F1, 0}, | |
1315 | /*All L (English)*/ | |
1316 | stringEnglish[]={0x71, 0x61, 0x66, 0}, | |
1317 | /*Mixed Start with weak AL an then L*/ | |
1318 | stringStartWeakAL[]={ 0x0663, 0x71, 0x61, 0x66, 0}, | |
1319 | /*Mixed Start with weak L and then AL*/ | |
1320 | stringStartWeakL[]={0x31, 0x0698, 0x067E, 0x0686, 0x06AF, 0}, | |
1321 | /*Empty*/ | |
1322 | stringEmpty[]={0}, | |
1323 | /*Surrogate Char.*/ | |
1324 | stringSurrogateChar[]={0xD800, 0xDC00, 0}, | |
1325 | /*Invalid UChar*/ | |
1326 | stringInvalidUchar[]={-1}, | |
1327 | /*All weak L (English Digits)*/ | |
1328 | stringAllEnglishDigits[]={0x31, 0x32, 0x33, 0}, | |
1329 | /*All weak AL (Arabic Digits)*/ | |
1330 | stringAllArabicDigits[]={0x0663, 0x0664, 0x0665, 0}, | |
1331 | /*First L (English) others are R (Hebrew etc.) */ | |
1332 | stringFirstL[] = {0x71, 0x0590, 0x05D5, 0x05EA, 0x05F1, 0}, | |
1333 | /*Last R (Hebrew etc.) others are weak L (English Digits)*/ | |
1334 | stringLastR[] = {0x31, 0x32, 0x33, 0x05F1, 0}; | |
1335 | ||
1336 | static const struct { | |
1337 | const UChar *s; | |
1338 | int32_t length; | |
1339 | } testCases[]={ | |
1340 | STRING_TEST_CASE(stringMixedEnglishFirst), | |
1341 | STRING_TEST_CASE(stringMixedArabicFirst), | |
1342 | STRING_TEST_CASE(stringMixedHebrewFirst), | |
1343 | STRING_TEST_CASE(stringPersian), | |
1344 | STRING_TEST_CASE(stringHebrew), | |
1345 | STRING_TEST_CASE(stringEnglish), | |
1346 | STRING_TEST_CASE(stringStartWeakAL), | |
1347 | STRING_TEST_CASE(stringStartWeakL), | |
1348 | STRING_TEST_CASE(stringEmpty), | |
1349 | STRING_TEST_CASE(stringSurrogateChar), | |
1350 | STRING_TEST_CASE(stringInvalidUchar), | |
1351 | STRING_TEST_CASE(stringAllEnglishDigits), | |
1352 | STRING_TEST_CASE(stringAllArabicDigits), | |
1353 | STRING_TEST_CASE(stringFirstL), | |
1354 | STRING_TEST_CASE(stringLastR), | |
1355 | }; | |
1356 | ||
1357 | /* Expected results */ | |
1358 | static const UBiDiDirection expectedDir[] ={ | |
1359 | UBIDI_LTR, UBIDI_RTL, UBIDI_RTL, | |
1360 | UBIDI_RTL, UBIDI_RTL, UBIDI_LTR, | |
1361 | UBIDI_LTR, UBIDI_RTL, UBIDI_NEUTRAL, | |
1362 | UBIDI_LTR, UBIDI_NEUTRAL, UBIDI_NEUTRAL, | |
1363 | UBIDI_NEUTRAL, UBIDI_LTR, UBIDI_RTL | |
1364 | }; | |
1365 | ||
1366 | log_verbose("testGetBaseDirection() with %u test cases ---\n", | |
b331163b | 1367 | UPRV_LENGTHOF(testCases)); |
729e4ab9 | 1368 | /* Run Tests */ |
b331163b | 1369 | for(i=0; i<UPRV_LENGTHOF(testCases); ++i) { |
729e4ab9 A |
1370 | dir = ubidi_getBaseDirection(testCases[i].s, testCases[i].length ); |
1371 | log_verbose("Testing case %d\tReceived dir %d\n", i, dir); | |
4388f060 A |
1372 | if (dir != expectedDir[i]) |
1373 | log_err("\nFailed getBaseDirection case %d Expected %d \tReceived %d\n", | |
729e4ab9 A |
1374 | i, expectedDir[i], dir); |
1375 | } | |
1376 | ||
1377 | /* Misc. tests */ | |
1378 | /* NULL string */ | |
1379 | dir = ubidi_getBaseDirection(NULL, 3); | |
1380 | if (dir != UBIDI_NEUTRAL ) | |
1381 | log_err("\nFailed getBaseDirection for NULL string " , | |
1382 | "\nExpected %d \nReceived %d", UBIDI_NEUTRAL, dir); | |
1383 | /*All L- English string and length=-3 */ | |
1384 | dir = ubidi_getBaseDirection( stringEnglish, -3); | |
1385 | if (dir != UBIDI_NEUTRAL ) | |
1386 | log_err("\nFailed getBaseDirection for string w length= -3 ", | |
1387 | "\nExpected %d \nReceived %d", UBIDI_NEUTRAL, dir); | |
1388 | /*All L- English string and length=-1 */ | |
1389 | dir = ubidi_getBaseDirection( stringEnglish, -1); | |
1390 | if (dir != UBIDI_LTR ) | |
1391 | log_err("\nFailed getBaseDirection for English string w length= -1 ", | |
1392 | "\nExpected %d \nReceived %d", UBIDI_LTR, dir); | |
1393 | /*All AL- Persian string and length=-1 */ | |
1394 | dir = ubidi_getBaseDirection( stringPersian, -1); | |
1395 | if (dir != UBIDI_RTL ) | |
1396 | log_err("\nFailed getBaseDirection for Persian string w length= -1 ", | |
1397 | "\nExpected %d \nReceived %d", UBIDI_RTL, dir); | |
1398 | /*All R- Hebrew string and length=-1 */ | |
1399 | dir = ubidi_getBaseDirection( stringHebrew, -1); | |
1400 | if (dir != UBIDI_RTL ) | |
1401 | log_err("\nFailed getBaseDirection for Hebrew string w length= -1 ", | |
1402 | "\nExpected %d \nReceived %d", UBIDI_RTL, dir); | |
1403 | /*All weak L- English digits string and length=-1 */ | |
1404 | dir = ubidi_getBaseDirection(stringAllEnglishDigits, -1); | |
1405 | if (dir != UBIDI_NEUTRAL ) | |
1406 | log_err("\nFailed getBaseDirection for English digits string w length= -1 ", | |
1407 | "\nExpected %d \nReceived %d", UBIDI_NEUTRAL, dir); | |
1408 | /*All weak AL- Arabic digits string and length=-1 */ | |
1409 | dir = ubidi_getBaseDirection(stringAllArabicDigits, -1); | |
1410 | if (dir != UBIDI_NEUTRAL ) | |
1411 | log_err("\nFailed getBaseDirection for Arabic string w length= -1 ", | |
1412 | "\nExpected %d \nReceived %d", UBIDI_NEUTRAL, dir); | |
1413 | ||
1414 | } | |
1415 | ||
46f4442e A |
1416 | |
1417 | static void doMisc(void) { | |
1418 | /* Miscellaneous tests to exercize less popular code paths */ | |
1419 | UBiDi *bidi, *bidiLine; | |
1420 | UChar src[MAXLEN], dest[MAXLEN]; | |
1421 | int32_t srcLen, destLen, runCount, i; | |
1422 | UBiDiLevel level; | |
1423 | UBiDiDirection dir; | |
1424 | int32_t map[MAXLEN]; | |
1425 | UErrorCode errorCode=U_ZERO_ERROR; | |
1426 | static const int32_t srcMap[6] = {0,1,-1,5,4}; | |
1427 | static const int32_t dstMap[6] = {0,1,-1,-1,4,3}; | |
1428 | ||
1429 | bidi = ubidi_openSized(120, 66, &errorCode); | |
1430 | if (bidi == NULL) { | |
1431 | log_err("Error with openSized(120, 66)\n"); | |
1432 | return; | |
1433 | } | |
1434 | bidiLine = ubidi_open(); | |
1435 | if (bidi == NULL) { | |
1436 | log_err("Error with open()\n"); | |
1437 | return; | |
1438 | } | |
b75a7d8f | 1439 | |
46f4442e A |
1440 | destLen = ubidi_writeReverse(src, 0, dest, MAXLEN, 0, &errorCode); |
1441 | if (destLen != 0) { | |
1442 | log_err("\nwriteReverse should return zero length, ", | |
1443 | "returned %d instead\n", destLen); | |
1444 | } | |
1445 | RETURN_IF_BAD_ERRCODE("#1#"); | |
1446 | ||
1447 | ubidi_setPara(bidi, src, 0, UBIDI_LTR, NULL, &errorCode); | |
1448 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1449 | if (destLen != 0) { | |
1450 | log_err("\nwriteReordered should return zero length, ", | |
1451 | "returned %d instead\n", destLen); | |
1452 | } | |
1453 | RETURN_IF_BAD_ERRCODE("#2#"); | |
1454 | ||
1455 | srcLen = u_unescape("abc ", src, MAXLEN); | |
1456 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1457 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1458 | for (i = 3; i < 6; i++) { | |
1459 | level = ubidi_getLevelAt(bidiLine, i); | |
1460 | if (level != UBIDI_RTL) { | |
1461 | log_err("\nTrailing space at index %d should get paragraph level" | |
1462 | "%d, got %d instead\n", i, UBIDI_RTL, level); | |
1463 | } | |
1464 | } | |
1465 | RETURN_IF_BAD_ERRCODE("#3#"); | |
1466 | ||
1467 | srcLen = u_unescape("abc def", src, MAXLEN); | |
1468 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1469 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1470 | for (i = 3; i < 6; i++) { | |
1471 | level = ubidi_getLevelAt(bidiLine, i); | |
1472 | if (level != UBIDI_RTL) { | |
1473 | log_err("\nTrailing space at index %d should get paragraph level" | |
1474 | "%d, got %d instead\n", i, UBIDI_RTL, level); | |
1475 | } | |
1476 | } | |
1477 | RETURN_IF_BAD_ERRCODE("#4#"); | |
1478 | ||
1479 | srcLen = u_unescape("abcdefghi ", src, MAXLEN); | |
1480 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1481 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1482 | for (i = 3; i < 6; i++) { | |
1483 | level = ubidi_getLevelAt(bidiLine, i); | |
1484 | if (level != 2) { | |
1485 | log_err("\nTrailing char at index %d should get level 2, " | |
1486 | "got %d instead\n", i, level); | |
1487 | } | |
1488 | } | |
1489 | RETURN_IF_BAD_ERRCODE("#5#"); | |
1490 | ||
1491 | ubidi_setReorderingOptions(bidi, UBIDI_OPTION_REMOVE_CONTROLS); | |
1492 | srcLen = u_unescape("\\u200eabc def", src, MAXLEN); | |
1493 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1494 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1495 | destLen = ubidi_getResultLength(bidiLine); | |
1496 | if (destLen != 5) { | |
1497 | log_err("\nWrong result length, should be 5, got %d\n", destLen); | |
1498 | } | |
1499 | RETURN_IF_BAD_ERRCODE("#6#"); | |
1500 | ||
1501 | srcLen = u_unescape("abcdefghi", src, MAXLEN); | |
1502 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR, NULL, &errorCode); | |
1503 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1504 | dir = ubidi_getDirection(bidiLine); | |
1505 | if (dir != UBIDI_LTR) { | |
1506 | log_err("\nWrong direction #1, should be %d, got %d\n", | |
1507 | UBIDI_LTR, dir); | |
1508 | } | |
1509 | RETURN_IF_BAD_ERRCODE("#7#"); | |
1510 | ||
1511 | ubidi_setPara(bidi, src, 0, UBIDI_LTR, NULL, &errorCode); | |
1512 | runCount = ubidi_countRuns(bidi, &errorCode); | |
1513 | if (runCount != 0) { | |
1514 | log_err("\nWrong number of runs #1, should be 0, got %d\n", runCount); | |
1515 | } | |
1516 | RETURN_IF_BAD_ERRCODE("#8#"); | |
1517 | ||
1518 | srcLen = u_unescape(" ", src, MAXLEN); | |
1519 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1520 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1521 | runCount = ubidi_countRuns(bidiLine, &errorCode); | |
1522 | if (runCount != 1) { | |
1523 | log_err("\nWrong number of runs #2, should be 1, got %d\n", runCount); | |
1524 | } | |
1525 | RETURN_IF_BAD_ERRCODE("#9#"); | |
1526 | ||
1527 | srcLen = u_unescape("a\\u05d0 bc", src, MAXLEN); | |
1528 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1529 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1530 | dir = ubidi_getDirection(bidi); | |
1531 | if (dir != UBIDI_MIXED) { | |
1532 | log_err("\nWrong direction #2, should be %d, got %d\n", | |
1533 | UBIDI_MIXED, dir); | |
1534 | } | |
1535 | dir = ubidi_getDirection(bidiLine); | |
1536 | if (dir != UBIDI_MIXED) { | |
1537 | log_err("\nWrong direction #3, should be %d, got %d\n", | |
1538 | UBIDI_MIXED, dir); | |
1539 | } | |
1540 | runCount = ubidi_countRuns(bidiLine, &errorCode); | |
1541 | if (runCount != 2) { | |
1542 | log_err("\nWrong number of runs #3, should be 2, got %d\n", runCount); | |
1543 | } | |
1544 | RETURN_IF_BAD_ERRCODE("#10#"); | |
1545 | ||
1546 | ubidi_invertMap(srcMap, map, 5); | |
1547 | if (memcmp(dstMap, map, sizeof(dstMap))) { | |
1548 | log_err("\nUnexpected inverted Map, got "); | |
1549 | for (i = 0; i < 6; i++) { | |
1550 | log_err("%d ", map[i]); | |
1551 | } | |
1552 | log_err("\n"); | |
1553 | } | |
1554 | ||
1555 | /* test REMOVE_BIDI_CONTROLS together with DO_MIRRORING */ | |
1556 | srcLen = u_unescape("abc\\u200e", src, MAXLEN); | |
1557 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR, NULL, &errorCode); | |
1558 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, | |
1559 | UBIDI_REMOVE_BIDI_CONTROLS | UBIDI_DO_MIRRORING, &errorCode); | |
1560 | if (destLen != 3 || memcmp(dest, src, 3 * sizeof(UChar))) { | |
1561 | log_err("\nWrong result #1, should be 'abc', got '%s'\n", | |
1562 | aescstrdup(dest, destLen)); | |
1563 | } | |
1564 | RETURN_IF_BAD_ERRCODE("#11#"); | |
1565 | ||
1566 | /* test inverse Bidi with marks and contextual orientation */ | |
1567 | ubidi_setReorderingMode(bidi, UBIDI_REORDER_INVERSE_LIKE_DIRECT); | |
1568 | ubidi_setReorderingOptions(bidi, UBIDI_OPTION_INSERT_MARKS); | |
1569 | ubidi_setPara(bidi, src, 0, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1570 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1571 | if (destLen != 0) { | |
1572 | log_err("\nWrong result #2, length should be 0, got %d\n", destLen); | |
1573 | } | |
1574 | RETURN_IF_BAD_ERRCODE("#12#"); | |
1575 | srcLen = u_unescape(" ", src, MAXLEN); | |
1576 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1577 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1578 | if (destLen != 3 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1579 | log_err("\nWrong result #3, should be ' ', got '%s'\n", | |
1580 | aescstrdup(dest, destLen)); | |
1581 | } | |
1582 | RETURN_IF_BAD_ERRCODE("#13#"); | |
1583 | srcLen = u_unescape("abc", src, MAXLEN); | |
1584 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1585 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1586 | if (destLen != 3 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1587 | log_err("\nWrong result #4, should be 'abc', got '%s'\n", | |
1588 | aescstrdup(dest, destLen)); | |
1589 | } | |
1590 | RETURN_IF_BAD_ERRCODE("#14#"); | |
1591 | srcLen = u_unescape("\\u05d0\\u05d1", src, MAXLEN); | |
1592 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1593 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1594 | srcLen = u_unescape("\\u05d1\\u05d0", src, MAXLEN); | |
1595 | if (destLen != 2 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1596 | log_err("\nWrong result #5, should be '%s', got '%s'\n", | |
1597 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1598 | } | |
1599 | RETURN_IF_BAD_ERRCODE("#15#"); | |
1600 | srcLen = u_unescape("abc \\u05d0\\u05d1", src, MAXLEN); | |
1601 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1602 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1603 | srcLen = u_unescape("\\u05d1\\u05d0 abc", src, MAXLEN); | |
1604 | if (destLen != 6 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1605 | log_err("\nWrong result #6, should be '%s', got '%s'\n", | |
1606 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1607 | } | |
1608 | RETURN_IF_BAD_ERRCODE("#16#"); | |
1609 | srcLen = u_unescape("\\u05d0\\u05d1 abc", src, MAXLEN); | |
1610 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1611 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1612 | srcLen = u_unescape("\\u200fabc \\u05d1\\u05d0", src, MAXLEN); | |
1613 | if (destLen != 7 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1614 | log_err("\nWrong result #7, should be '%s', got '%s'\n", | |
1615 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1616 | } | |
1617 | RETURN_IF_BAD_ERRCODE("#17#"); | |
1618 | srcLen = u_unescape("\\u05d0\\u05d1 abc .-=", src, MAXLEN); | |
1619 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1620 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1621 | srcLen = u_unescape("\\u200f=-. abc \\u05d1\\u05d0", src, MAXLEN); | |
1622 | if (destLen != 11 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1623 | log_err("\nWrong result #8, should be '%s', got '%s'\n", | |
1624 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1625 | } | |
1626 | RETURN_IF_BAD_ERRCODE("#18#"); | |
1627 | ubidi_orderParagraphsLTR(bidi, TRUE); | |
1628 | srcLen = u_unescape("\n\r \n\rabc\n\\u05d0\\u05d1\rabc \\u05d2\\u05d3\n\r" | |
1629 | "\\u05d4\\u05d5 abc\n\\u05d6\\u05d7 abc .-=\r\n" | |
1630 | "-* \\u05d8\\u05d9 abc .-=", src, MAXLEN); | |
1631 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
1632 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1633 | srcLen = u_unescape("\n\r \n\rabc\n\\u05d1\\u05d0\r\\u05d3\\u05d2 abc\n\r" | |
1634 | "\\u200fabc \\u05d5\\u05d4\n\\u200f=-. abc \\u05d7\\u05d6\r\n" | |
1635 | "\\u200f=-. abc \\u05d9\\u05d8 *-", src, MAXLEN); | |
1636 | if (destLen != 57 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1637 | log_err("\nWrong result #9, should be '%s', got '%s'\n", | |
1638 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1639 | } | |
1640 | RETURN_IF_BAD_ERRCODE("#19#"); | |
1641 | srcLen = u_unescape("\\u05d0 \t", src, MAXLEN); | |
1642 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR, NULL, &errorCode); | |
1643 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1644 | srcLen = u_unescape("\\u05D0\\u200e \t", src, MAXLEN); | |
1645 | if (destLen != 4 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1646 | log_err("\nWrong result #10, should be '%s', got '%s'\n", | |
1647 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1648 | } | |
1649 | RETURN_IF_BAD_ERRCODE("#20#"); | |
1650 | srcLen = u_unescape("\\u05d0 123 \t\\u05d1 123 \\u05d2", src, MAXLEN); | |
1651 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR, NULL, &errorCode); | |
1652 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1653 | srcLen = u_unescape("\\u05d0 \\u200e123\\u200e \t\\u05d2 123 \\u05d1", src, MAXLEN); | |
1654 | if (destLen != 16 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1655 | log_err("\nWrong result #11, should be '%s', got '%s'\n", | |
1656 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1657 | } | |
1658 | RETURN_IF_BAD_ERRCODE("#21#"); | |
1659 | srcLen = u_unescape("\\u05d0 123 \\u0660\\u0661 ab", src, MAXLEN); | |
1660 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR, NULL, &errorCode); | |
1661 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1662 | srcLen = u_unescape("\\u05d0 \\u200e123 \\u200e\\u0660\\u0661 ab", src, MAXLEN); | |
1663 | if (destLen != 13 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1664 | log_err("\nWrong result #12, should be '%s', got '%s'\n", | |
1665 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1666 | } | |
1667 | RETURN_IF_BAD_ERRCODE("#22#"); | |
1668 | srcLen = u_unescape("ab \t", src, MAXLEN); | |
1669 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1670 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); | |
1671 | srcLen = u_unescape("\\u200f\t ab", src, MAXLEN); | |
1672 | if (destLen != 5 || memcmp(dest, src, destLen * sizeof(UChar))) { | |
1673 | log_err("\nWrong result #13, should be '%s', got '%s'\n", | |
1674 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
1675 | } | |
1676 | RETURN_IF_BAD_ERRCODE("#23#"); | |
1677 | ||
1678 | /* check exceeding para level */ | |
1679 | ubidi_close(bidi); | |
1680 | bidi = ubidi_open(); | |
1681 | srcLen = u_unescape("A\\u202a\\u05d0\\u202aC\\u202c\\u05d1\\u202cE", src, MAXLEN); | |
1682 | ubidi_setPara(bidi, src, srcLen, UBIDI_MAX_EXPLICIT_LEVEL - 1, NULL, &errorCode); | |
1683 | level = ubidi_getLevelAt(bidi, 2); | |
57a6839d A |
1684 | if (level != UBIDI_MAX_EXPLICIT_LEVEL) { |
1685 | log_err("\nWrong level at index 2\n, should be %d, got %d\n", UBIDI_MAX_EXPLICIT_LEVEL, level); | |
46f4442e A |
1686 | } |
1687 | RETURN_IF_BAD_ERRCODE("#24#"); | |
1688 | ||
1689 | /* check 1-char runs with RUNS_ONLY */ | |
1690 | ubidi_setReorderingMode(bidi, UBIDI_REORDER_RUNS_ONLY); | |
1691 | srcLen = u_unescape("a \\u05d0 b \\u05d1 c \\u05d2 d ", src, MAXLEN); | |
1692 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR, NULL, &errorCode); | |
1693 | runCount = ubidi_countRuns(bidi, &errorCode); | |
1694 | if (runCount != 14) { | |
1695 | log_err("\nWrong number of runs #3, should be 14, got %d\n", runCount); | |
1696 | } | |
1697 | RETURN_IF_BAD_ERRCODE("#25#"); | |
1698 | ||
1699 | ubidi_close(bidi); | |
1700 | ubidi_close(bidiLine); | |
1701 | } | |
1702 | ||
1703 | static void | |
1704 | testFailureRecovery(void) { | |
1705 | UErrorCode errorCode; | |
1706 | UBiDi *bidi, *bidiLine; | |
1707 | UChar src[MAXLEN]; | |
1708 | int32_t srcLen; | |
1709 | UBiDiLevel level; | |
1710 | UBiDiReorderingMode rm; | |
1711 | static UBiDiLevel myLevels[3] = {6,5,4}; | |
1712 | ||
1713 | log_verbose("\nEntering TestFailureRecovery\n\n"); | |
1714 | errorCode = U_FILE_ACCESS_ERROR; | |
1715 | if (ubidi_writeReordered(NULL, NULL, 0, 0, &errorCode) != 0) { | |
73c04bcf A |
1716 | log_err("ubidi_writeReordered did not return 0 when passed a failing UErrorCode\n"); |
1717 | } | |
46f4442e | 1718 | if (ubidi_writeReverse(NULL, 0, NULL, 0, 0, &errorCode) != 0) { |
73c04bcf A |
1719 | log_err("ubidi_writeReverse did not return 0 when passed a failing UErrorCode\n"); |
1720 | } | |
46f4442e A |
1721 | errorCode = U_ZERO_ERROR; |
1722 | if (ubidi_writeReordered(NULL, NULL, 0, 0, &errorCode) != 0 || errorCode != U_ILLEGAL_ARGUMENT_ERROR) { | |
73c04bcf A |
1723 | log_err("ubidi_writeReordered did not fail as expected\n"); |
1724 | } | |
46f4442e A |
1725 | |
1726 | bidi = ubidi_open(); | |
1727 | srcLen = u_unescape("abc", src, MAXLEN); | |
1728 | errorCode = U_ZERO_ERROR; | |
1729 | ubidi_setPara(bidi, src, srcLen, UBIDI_DEFAULT_LTR - 1, NULL, &errorCode); | |
1730 | if (U_SUCCESS(errorCode)) { | |
1731 | log_err("\nubidi_setPara did not fail when passed too big para level\n"); | |
1732 | } | |
1733 | errorCode = U_ZERO_ERROR; | |
1734 | if (ubidi_writeReverse(NULL, 0, NULL, 0, 0, &errorCode) != 0 || errorCode != U_ILLEGAL_ARGUMENT_ERROR) { | |
73c04bcf A |
1735 | log_err("ubidi_writeReverse did not fail as expected\n"); |
1736 | } | |
46f4442e A |
1737 | bidiLine = ubidi_open(); |
1738 | errorCode = U_ZERO_ERROR; | |
1739 | ubidi_setLine(bidi, 0, 6, bidiLine, &errorCode); | |
1740 | if (U_SUCCESS(errorCode)) { | |
1741 | log_err("\nubidi_setLine did not fail when called before valid setPara()\n"); | |
1742 | } | |
1743 | errorCode = U_ZERO_ERROR; | |
1744 | srcLen = u_unescape("abc", src, MAXLEN); | |
1745 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR + 4, NULL, &errorCode); | |
1746 | level = ubidi_getLevelAt(bidi, 3); | |
1747 | if (level != 0) { | |
1748 | log_err("\nubidi_getLevelAt did not fail when called with bad argument\n"); | |
1749 | } | |
1750 | errorCode = U_ZERO_ERROR; | |
1751 | ubidi_close(bidi); | |
1752 | bidi = ubidi_openSized(-1, 0, &errorCode); | |
1753 | if (U_SUCCESS(errorCode)) { | |
1754 | log_err("\nubidi_openSized did not fail when called with bad argument\n"); | |
1755 | } | |
1756 | ubidi_close(bidi); | |
1757 | bidi = ubidi_openSized(2, 1, &errorCode); | |
1758 | errorCode = U_ZERO_ERROR; | |
1759 | srcLen = u_unescape("abc", src, MAXLEN); | |
1760 | ubidi_setPara(bidi, src, srcLen, UBIDI_LTR, NULL, &errorCode); | |
1761 | if (U_SUCCESS(errorCode)) { | |
1762 | log_err("\nsetPara did not fail when called with text too long\n"); | |
1763 | } | |
1764 | errorCode = U_ZERO_ERROR; | |
1765 | srcLen = u_unescape("=2", src, MAXLEN); | |
1766 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1767 | ubidi_countRuns(bidi, &errorCode); | |
1768 | if (U_SUCCESS(errorCode)) { | |
1769 | log_err("\nsetPara did not fail when called for too many runs\n"); | |
1770 | } | |
1771 | ubidi_close(bidi); | |
1772 | bidi = ubidi_open(); | |
1773 | rm = ubidi_getReorderingMode(bidi); | |
1774 | ubidi_setReorderingMode(bidi, UBIDI_REORDER_DEFAULT - 1); | |
1775 | if (rm != ubidi_getReorderingMode(bidi)) { | |
1776 | log_err("\nsetReorderingMode with bad argument #1 should have no effect\n"); | |
1777 | } | |
1778 | ubidi_setReorderingMode(bidi, 9999); | |
1779 | if (rm != ubidi_getReorderingMode(bidi)) { | |
1780 | log_err("\nsetReorderingMode with bad argument #2 should have no effect\n"); | |
1781 | } | |
1782 | ||
1783 | /* Try a surrogate char */ | |
1784 | errorCode = U_ZERO_ERROR; | |
1785 | srcLen = u_unescape("\\uD800\\uDC00", src, MAXLEN); | |
1786 | ubidi_setPara(bidi, src, srcLen, UBIDI_RTL, NULL, &errorCode); | |
1787 | if (ubidi_getDirection(bidi) != UBIDI_MIXED) { | |
1788 | log_err("\ngetDirection for 1st surrogate char should be MIXED\n"); | |
1789 | } | |
1790 | errorCode = U_ZERO_ERROR; | |
1791 | srcLen = u_unescape("abc", src, MAXLEN); | |
1792 | ubidi_setPara(bidi, src, srcLen, 5, myLevels, &errorCode); | |
1793 | if (U_SUCCESS(errorCode)) { | |
1794 | log_err("\nsetPara did not fail when called with bad levels\n"); | |
1795 | } | |
1796 | ubidi_close(bidi); | |
1797 | ubidi_close(bidiLine); | |
1798 | ||
1799 | log_verbose("\nExiting TestFailureRecovery\n\n"); | |
73c04bcf | 1800 | } |
b75a7d8f | 1801 | |
46f4442e A |
1802 | static void |
1803 | testMultipleParagraphs(void) { | |
73c04bcf A |
1804 | static const char* const text = "__ABC\\u001c" /* Para #0 offset 0 */ |
1805 | "__\\u05d0DE\\u001c" /* 1 6 */ | |
1806 | "__123\\u001c" /* 2 12 */ | |
1807 | "\\u000d\\u000a" /* 3 18 */ | |
1808 | "FG\\u000d" /* 4 20 */ | |
1809 | "\\u000d" /* 5 23 */ | |
1810 | "HI\\u000d\\u000a" /* 6 24 */ | |
1811 | "\\u000d\\u000a" /* 7 28 */ | |
1812 | "\\u000a" /* 8 30 */ | |
1813 | "\\u000a" /* 9 31 */ | |
1814 | "JK\\u001c"; /* 10 32 */ | |
1815 | static const int32_t paraCount=11; | |
1816 | static const int32_t paraBounds[]={0, 6, 12, 18, 20, 23, 24, 28, 30, 31, 32, 35}; | |
1817 | static const UBiDiLevel paraLevels[]={UBIDI_LTR, UBIDI_RTL, UBIDI_DEFAULT_LTR, UBIDI_DEFAULT_RTL, 22, 23}; | |
1818 | static const UBiDiLevel multiLevels[6][11] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | |
1819 | {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, | |
1820 | {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | |
1821 | {0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0}, | |
1822 | {22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22}, | |
1823 | {23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23}}; | |
1824 | static const char* const text2 = "\\u05d0 1-2\\u001c\\u0630 1-2\\u001c1-2"; | |
1825 | static const UBiDiLevel levels2[] = {1,1,2,2,2,0, 1,1,2,1,2,0, 2,2,2}; | |
46f4442e A |
1826 | static UBiDiLevel myLevels[10] = {0,0,0,0,0,0,0,0,0,0}; |
1827 | static const UChar multiparaTestString[] = { | |
1828 | 0x5de, 0x5e0, 0x5e1, 0x5d4, 0x20, 0x5e1, 0x5e4, 0x5da, | |
1829 | 0x20, 0xa, 0xa, 0x41, 0x72, 0x74, 0x69, 0x73, | |
1830 | 0x74, 0x3a, 0x20, 0x5de, 0x5e0, 0x5e1, 0x5d4, 0x20, | |
1831 | 0x5e1, 0x5e4, 0x5da, 0x20, 0xa, 0xa, 0x41, 0x6c, | |
1832 | 0x62, 0x75, 0x6d, 0x3a, 0x20, 0x5de, 0x5e0, 0x5e1, | |
1833 | 0x5d4, 0x20, 0x5e1, 0x5e4, 0x5da, 0x20, 0xa, 0xa, | |
1834 | 0x54, 0x69, 0x6d, 0x65, 0x3a, 0x20, 0x32, 0x3a, | |
1835 | 0x32, 0x37, 0xa, 0xa | |
1836 | }; | |
1837 | static const UBiDiLevel multiparaTestLevels[] = { | |
1838 | 1, 1, 1, 1, 1, 1, 1, 1, | |
1839 | 1, 1, 0, 0, 0, 0, 0, 0, | |
1840 | 0, 0, 0, 1, 1, 1, 1, 1, | |
1841 | 1, 1, 1, 0, 0, 0, 0, 0, | |
1842 | 0, 0, 0, 0, 0, 1, 1, 1, | |
1843 | 1, 1, 1, 1, 1, 0, 0, 0, | |
1844 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1845 | 0, 0, 0, 0 | |
1846 | }; | |
73c04bcf A |
1847 | UBiDiLevel gotLevel; |
1848 | const UBiDiLevel* gotLevels; | |
1849 | UBool orderParagraphsLTR; | |
46f4442e | 1850 | UChar src[MAXLEN], dest[MAXLEN]; |
73c04bcf A |
1851 | UErrorCode errorCode=U_ZERO_ERROR; |
1852 | UBiDi* pBidi=ubidi_open(); | |
1853 | UBiDi* pLine; | |
1854 | int32_t srcSize, count, paraStart, paraLimit, paraIndex, length; | |
46f4442e | 1855 | int32_t srcLen, destLen; |
73c04bcf | 1856 | int i, j, k; |
b75a7d8f | 1857 | |
46f4442e | 1858 | log_verbose("\nEntering TestMultipleParagraphs\n\n"); |
73c04bcf A |
1859 | u_unescape(text, src, MAXLEN); |
1860 | srcSize=u_strlen(src); | |
1861 | ubidi_setPara(pBidi, src, srcSize, UBIDI_LTR, NULL, &errorCode); | |
1862 | if(U_FAILURE(errorCode)){ | |
1863 | log_err("ubidi_setPara failed, paraLevel=%d, errorCode %s\n", | |
1864 | UBIDI_LTR, u_errorName(errorCode)); | |
1865 | ubidi_close(pBidi); | |
1866 | return; | |
1867 | } | |
1868 | /* check paragraph count and boundaries */ | |
1869 | if (paraCount!=(count=ubidi_countParagraphs(pBidi))) { | |
1870 | log_err("ubidi_countParagraphs returned %d, should be %d\n", | |
1871 | count, paraCount); | |
1872 | } | |
1873 | for (i=0; i<paraCount; i++) { | |
1874 | ubidi_getParagraphByIndex(pBidi, i, ¶Start, ¶Limit, NULL, &errorCode); | |
1875 | if ((paraStart!=paraBounds[i]) || (paraLimit!=paraBounds[i+1])) { | |
1876 | log_err("Found boundaries of paragraph %d: %d-%d; expected: %d-%d\n", | |
1877 | i, paraStart, paraLimit, paraBounds[i], paraBounds[i+1]); | |
1878 | } | |
1879 | } | |
1880 | errorCode=U_ZERO_ERROR; | |
1881 | /* check with last paragraph not terminated by B */ | |
1882 | src[srcSize-1]='L'; | |
1883 | ubidi_setPara(pBidi, src, srcSize, UBIDI_LTR, NULL, &errorCode); | |
1884 | if(U_FAILURE(errorCode)){ | |
1885 | log_err("2nd ubidi_setPara failed, paraLevel=%d, errorCode %s\n", | |
1886 | UBIDI_LTR, u_errorName(errorCode)); | |
1887 | ubidi_close(pBidi); | |
1888 | return; | |
1889 | } | |
1890 | if (paraCount!=(count=ubidi_countParagraphs(pBidi))) { | |
1891 | log_err("2nd ubidi_countParagraphs returned %d, should be %d\n", | |
1892 | count, paraCount); | |
1893 | } | |
1894 | i=paraCount-1; | |
1895 | ubidi_getParagraphByIndex(pBidi, i, ¶Start, ¶Limit, NULL, &errorCode); | |
1896 | if ((paraStart!=paraBounds[i]) || (paraLimit!=paraBounds[i+1])) { | |
1897 | log_err("2nd Found boundaries of paragraph %d: %d-%d; expected: %d-%d\n", | |
1898 | i, paraStart, paraLimit, paraBounds[i], paraBounds[i+1]); | |
1899 | } | |
1900 | errorCode=U_ZERO_ERROR; | |
1901 | /* check paraLevel for all paragraphs under various paraLevel specs */ | |
1902 | for (k=0; k<6; k++) { | |
1903 | ubidi_setPara(pBidi, src, srcSize, paraLevels[k], NULL, &errorCode); | |
1904 | for (i=0; i<paraCount; i++) { | |
1905 | paraIndex=ubidi_getParagraph(pBidi, paraBounds[i], NULL, NULL, &gotLevel, &errorCode); | |
1906 | if (paraIndex!=i) { | |
1907 | log_err("For paraLevel=%d paragraph=%d, found paragraph index=%d expected=%d\n", | |
1908 | paraLevels[k], i, paraIndex, i); | |
1909 | } | |
1910 | if (gotLevel!=multiLevels[k][i]) { | |
1911 | log_err("For paraLevel=%d paragraph=%d, found level=%d expected %d\n", | |
1912 | paraLevels[k], i, gotLevel, multiLevels[k][i]); | |
1913 | } | |
1914 | } | |
1915 | gotLevel=ubidi_getParaLevel(pBidi); | |
1916 | if (gotLevel!=multiLevels[k][0]) { | |
1917 | log_err("For paraLevel=%d getParaLevel=%d, expected %d\n", | |
1918 | paraLevels[k], gotLevel, multiLevels[k][0]); | |
1919 | } | |
1920 | } | |
1921 | errorCode=U_ZERO_ERROR; | |
1922 | /* check that the result of ubidi_getParaLevel changes if the first | |
1923 | * paragraph has a different level | |
1924 | */ | |
1925 | src[0]=0x05d2; /* Hebrew letter Gimel */ | |
1926 | ubidi_setPara(pBidi, src, srcSize, UBIDI_DEFAULT_LTR, NULL, &errorCode); | |
1927 | gotLevel=ubidi_getParaLevel(pBidi); | |
1928 | if (gotLevel!=UBIDI_RTL) { | |
1929 | log_err("For paraLevel=UBIDI_DEFAULT_LTR getParaLevel=%d, expected=%d\n", | |
1930 | gotLevel, UBIDI_RTL); | |
1931 | } | |
1932 | errorCode=U_ZERO_ERROR; | |
1933 | /* check that line cannot overlap paragraph boundaries */ | |
1934 | pLine=ubidi_open(); | |
1935 | i=paraBounds[1]; | |
1936 | k=paraBounds[2]+1; | |
1937 | ubidi_setLine(pBidi, i, k, pLine, &errorCode); | |
1938 | if (U_SUCCESS(errorCode)) { | |
1939 | log_err("For line limits %d-%d got success %s\n", | |
1940 | i, k, u_errorName(errorCode)); | |
1941 | } | |
1942 | errorCode=U_ZERO_ERROR; | |
1943 | i=paraBounds[1]; | |
1944 | k=paraBounds[2]; | |
1945 | ubidi_setLine(pBidi, i, k, pLine, &errorCode); | |
1946 | if (U_FAILURE(errorCode)) { | |
1947 | log_err("For line limits %d-%d got error %s\n", | |
1948 | i, k, u_errorName(errorCode)); | |
1949 | errorCode=U_ZERO_ERROR; | |
1950 | } | |
1951 | /* check level of block separator at end of paragraph when orderParagraphsLTR==FALSE */ | |
1952 | ubidi_setPara(pBidi, src, srcSize, UBIDI_RTL, NULL, &errorCode); | |
1953 | /* get levels through para Bidi block */ | |
1954 | gotLevels=ubidi_getLevels(pBidi, &errorCode); | |
1955 | if (U_FAILURE(errorCode)) { | |
1956 | log_err("Error on Para getLevels %s\n", u_errorName(errorCode)); | |
1957 | ubidi_close(pLine); | |
1958 | ubidi_close(pBidi); | |
1959 | return; | |
1960 | } | |
1961 | for (i=26; i<32; i++) { | |
1962 | if (gotLevels[i]!=UBIDI_RTL) { | |
1963 | log_err("For char %d(%04x), level=%d, expected=%d\n", | |
1964 | i, src[i], gotLevels[i], UBIDI_RTL); | |
1965 | } | |
1966 | } | |
1967 | /* get levels through para Line block */ | |
1968 | i=paraBounds[1]; | |
1969 | k=paraBounds[2]; | |
1970 | ubidi_setLine(pBidi, i, k, pLine, &errorCode); | |
1971 | if (U_FAILURE(errorCode)) { | |
1972 | log_err("For line limits %d-%d got error %s\n", | |
1973 | i, k, u_errorName(errorCode)); | |
1974 | ubidi_close(pLine); | |
1975 | ubidi_close(pBidi); | |
1976 | return; | |
1977 | } | |
1978 | paraIndex=ubidi_getParagraph(pLine, i, ¶Start, ¶Limit, &gotLevel, &errorCode); | |
1979 | gotLevels=ubidi_getLevels(pLine, &errorCode); | |
1980 | if (U_FAILURE(errorCode)) { | |
1981 | log_err("Error on Line getLevels %s\n", u_errorName(errorCode)); | |
1982 | ubidi_close(pLine); | |
1983 | ubidi_close(pBidi); | |
1984 | return; | |
1985 | } | |
1986 | length=ubidi_getLength(pLine); | |
1987 | if ((gotLevel!=UBIDI_RTL) || (gotLevels[length-1]!=UBIDI_RTL)) { | |
1988 | log_err("For paragraph %d with limits %d-%d, paraLevel=%d expected=%d, " | |
1989 | "level of separator=%d expected=%d\n", | |
1990 | paraIndex, paraStart, paraLimit, gotLevel, UBIDI_RTL, gotLevels[length-1], UBIDI_RTL); | |
1991 | } | |
1992 | orderParagraphsLTR=ubidi_isOrderParagraphsLTR(pBidi); | |
1993 | if (orderParagraphsLTR) { | |
1994 | log_err("Found orderParagraphsLTR=%d expected=%d\n", orderParagraphsLTR, FALSE); | |
1995 | } | |
1996 | ubidi_orderParagraphsLTR(pBidi, TRUE); | |
1997 | orderParagraphsLTR=ubidi_isOrderParagraphsLTR(pBidi); | |
1998 | if (!orderParagraphsLTR) { | |
1999 | log_err("Found orderParagraphsLTR=%d expected=%d\n", orderParagraphsLTR, TRUE); | |
2000 | } | |
2001 | /* check level of block separator at end of paragraph when orderParagraphsLTR==TRUE */ | |
2002 | ubidi_setPara(pBidi, src, srcSize, UBIDI_RTL, NULL, &errorCode); | |
2003 | /* get levels through para Bidi block */ | |
2004 | gotLevels=ubidi_getLevels(pBidi, &errorCode); | |
2005 | for (i=26; i<32; i++) { | |
2006 | if (gotLevels[i]!=0) { | |
2007 | log_err("For char %d(%04x), level=%d, expected=%d\n", | |
2008 | i, src[i], gotLevels[i], 0); | |
2009 | } | |
2010 | } | |
2011 | errorCode=U_ZERO_ERROR; | |
2012 | /* get levels through para Line block */ | |
2013 | i=paraBounds[1]; | |
2014 | k=paraBounds[2]; | |
2015 | ubidi_setLine(pBidi, paraStart, paraLimit, pLine, &errorCode); | |
2016 | paraIndex=ubidi_getParagraph(pLine, i, ¶Start, ¶Limit, &gotLevel, &errorCode); | |
2017 | gotLevels=ubidi_getLevels(pLine, &errorCode); | |
2018 | length=ubidi_getLength(pLine); | |
2019 | if ((gotLevel!=UBIDI_RTL) || (gotLevels[length-1]!=0)) { | |
2020 | log_err("For paragraph %d with limits %d-%d, paraLevel=%d expected=%d, " | |
2021 | "level of separator=%d expected=%d\n", | |
2022 | paraIndex, paraStart, paraLimit, gotLevel, UBIDI_RTL, gotLevels[length-1], 0); | |
2023 | log_verbose("levels="); | |
2024 | for (count=0; count<length; count++) { | |
2025 | log_verbose(" %d", gotLevels[count]); | |
2026 | } | |
2027 | log_verbose("\n"); | |
2028 | } | |
b75a7d8f | 2029 | |
73c04bcf A |
2030 | /* test that the concatenation of separate invocations of the bidi code |
2031 | * on each individual paragraph in order matches the levels array that | |
2032 | * results from invoking bidi once over the entire multiparagraph tests | |
2033 | * (with orderParagraphsLTR false, of course) | |
2034 | */ | |
2035 | u_unescape(text, src, MAXLEN); /* restore original content */ | |
2036 | srcSize=u_strlen(src); | |
2037 | ubidi_orderParagraphsLTR(pBidi, FALSE); | |
2038 | ubidi_setPara(pBidi, src, srcSize, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
2039 | gotLevels=ubidi_getLevels(pBidi, &errorCode); | |
2040 | for (i=0; i<paraCount; i++) { | |
2041 | /* use pLine for individual paragraphs */ | |
2042 | paraStart = paraBounds[i]; | |
2043 | length = paraBounds[i+1] - paraStart; | |
2044 | ubidi_setPara(pLine, src+paraStart, length, UBIDI_DEFAULT_RTL, NULL, &errorCode); | |
2045 | for (j=0; j<length; j++) { | |
2046 | if ((k=ubidi_getLevelAt(pLine, j)) != (gotLevel=gotLevels[paraStart+j])) { | |
2047 | log_err("Checking paragraph concatenation: for paragraph=%d, " | |
2048 | "char=%d(%04x), level=%d, expected=%d\n", | |
2049 | i, j, src[paraStart+j], k, gotLevel); | |
2050 | } | |
2051 | } | |
2052 | } | |
2053 | ||
2054 | /* ensure that leading numerics in a paragraph are not treated as arabic | |
2055 | numerals because of arabic text in a preceding paragraph | |
2056 | */ | |
2057 | u_unescape(text2, src, MAXLEN); | |
2058 | srcSize=u_strlen(src); | |
2059 | ubidi_orderParagraphsLTR(pBidi, TRUE); | |
2060 | ubidi_setPara(pBidi, src, srcSize, UBIDI_RTL, NULL, &errorCode); | |
2061 | gotLevels=ubidi_getLevels(pBidi, &errorCode); | |
46f4442e A |
2062 | if (U_FAILURE(errorCode)) { |
2063 | log_err("Can't get levels. %s\n", u_errorName(errorCode)); | |
2064 | return; | |
2065 | } | |
73c04bcf A |
2066 | for (i=0; i<srcSize; i++) { |
2067 | if (gotLevels[i]!=levels2[i]) { | |
2068 | log_err("Checking leading numerics: for char %d(%04x), level=%d, expected=%d\n", | |
2069 | i, src[i], gotLevels[i], levels2[i]); | |
2070 | } | |
2071 | } | |
2072 | ||
2073 | /* check handling of whitespace before end of paragraph separator when | |
2074 | * orderParagraphsLTR==TRUE, when last paragraph has, and lacks, a terminating B | |
2075 | */ | |
2076 | u_memset(src, 0x0020, MAXLEN); | |
2077 | srcSize = 5; | |
2078 | ubidi_orderParagraphsLTR(pBidi, TRUE); | |
2079 | for (i=0x001c; i<=0x0020; i+=(0x0020-0x001c)) { | |
46f4442e | 2080 | src[4]=(UChar)i; /* with and without terminating B */ |
73c04bcf | 2081 | for (j=0x0041; j<=0x05d0; j+=(0x05d0-0x0041)) { |
46f4442e | 2082 | src[0]=(UChar)j; /* leading 'A' or Alef */ |
73c04bcf A |
2083 | for (gotLevel=4; gotLevel<=5; gotLevel++) { |
2084 | /* test even and odd paraLevel */ | |
2085 | ubidi_setPara(pBidi, src, srcSize, gotLevel, NULL, &errorCode); | |
2086 | gotLevels=ubidi_getLevels(pBidi, &errorCode); | |
2087 | for (k=1; k<=3; k++) { | |
2088 | if (gotLevels[k]!=gotLevel) { | |
2089 | log_err("Checking trailing spaces: for leading_char=%04x, " | |
2090 | "last_char=%04x, index=%d, level=%d, expected=%d\n", | |
2091 | src[0], src[4], k, gotLevels[k], gotLevel); | |
2092 | } | |
2093 | } | |
2094 | } | |
2095 | } | |
2096 | } | |
2097 | ||
46f4442e A |
2098 | /* check default orientation when inverse bidi and paragraph starts |
2099 | * with LTR strong char and ends with RTL strong char, with and without | |
2100 | * a terminating B | |
2101 | */ | |
2102 | ubidi_setReorderingMode(pBidi, UBIDI_REORDER_INVERSE_LIKE_DIRECT); | |
2103 | srcLen = u_unescape("abc \\u05d2\\u05d1\n", src, MAXLEN); | |
2104 | ubidi_setPara(pBidi, src, srcLen, UBIDI_DEFAULT_LTR, NULL, &errorCode); | |
2105 | destLen = ubidi_writeReordered(pBidi, dest, MAXLEN, 0, &errorCode); | |
2106 | srcLen = u_unescape("\\u05d1\\u05d2 abc\n", src, MAXLEN); | |
2107 | if (memcmp(src, dest, destLen * sizeof(UChar))) { | |
2108 | log_err("\nInvalid output #0, should be '%s', got '%s'\n", | |
2109 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
2110 | } | |
2111 | srcLen = u_unescape("abc \\u05d2\\u05d1", src, MAXLEN); | |
2112 | ubidi_setPara(pBidi, src, srcLen, UBIDI_DEFAULT_LTR, NULL, &errorCode); | |
2113 | destLen = ubidi_writeReordered(pBidi, dest, MAXLEN, 0, &errorCode); | |
2114 | srcLen = u_unescape("\\u05d1\\u05d2 abc", src, MAXLEN); | |
2115 | if (memcmp(src, dest, destLen * sizeof(UChar))) { | |
2116 | log_err("\nInvalid output #1, should be '%s', got '%s'\n", | |
2117 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
2118 | } | |
2119 | ||
2120 | /* check multiple paragraphs together with explicit levels | |
2121 | */ | |
2122 | ubidi_setReorderingMode(pBidi, UBIDI_REORDER_DEFAULT); | |
2123 | srcLen = u_unescape("ab\\u05d1\\u05d2\n\\u05d3\\u05d4123", src, MAXLEN); | |
2124 | ubidi_setPara(pBidi, src, srcLen, UBIDI_LTR, myLevels, &errorCode); | |
2125 | destLen = ubidi_writeReordered(pBidi, dest, MAXLEN, 0, &errorCode); | |
2126 | srcLen = u_unescape("ab\\u05d2\\u05d1\\n123\\u05d4\\u05d3", src, MAXLEN); | |
2127 | if (memcmp(src, dest, destLen * sizeof(UChar))) { | |
2128 | log_err("\nInvalid output #2, should be '%s', got '%s'\n", | |
2129 | aescstrdup(src, srcLen), aescstrdup(dest, destLen)); | |
2130 | } | |
2131 | count = ubidi_countParagraphs(pBidi); | |
2132 | if (count != 2) { | |
2133 | log_err("\nInvalid number of paras, should be 2, got %d\n", count); | |
2134 | } | |
2135 | ||
73c04bcf A |
2136 | ubidi_close(pLine); |
2137 | ubidi_close(pBidi); | |
46f4442e A |
2138 | log_verbose("\nExiting TestMultipleParagraphs\n\n"); |
2139 | ||
2140 | /* check levels in multiple paragraphs with default para level | |
2141 | */ | |
2142 | pBidi = ubidi_open(); | |
2143 | errorCode = U_ZERO_ERROR; | |
b331163b | 2144 | ubidi_setPara(pBidi, multiparaTestString, UPRV_LENGTHOF(multiparaTestString), |
46f4442e A |
2145 | UBIDI_DEFAULT_LTR, NULL, &errorCode); |
2146 | if (U_FAILURE(errorCode)) { | |
2147 | log_err("ubidi_setPara failed for multiparaTestString\n"); | |
2148 | ubidi_close(pBidi); | |
2149 | return; | |
2150 | } | |
2151 | gotLevels = ubidi_getLevels(pBidi, &errorCode); | |
2152 | if (U_FAILURE(errorCode)) { | |
2153 | log_err("ubidi_getLevels failed for multiparaTestString\n"); | |
2154 | ubidi_close(pBidi); | |
2155 | return; | |
2156 | } | |
b331163b | 2157 | for (i = 0; i < UPRV_LENGTHOF(multiparaTestString); i++) { |
46f4442e A |
2158 | if (gotLevels[i] != multiparaTestLevels[i]) { |
2159 | log_err("Error on level for multiparaTestString at index %d, " | |
2160 | "expected=%d, actual=%d\n", | |
2161 | i, multiparaTestLevels[i], gotLevels[i]); | |
2162 | } | |
2163 | } | |
2164 | ubidi_close(pBidi); | |
2165 | ||
73c04bcf A |
2166 | } |
2167 | ||
2168 | ||
2169 | /* inverse BiDi ------------------------------------------------------------- */ | |
b75a7d8f A |
2170 | |
2171 | static int countRoundtrips=0, countNonRoundtrips=0; | |
2172 | ||
b331163b | 2173 | #define STRING_TEST_CASE(s) { (s), UPRV_LENGTHOF(s) } |
73c04bcf | 2174 | |
b75a7d8f | 2175 | static void |
46f4442e | 2176 | testInverse(void) { |
73c04bcf A |
2177 | static const UChar |
2178 | string0[]={ 0x6c, 0x61, 0x28, 0x74, 0x69, 0x6e, 0x20, 0x5d0, 0x5d1, 0x29, 0x5d2, 0x5d3 }, | |
2179 | string1[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x31, 0x32, 0x33 }, | |
2180 | string2[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x28, 0x5d1, 0x5d2, 0x20, 0x31, 0x29, 0x32, 0x33 }, | |
2181 | string3[]={ 0x31, 0x32, 0x33, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x34, 0x35, 0x36 }, | |
2182 | string4[]={ 0x61, 0x62, 0x20, 0x61, 0x62, 0x20, 0x661, 0x662 }; | |
2183 | ||
2184 | static const struct { | |
2185 | const UChar *s; | |
2186 | int32_t length; | |
2187 | } testCases[]={ | |
2188 | STRING_TEST_CASE(string0), | |
2189 | STRING_TEST_CASE(string1), | |
2190 | STRING_TEST_CASE(string2), | |
2191 | STRING_TEST_CASE(string3), | |
2192 | STRING_TEST_CASE(string4) | |
2193 | }; | |
2194 | ||
b75a7d8f A |
2195 | UBiDi *pBiDi; |
2196 | UErrorCode errorCode; | |
2197 | int i; | |
2198 | ||
46f4442e | 2199 | log_verbose("\nEntering TestInverse\n\n"); |
b75a7d8f A |
2200 | pBiDi=ubidi_open(); |
2201 | if(pBiDi==NULL) { | |
2202 | log_err("unable to open a UBiDi object (out of memory)\n"); | |
2203 | return; | |
2204 | } | |
2205 | ||
b331163b A |
2206 | log_verbose("inverse Bidi: testInverse(L) with %u test cases ---\n", UPRV_LENGTHOF(testCases)); |
2207 | for(i=0; i<UPRV_LENGTHOF(testCases); ++i) { | |
46f4442e | 2208 | log_verbose("Testing case %d\n", i); |
b75a7d8f | 2209 | errorCode=U_ZERO_ERROR; |
46f4442e | 2210 | _testInverseBidi(pBiDi, testCases[i].s, testCases[i].length, 0, &errorCode); |
b75a7d8f A |
2211 | } |
2212 | ||
b331163b A |
2213 | log_verbose("inverse Bidi: testInverse(R) with %u test cases ---\n", UPRV_LENGTHOF(testCases)); |
2214 | for(i=0; i<UPRV_LENGTHOF(testCases); ++i) { | |
46f4442e | 2215 | log_verbose("Testing case %d\n", i); |
b75a7d8f | 2216 | errorCode=U_ZERO_ERROR; |
46f4442e | 2217 | _testInverseBidi(pBiDi, testCases[i].s, testCases[i].length, 1, &errorCode); |
b75a7d8f A |
2218 | } |
2219 | ||
46f4442e A |
2220 | _testManyInverseBidi(pBiDi, 0); |
2221 | _testManyInverseBidi(pBiDi, 1); | |
b75a7d8f A |
2222 | |
2223 | ubidi_close(pBiDi); | |
2224 | ||
46f4442e A |
2225 | log_verbose("inverse Bidi: rountrips: %5u\nnon-roundtrips: %5u\n", countRoundtrips, countNonRoundtrips); |
2226 | ||
2227 | _testWriteReverse(); | |
2228 | ||
2229 | _testManyAddedPoints(); | |
2230 | ||
2231 | _testMisc(); | |
b75a7d8f | 2232 | |
46f4442e | 2233 | log_verbose("\nExiting TestInverse\n\n"); |
b75a7d8f A |
2234 | } |
2235 | ||
2236 | #define COUNT_REPEAT_SEGMENTS 6 | |
2237 | ||
2238 | static const UChar repeatSegments[COUNT_REPEAT_SEGMENTS][2]={ | |
2239 | { 0x61, 0x62 }, /* L */ | |
2240 | { 0x5d0, 0x5d1 }, /* R */ | |
2241 | { 0x627, 0x628 }, /* AL */ | |
2242 | { 0x31, 0x32 }, /* EN */ | |
2243 | { 0x661, 0x662 }, /* AN */ | |
2244 | { 0x20, 0x20 } /* WS (N) */ | |
2245 | }; | |
2246 | ||
2247 | static void | |
46f4442e | 2248 | _testManyInverseBidi(UBiDi *pBiDi, UBiDiLevel direction) { |
73c04bcf | 2249 | UChar text[8]={ 0, 0, 0x20, 0, 0, 0x20, 0, 0 }; |
b75a7d8f A |
2250 | int i, j, k; |
2251 | UErrorCode errorCode; | |
2252 | ||
46f4442e A |
2253 | log_verbose("inverse Bidi: testManyInverseBidi(%c) - test permutations of text snippets ---\n", |
2254 | direction==0 ? 'L' : 'R'); | |
b75a7d8f A |
2255 | for(i=0; i<COUNT_REPEAT_SEGMENTS; ++i) { |
2256 | text[0]=repeatSegments[i][0]; | |
2257 | text[1]=repeatSegments[i][1]; | |
2258 | for(j=0; j<COUNT_REPEAT_SEGMENTS; ++j) { | |
2259 | text[3]=repeatSegments[j][0]; | |
2260 | text[4]=repeatSegments[j][1]; | |
2261 | for(k=0; k<COUNT_REPEAT_SEGMENTS; ++k) { | |
2262 | text[6]=repeatSegments[k][0]; | |
2263 | text[7]=repeatSegments[k][1]; | |
2264 | ||
2265 | errorCode=U_ZERO_ERROR; | |
46f4442e A |
2266 | log_verbose("inverse Bidi: testManyInverseBidi()[%u %u %u]\n", i, j, k); |
2267 | _testInverseBidi(pBiDi, text, 8, direction, &errorCode); | |
b75a7d8f A |
2268 | } |
2269 | } | |
2270 | } | |
2271 | } | |
2272 | ||
2273 | static void | |
46f4442e | 2274 | _testInverseBidi(UBiDi *pBiDi, const UChar *src, int32_t srcLength, |
73c04bcf A |
2275 | UBiDiLevel direction, UErrorCode *pErrorCode) { |
2276 | UChar visualLTR[MAXLEN], logicalDest[MAXLEN], visualDest[MAXLEN]; | |
b75a7d8f A |
2277 | int32_t ltrLength, logicalLength, visualLength; |
2278 | ||
2279 | if(direction==0) { | |
46f4442e | 2280 | log_verbose("inverse Bidi: testInverse(L)\n"); |
b75a7d8f A |
2281 | |
2282 | /* convert visual to logical */ | |
2283 | ubidi_setInverse(pBiDi, TRUE); | |
73c04bcf A |
2284 | if (!ubidi_isInverse(pBiDi)) { |
2285 | log_err("Error while doing ubidi_setInverse(TRUE)\n"); | |
2286 | } | |
b75a7d8f | 2287 | ubidi_setPara(pBiDi, src, srcLength, 0, NULL, pErrorCode); |
73c04bcf A |
2288 | if (src != ubidi_getText(pBiDi)) { |
2289 | log_err("Wrong value returned by ubidi_getText\n"); | |
2290 | } | |
b331163b | 2291 | logicalLength=ubidi_writeReordered(pBiDi, logicalDest, UPRV_LENGTHOF(logicalDest), |
b75a7d8f A |
2292 | UBIDI_DO_MIRRORING|UBIDI_INSERT_LRM_FOR_NUMERIC, pErrorCode); |
2293 | log_verbose(" v "); | |
2294 | printUnicode(src, srcLength, ubidi_getLevels(pBiDi, pErrorCode)); | |
2295 | log_verbose("\n"); | |
2296 | ||
2297 | /* convert back to visual LTR */ | |
2298 | ubidi_setInverse(pBiDi, FALSE); | |
73c04bcf A |
2299 | if (ubidi_isInverse(pBiDi)) { |
2300 | log_err("Error while doing ubidi_setInverse(FALSE)\n"); | |
2301 | } | |
b75a7d8f | 2302 | ubidi_setPara(pBiDi, logicalDest, logicalLength, 0, NULL, pErrorCode); |
b331163b | 2303 | visualLength=ubidi_writeReordered(pBiDi, visualDest, UPRV_LENGTHOF(visualDest), |
b75a7d8f A |
2304 | UBIDI_DO_MIRRORING|UBIDI_REMOVE_BIDI_CONTROLS, pErrorCode); |
2305 | } else { | |
46f4442e | 2306 | log_verbose("inverse Bidi: testInverse(R)\n"); |
b75a7d8f A |
2307 | |
2308 | /* reverse visual from RTL to LTR */ | |
b331163b | 2309 | ltrLength=ubidi_writeReverse(src, srcLength, visualLTR, UPRV_LENGTHOF(visualLTR), 0, pErrorCode); |
b75a7d8f A |
2310 | log_verbose(" vr"); |
2311 | printUnicode(src, srcLength, NULL); | |
2312 | log_verbose("\n"); | |
2313 | ||
2314 | /* convert visual RTL to logical */ | |
2315 | ubidi_setInverse(pBiDi, TRUE); | |
2316 | ubidi_setPara(pBiDi, visualLTR, ltrLength, 0, NULL, pErrorCode); | |
b331163b | 2317 | logicalLength=ubidi_writeReordered(pBiDi, logicalDest, UPRV_LENGTHOF(logicalDest), |
b75a7d8f A |
2318 | UBIDI_DO_MIRRORING|UBIDI_INSERT_LRM_FOR_NUMERIC, pErrorCode); |
2319 | log_verbose(" vl"); | |
2320 | printUnicode(visualLTR, ltrLength, ubidi_getLevels(pBiDi, pErrorCode)); | |
2321 | log_verbose("\n"); | |
2322 | ||
2323 | /* convert back to visual RTL */ | |
2324 | ubidi_setInverse(pBiDi, FALSE); | |
2325 | ubidi_setPara(pBiDi, logicalDest, logicalLength, 0, NULL, pErrorCode); | |
b331163b | 2326 | visualLength=ubidi_writeReordered(pBiDi, visualDest, UPRV_LENGTHOF(visualDest), |
b75a7d8f A |
2327 | UBIDI_DO_MIRRORING|UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_OUTPUT_REVERSE, pErrorCode); |
2328 | } | |
2329 | log_verbose(" l "); | |
2330 | printUnicode(logicalDest, logicalLength, ubidi_getLevels(pBiDi, pErrorCode)); | |
2331 | log_verbose("\n"); | |
2332 | log_verbose(" v "); | |
2333 | printUnicode(visualDest, visualLength, NULL); | |
2334 | log_verbose("\n"); | |
2335 | ||
2336 | /* check and print results */ | |
2337 | if(U_FAILURE(*pErrorCode)) { | |
2338 | log_err("inverse BiDi: *** error %s\n" | |
2339 | " turn on verbose mode to see details\n", u_errorName(*pErrorCode)); | |
73c04bcf | 2340 | } else if(srcLength==visualLength && memcmp(src, visualDest, srcLength*U_SIZEOF_UCHAR)==0) { |
b75a7d8f A |
2341 | ++countRoundtrips; |
2342 | log_verbose(" + roundtripped\n"); | |
2343 | } else { | |
2344 | ++countNonRoundtrips; | |
2345 | log_verbose(" * did not roundtrip\n"); | |
2346 | log_err("inverse BiDi: transformation visual->logical->visual did not roundtrip the text;\n" | |
2347 | " turn on verbose mode to see details\n"); | |
2348 | } | |
2349 | } | |
2350 | ||
2351 | static void | |
46f4442e | 2352 | _testWriteReverse(void) { |
b75a7d8f A |
2353 | /* U+064e and U+0650 are combining marks (Mn) */ |
2354 | static const UChar forward[]={ | |
2355 | 0x200f, 0x627, 0x64e, 0x650, 0x20, 0x28, 0x31, 0x29 | |
2356 | }, reverseKeepCombining[]={ | |
2357 | 0x29, 0x31, 0x28, 0x20, 0x627, 0x64e, 0x650, 0x200f | |
2358 | }, reverseRemoveControlsKeepCombiningDoMirror[]={ | |
2359 | 0x28, 0x31, 0x29, 0x20, 0x627, 0x64e, 0x650 | |
2360 | }; | |
73c04bcf | 2361 | UChar reverse[10]; |
b75a7d8f A |
2362 | UErrorCode errorCode; |
2363 | int32_t length; | |
2364 | ||
2365 | /* test ubidi_writeReverse() with "interesting" options */ | |
2366 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2367 | length=ubidi_writeReverse(forward, UPRV_LENGTHOF(forward), |
2368 | reverse, UPRV_LENGTHOF(reverse), | |
b75a7d8f A |
2369 | UBIDI_KEEP_BASE_COMBINING, |
2370 | &errorCode); | |
b331163b | 2371 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(reverseKeepCombining) || memcmp(reverse, reverseKeepCombining, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f | 2372 | log_err("failure in ubidi_writeReverse(UBIDI_KEEP_BASE_COMBINING): length=%d (should be %d), error code %s\n", |
b331163b | 2373 | length, UPRV_LENGTHOF(reverseKeepCombining), u_errorName(errorCode)); |
b75a7d8f A |
2374 | } |
2375 | ||
b331163b | 2376 | memset(reverse, 0xa5, UPRV_LENGTHOF(reverse)*U_SIZEOF_UCHAR); |
b75a7d8f | 2377 | errorCode=U_ZERO_ERROR; |
b331163b A |
2378 | length=ubidi_writeReverse(forward, UPRV_LENGTHOF(forward), |
2379 | reverse, UPRV_LENGTHOF(reverse), | |
b75a7d8f A |
2380 | UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING, |
2381 | &errorCode); | |
b331163b | 2382 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror) || memcmp(reverse, reverseRemoveControlsKeepCombiningDoMirror, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2383 | log_err("failure in ubidi_writeReverse(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING):\n" |
2384 | " length=%d (should be %d), error code %s\n", | |
b331163b | 2385 | length, UPRV_LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror), u_errorName(errorCode)); |
b75a7d8f A |
2386 | } |
2387 | } | |
2388 | ||
46f4442e A |
2389 | static void _testManyAddedPoints(void) { |
2390 | UErrorCode errorCode = U_ZERO_ERROR; | |
2391 | UBiDi *bidi = ubidi_open(); | |
2392 | UChar text[90], dest[MAXLEN], expected[120]; | |
2393 | int destLen, i; | |
b331163b | 2394 | for (i = 0; i < UPRV_LENGTHOF(text); i+=3) { |
46f4442e A |
2395 | text[i] = 0x0061; /* 'a' */ |
2396 | text[i+1] = 0x05d0; | |
2397 | text[i+2] = 0x0033; /* '3' */ | |
2398 | } | |
2399 | ubidi_setReorderingMode(bidi, UBIDI_REORDER_INVERSE_LIKE_DIRECT); | |
2400 | ubidi_setReorderingOptions(bidi, UBIDI_OPTION_INSERT_MARKS); | |
b331163b | 2401 | ubidi_setPara(bidi, text, UPRV_LENGTHOF(text), UBIDI_LTR, NULL, &errorCode); |
46f4442e | 2402 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, 0, &errorCode); |
b331163b | 2403 | for (i = 0; i < UPRV_LENGTHOF(expected); i+=4) { |
46f4442e A |
2404 | expected[i] = 0x0061; /* 'a' */ |
2405 | expected[i+1] = 0x05d0; | |
2406 | expected[i+2] = 0x200e; | |
2407 | expected[i+3] = 0x0033; /* '3' */ | |
2408 | } | |
2409 | if (memcmp(dest, expected, destLen * sizeof(UChar))) { | |
2410 | log_err("\nInvalid output with many added points, " | |
2411 | "expected '%s', got '%s'\n", | |
b331163b | 2412 | aescstrdup(expected, UPRV_LENGTHOF(expected)), |
46f4442e A |
2413 | aescstrdup(dest, destLen)); |
2414 | } | |
2415 | ubidi_close(bidi); | |
2416 | } | |
2417 | ||
2418 | static void _testMisc(void) { | |
2419 | UErrorCode errorCode = U_ZERO_ERROR; | |
2420 | UBiDi *bidi = ubidi_open(); | |
2421 | UChar src[3], dest[MAXLEN], expected[5]; | |
2422 | int destLen; | |
2423 | ubidi_setInverse(bidi, TRUE); | |
2424 | src[0] = src[1] = src[2] = 0x0020; | |
b331163b | 2425 | ubidi_setPara(bidi, src, UPRV_LENGTHOF(src), UBIDI_RTL, NULL, &errorCode); |
46f4442e A |
2426 | destLen = ubidi_writeReordered(bidi, dest, MAXLEN, |
2427 | UBIDI_OUTPUT_REVERSE | UBIDI_INSERT_LRM_FOR_NUMERIC, | |
2428 | &errorCode); | |
2429 | u_unescape("\\u200f \\u200f", expected, 5); | |
2430 | if (memcmp(dest, expected, destLen * sizeof(UChar))) { | |
2431 | log_err("\nInvalid output with RLM at both sides, " | |
2432 | "expected '%s', got '%s'\n", | |
b331163b | 2433 | aescstrdup(expected, UPRV_LENGTHOF(expected)), |
46f4442e A |
2434 | aescstrdup(dest, destLen)); |
2435 | } | |
2436 | ubidi_close(bidi); | |
2437 | } | |
2438 | ||
b75a7d8f A |
2439 | /* arabic shaping ----------------------------------------------------------- */ |
2440 | ||
2441 | static void | |
46f4442e | 2442 | doArabicShapingTest(void) { |
b75a7d8f A |
2443 | static const UChar |
2444 | source[]={ | |
2445 | 0x31, /* en:1 */ | |
2446 | 0x627, /* arabic:alef */ | |
2447 | 0x32, /* en:2 */ | |
2448 | 0x6f3, /* an:3 */ | |
2449 | 0x61, /* latin:a */ | |
2450 | 0x34, /* en:4 */ | |
2451 | 0 | |
2452 | }, en2an[]={ | |
2453 | 0x661, 0x627, 0x662, 0x6f3, 0x61, 0x664, 0 | |
2454 | }, an2en[]={ | |
2455 | 0x31, 0x627, 0x32, 0x33, 0x61, 0x34, 0 | |
2456 | }, logical_alen2an_init_lr[]={ | |
2457 | 0x31, 0x627, 0x662, 0x6f3, 0x61, 0x34, 0 | |
2458 | }, logical_alen2an_init_al[]={ | |
2459 | 0x6f1, 0x627, 0x6f2, 0x6f3, 0x61, 0x34, 0 | |
2460 | }, reverse_alen2an_init_lr[]={ | |
2461 | 0x661, 0x627, 0x32, 0x6f3, 0x61, 0x34, 0 | |
2462 | }, reverse_alen2an_init_al[]={ | |
2463 | 0x6f1, 0x627, 0x32, 0x6f3, 0x61, 0x6f4, 0 | |
729e4ab9 A |
2464 | }, lamalef[]={ |
2465 | 0xfefb, 0 | |
b75a7d8f A |
2466 | }; |
2467 | UChar dest[8]; | |
2468 | UErrorCode errorCode; | |
2469 | int32_t length; | |
2470 | ||
2471 | /* test number shaping */ | |
2472 | ||
2473 | /* european->arabic */ | |
2474 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2475 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2476 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2477 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, |
2478 | &errorCode); | |
b331163b | 2479 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(source) || memcmp(dest, en2an, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2480 | log_err("failure in u_shapeArabic(en2an)\n"); |
2481 | } | |
2482 | ||
2483 | /* arabic->european */ | |
2484 | errorCode=U_ZERO_ERROR; | |
2485 | length=u_shapeArabic(source, -1, | |
b331163b | 2486 | dest, UPRV_LENGTHOF(dest), |
b75a7d8f A |
2487 | U_SHAPE_DIGITS_AN2EN|U_SHAPE_DIGIT_TYPE_AN_EXTENDED, |
2488 | &errorCode); | |
73c04bcf | 2489 | if(U_FAILURE(errorCode) || length!=u_strlen(source) || memcmp(dest, an2en, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2490 | log_err("failure in u_shapeArabic(an2en)\n"); |
2491 | } | |
2492 | ||
2493 | /* european->arabic with context, logical order, initial state not AL */ | |
2494 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2495 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2496 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2497 | U_SHAPE_DIGITS_ALEN2AN_INIT_LR|U_SHAPE_DIGIT_TYPE_AN, |
2498 | &errorCode); | |
b331163b | 2499 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(source) || memcmp(dest, logical_alen2an_init_lr, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2500 | log_err("failure in u_shapeArabic(logical_alen2an_init_lr)\n"); |
2501 | } | |
2502 | ||
2503 | /* european->arabic with context, logical order, initial state AL */ | |
2504 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2505 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2506 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2507 | U_SHAPE_DIGITS_ALEN2AN_INIT_AL|U_SHAPE_DIGIT_TYPE_AN_EXTENDED, |
2508 | &errorCode); | |
b331163b | 2509 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(source) || memcmp(dest, logical_alen2an_init_al, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2510 | log_err("failure in u_shapeArabic(logical_alen2an_init_al)\n"); |
2511 | } | |
2512 | ||
2513 | /* european->arabic with context, reverse order, initial state not AL */ | |
2514 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2515 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2516 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2517 | U_SHAPE_DIGITS_ALEN2AN_INIT_LR|U_SHAPE_DIGIT_TYPE_AN|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, |
2518 | &errorCode); | |
b331163b | 2519 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(source) || memcmp(dest, reverse_alen2an_init_lr, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2520 | log_err("failure in u_shapeArabic(reverse_alen2an_init_lr)\n"); |
2521 | } | |
2522 | ||
2523 | /* european->arabic with context, reverse order, initial state AL */ | |
2524 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2525 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2526 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2527 | U_SHAPE_DIGITS_ALEN2AN_INIT_AL|U_SHAPE_DIGIT_TYPE_AN_EXTENDED|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, |
2528 | &errorCode); | |
b331163b | 2529 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(source) || memcmp(dest, reverse_alen2an_init_al, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2530 | log_err("failure in u_shapeArabic(reverse_alen2an_init_al)\n"); |
2531 | } | |
2532 | ||
2533 | /* test noop */ | |
2534 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2535 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2536 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2537 | 0, |
2538 | &errorCode); | |
b331163b | 2539 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(source) || memcmp(dest, source, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2540 | log_err("failure in u_shapeArabic(noop)\n"); |
2541 | } | |
2542 | ||
2543 | errorCode=U_ZERO_ERROR; | |
2544 | length=u_shapeArabic(source, 0, | |
b331163b | 2545 | dest, UPRV_LENGTHOF(dest), |
b75a7d8f A |
2546 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, |
2547 | &errorCode); | |
2548 | if(U_FAILURE(errorCode) || length!=0) { | |
b331163b | 2549 | log_err("failure in u_shapeArabic(en2an, sourceLength=0), returned %d/%s\n", u_errorName(errorCode), UPRV_LENGTHOF(source)); |
b75a7d8f A |
2550 | } |
2551 | ||
2552 | /* preflight digit shaping */ | |
2553 | errorCode=U_ZERO_ERROR; | |
b331163b | 2554 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
b75a7d8f A |
2555 | NULL, 0, |
2556 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, | |
2557 | &errorCode); | |
b331163b | 2558 | if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=UPRV_LENGTHOF(source)) { |
b75a7d8f | 2559 | log_err("failure in u_shapeArabic(en2an preflighting), returned %d/%s instead of %d/U_BUFFER_OVERFLOW_ERROR\n", |
b331163b | 2560 | length, u_errorName(errorCode), UPRV_LENGTHOF(source)); |
b75a7d8f A |
2561 | } |
2562 | ||
2563 | /* test illegal arguments */ | |
2564 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2565 | length=u_shapeArabic(NULL, UPRV_LENGTHOF(source), |
2566 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2567 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, |
2568 | &errorCode); | |
2569 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
2570 | log_err("failure in u_shapeArabic(source=NULL), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode)); | |
2571 | } | |
2572 | ||
2573 | errorCode=U_ZERO_ERROR; | |
2574 | length=u_shapeArabic(source, -2, | |
b331163b | 2575 | dest, UPRV_LENGTHOF(dest), |
b75a7d8f A |
2576 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, |
2577 | &errorCode); | |
2578 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
2579 | log_err("failure in u_shapeArabic(sourceLength=-2), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode)); | |
2580 | } | |
2581 | ||
2582 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2583 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2584 | NULL, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2585 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, |
2586 | &errorCode); | |
2587 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
2588 | log_err("failure in u_shapeArabic(dest=NULL), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode)); | |
2589 | } | |
2590 | ||
2591 | errorCode=U_ZERO_ERROR; | |
b331163b | 2592 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
b75a7d8f A |
2593 | dest, -1, |
2594 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, | |
2595 | &errorCode); | |
2596 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
2597 | log_err("failure in u_shapeArabic(destSize=-1), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode)); | |
2598 | } | |
2599 | ||
2600 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2601 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2602 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2603 | U_SHAPE_DIGITS_RESERVED|U_SHAPE_DIGIT_TYPE_AN, |
2604 | &errorCode); | |
2605 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
2606 | log_err("failure in u_shapeArabic(U_SHAPE_DIGITS_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode)); | |
2607 | } | |
2608 | ||
2609 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2610 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2611 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2612 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_RESERVED, |
2613 | &errorCode); | |
2614 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
2615 | log_err("failure in u_shapeArabic(U_SHAPE_DIGIT_TYPE_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode)); | |
2616 | } | |
2617 | ||
2618 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2619 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2620 | (UChar *)(source+2), UPRV_LENGTHOF(dest), /* overlap source and destination */ | |
b75a7d8f A |
2621 | U_SHAPE_DIGITS_EN2AN|U_SHAPE_DIGIT_TYPE_AN, |
2622 | &errorCode); | |
2623 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
2624 | log_err("failure in u_shapeArabic(U_SHAPE_DIGIT_TYPE_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode)); | |
2625 | } | |
729e4ab9 A |
2626 | |
2627 | errorCode=U_ZERO_ERROR; | |
b331163b A |
2628 | length=u_shapeArabic(lamalef, UPRV_LENGTHOF(lamalef), |
2629 | dest, UPRV_LENGTHOF(dest), | |
729e4ab9 A |
2630 | U_SHAPE_LETTERS_UNSHAPE | U_SHAPE_LENGTH_GROW_SHRINK | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, |
2631 | &errorCode); | |
b331163b | 2632 | if(U_FAILURE(errorCode) || length == UPRV_LENGTHOF(lamalef)) { |
729e4ab9 A |
2633 | log_err("failure in u_shapeArabic(U_SHAPE_LETTERS_UNSHAPE | U_SHAPE_LENGTH_GROW_SHRINK | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR)\n"); |
2634 | log_err("returned %s instead of U_ZERO_ERROR or returned length %d instead of 3\n", u_errorName(errorCode), length); | |
2635 | } | |
b75a7d8f A |
2636 | } |
2637 | ||
2638 | static void | |
46f4442e | 2639 | doLamAlefSpecialVLTRArabicShapingTest(void) { |
b75a7d8f A |
2640 | static const UChar |
2641 | source[]={ | |
2642 | /*a*/ 0x20 ,0x646,0x622,0x644,0x627,0x20, | |
2643 | /*b*/ 0x646,0x623,0x64E,0x644,0x627,0x20, | |
2644 | /*c*/ 0x646,0x627,0x670,0x644,0x627,0x20, | |
2645 | /*d*/ 0x646,0x622,0x653,0x644,0x627,0x20, | |
2646 | /*e*/ 0x646,0x625,0x655,0x644,0x627,0x20, | |
2647 | /*f*/ 0x646,0x622,0x654,0x644,0x627,0x20, | |
2648 | /*g*/ 0xFEFC,0x639 | |
2649 | }, shape_near[]={ | |
2650 | 0x20,0xfee5,0x20,0xfef5,0xfe8d,0x20,0xfee5,0x20,0xfe76,0xfef7,0xfe8d,0x20, | |
2651 | 0xfee5,0x20,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x20,0x653,0xfef5,0xfe8d,0x20, | |
2652 | 0xfee5,0x20,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x20,0x654,0xfef5,0xfe8d,0x20, | |
2653 | 0xfefc,0xfecb | |
2654 | }, shape_at_end[]={ | |
2655 | 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,0x670, | |
2656 | 0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,0xfe8d, | |
2657 | 0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb,0x20,0x20,0x20,0x20,0x20,0x20 | |
2658 | }, shape_at_begin[]={ | |
2659 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76, | |
2660 | 0xfef7,0xfe8d,0x20,0xfee5,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d, | |
2661 | 0x20,0xfee5,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb | |
2662 | }, shape_grow_shrink[]={ | |
2663 | 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5, | |
2664 | 0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9, | |
2665 | 0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb | |
2666 | }, shape_excepttashkeel_near[]={ | |
2667 | 0x20,0xfee5,0x20,0xfef5,0xfe8d,0x20,0xfee5,0x20,0xfe76,0xfef7,0xfe8d,0x20, | |
2668 | 0xfee5,0x20,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x20,0x653,0xfef5,0xfe8d,0x20, | |
2669 | 0xfee5,0x20,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x20,0x654,0xfef5,0xfe8d,0x20, | |
2670 | 0xfefc,0xfecb | |
2671 | }, shape_excepttashkeel_at_end[]={ | |
2672 | 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5, | |
2673 | 0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9, | |
2674 | 0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb,0x20,0x20,0x20, | |
2675 | 0x20,0x20,0x20 | |
2676 | }, shape_excepttashkeel_at_begin[]={ | |
2677 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76, | |
2678 | 0xfef7,0xfe8d,0x20,0xfee5,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d, | |
2679 | 0x20,0xfee5,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb | |
2680 | }, shape_excepttashkeel_grow_shrink[]={ | |
2681 | 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,0x670, | |
2682 | 0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,0xfe8d, | |
2683 | 0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb | |
2684 | }; | |
2685 | ||
2686 | UChar dest[38]; | |
2687 | UErrorCode errorCode; | |
2688 | int32_t length; | |
2689 | ||
2690 | errorCode=U_ZERO_ERROR; | |
2691 | ||
b331163b A |
2692 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2693 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2694 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_LENGTH_FIXED_SPACES_NEAR| |
2695 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2696 | &errorCode); | |
2697 | ||
b331163b | 2698 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_near) || memcmp(dest, shape_near, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2699 | log_err("failure in u_shapeArabic(LAMALEF shape_near)\n"); |
2700 | } | |
2701 | ||
2702 | errorCode=U_ZERO_ERROR; | |
2703 | ||
b331163b A |
2704 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2705 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2706 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_LENGTH_FIXED_SPACES_AT_END| |
2707 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2708 | &errorCode); | |
2709 | ||
b331163b | 2710 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_at_end) || memcmp(dest, shape_at_end, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2711 | log_err("failure in u_shapeArabic(LAMALEF shape_at_end)\n"); |
2712 | } | |
2713 | ||
2714 | errorCode=U_ZERO_ERROR; | |
2715 | ||
b331163b A |
2716 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2717 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2718 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING| |
2719 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2720 | &errorCode); | |
2721 | ||
b331163b | 2722 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_at_begin) || memcmp(dest, shape_at_begin, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2723 | log_err("failure in u_shapeArabic(LAMALEF shape_at_begin)\n"); |
2724 | } | |
2725 | ||
2726 | errorCode=U_ZERO_ERROR; | |
2727 | ||
b331163b A |
2728 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2729 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2730 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_LENGTH_GROW_SHRINK| |
2731 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2732 | &errorCode); | |
2733 | ||
73c04bcf | 2734 | if(U_FAILURE(errorCode) || memcmp(dest, shape_grow_shrink, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2735 | log_err("failure in u_shapeArabic(LAMALEF shape_grow_shrink)\n"); |
2736 | } | |
2737 | ||
2738 | /* ==================== U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED ==================== */ | |
2739 | ||
2740 | errorCode=U_ZERO_ERROR; | |
2741 | ||
b331163b A |
2742 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2743 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2744 | U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED|U_SHAPE_LENGTH_FIXED_SPACES_NEAR| |
2745 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2746 | &errorCode); | |
2747 | ||
b331163b | 2748 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_excepttashkeel_near) || memcmp(dest, shape_excepttashkeel_near, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2749 | log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_near)\n"); |
2750 | } | |
2751 | ||
2752 | errorCode=U_ZERO_ERROR; | |
2753 | ||
b331163b A |
2754 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2755 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2756 | U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED|U_SHAPE_LENGTH_FIXED_SPACES_AT_END| |
2757 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2758 | &errorCode); | |
2759 | ||
b331163b | 2760 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_excepttashkeel_at_end) || memcmp(dest,shape_excepttashkeel_at_end , length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2761 | log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_at_end)\n"); |
2762 | } | |
2763 | ||
2764 | errorCode=U_ZERO_ERROR; | |
2765 | ||
b331163b A |
2766 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2767 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2768 | U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING| |
2769 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2770 | &errorCode); | |
2771 | ||
b331163b | 2772 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_excepttashkeel_at_begin) || memcmp(dest, shape_excepttashkeel_at_begin, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2773 | log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_at_begin)\n"); |
2774 | } | |
2775 | ||
2776 | errorCode=U_ZERO_ERROR; | |
2777 | ||
b331163b A |
2778 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2779 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2780 | U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED|U_SHAPE_LENGTH_GROW_SHRINK| |
2781 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2782 | &errorCode); | |
2783 | ||
73c04bcf | 2784 | if(U_FAILURE(errorCode) || memcmp(dest, shape_excepttashkeel_grow_shrink, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2785 | log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_grow_shrink)\n"); |
2786 | } | |
2787 | } | |
2788 | ||
2789 | static void | |
46f4442e | 2790 | doTashkeelSpecialVLTRArabicShapingTest(void) { |
b75a7d8f A |
2791 | static const UChar |
2792 | source[]={ | |
2793 | 0x64A,0x628,0x631,0x639,0x20, | |
2794 | 0x64A,0x628,0x651,0x631,0x64E,0x639,0x20, | |
2795 | 0x64C,0x64A,0x628,0x631,0x64F,0x639,0x20, | |
2796 | 0x628,0x670,0x631,0x670,0x639,0x20, | |
2797 | 0x628,0x653,0x631,0x653,0x639,0x20, | |
2798 | 0x628,0x654,0x631,0x654,0x639,0x20, | |
2799 | 0x628,0x655,0x631,0x655,0x639,0x20, | |
2800 | }, shape_near[]={ | |
2801 | 0xfef2,0xfe91,0xfeae,0xfecb,0x20,0xfef2,0xfe91,0xfe7c,0xfeae,0xfe77,0xfecb, | |
2802 | 0x20,0xfe72,0xfef2,0xfe91,0xfeae,0xfe79,0xfecb,0x20,0xfe8f,0x670,0xfeae,0x670, | |
2803 | 0xfecb,0x20,0xfe8f,0x653,0xfeae,0x653,0xfecb,0x20,0xfe8f,0x654,0xfeae,0x654, | |
2804 | 0xfecb,0x20,0xfe8f,0x655,0xfeae,0x655,0xfecb,0x20 | |
2805 | }, shape_excepttashkeel_near[]={ | |
2806 | 0xfef2,0xfe91,0xfeae,0xfecb,0x20,0xfef2,0xfe91,0xfe7c,0xfeae,0xfe76,0xfecb,0x20, | |
2807 | 0xfe72,0xfef2,0xfe91,0xfeae,0xfe78,0xfecb,0x20,0xfe8f,0x670,0xfeae,0x670,0xfecb, | |
2808 | 0x20,0xfe8f,0x653,0xfeae,0x653,0xfecb,0x20,0xfe8f,0x654,0xfeae,0x654,0xfecb,0x20, | |
2809 | 0xfe8f,0x655,0xfeae,0x655,0xfecb,0x20 | |
2810 | }; | |
2811 | ||
2812 | UChar dest[43]; | |
2813 | UErrorCode errorCode; | |
2814 | int32_t length; | |
2815 | ||
2816 | errorCode=U_ZERO_ERROR; | |
2817 | ||
b331163b A |
2818 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2819 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2820 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_LENGTH_FIXED_SPACES_NEAR| |
2821 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2822 | &errorCode); | |
2823 | ||
b331163b | 2824 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_near) || memcmp(dest, shape_near, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2825 | log_err("failure in u_shapeArabic(TASHKEEL shape_near)\n"); |
2826 | } | |
2827 | ||
2828 | errorCode=U_ZERO_ERROR; | |
2829 | ||
b331163b A |
2830 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2831 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2832 | U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED|U_SHAPE_LENGTH_FIXED_SPACES_NEAR| |
2833 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
2834 | &errorCode); | |
2835 | ||
b331163b | 2836 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(shape_excepttashkeel_near) || memcmp(dest, shape_excepttashkeel_near, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2837 | log_err("failure in u_shapeArabic(TASHKEEL shape_excepttashkeel_near)\n"); |
2838 | } | |
2839 | } | |
2840 | ||
2841 | static void | |
46f4442e | 2842 | doLOGICALArabicDeShapingTest(void) { |
b75a7d8f A |
2843 | static const UChar |
2844 | source[]={ | |
2845 | 0x0020,0x0020,0x0020,0xFE8D,0xFEF5,0x0020,0xFEE5,0x0020,0xFE8D,0xFEF7,0x0020, | |
2846 | 0xFED7,0xFEFC,0x0020,0xFEE1,0x0020,0xFE8D,0xFEDF,0xFECC,0xFEAE,0xFE91,0xFEF4, | |
2847 | 0xFE94,0x0020,0xFE8D,0xFEDF,0xFEA4,0xFEAE,0xFE93,0x0020,0x0020,0x0020,0x0020 | |
2848 | }, unshape_near[]={ | |
2849 | 0x20,0x20,0x20,0x627,0x644,0x622,0x646,0x20,0x627,0x644,0x623,0x642,0x644,0x627, | |
2850 | 0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,0x644,0x62d,0x631, | |
2851 | 0x629,0x20,0x20,0x20,0x20 | |
2852 | }, unshape_at_end[]={ | |
2853 | 0x20,0x20,0x20,0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642, | |
2854 | 0x644,0x627,0x20,0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627, | |
2855 | 0x644,0x62d,0x631,0x629,0x20 | |
2856 | }, unshape_at_begin[]={ | |
2857 | 0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642,0x644,0x627,0x20, | |
2858 | 0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,0x644,0x62d,0x631, | |
2859 | 0x629,0x20,0x20,0x20,0x20 | |
2860 | }, unshape_grow_shrink[]={ | |
2861 | 0x20,0x20,0x20,0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642, | |
2862 | 0x644,0x627,0x20,0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627, | |
2863 | 0x644,0x62d,0x631,0x629,0x20,0x20,0x20,0x20 | |
2864 | }; | |
2865 | ||
2866 | UChar dest[36]; | |
2867 | UErrorCode errorCode; | |
2868 | int32_t length; | |
2869 | ||
2870 | errorCode=U_ZERO_ERROR; | |
2871 | ||
b331163b A |
2872 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2873 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2874 | U_SHAPE_LETTERS_UNSHAPE|U_SHAPE_LENGTH_FIXED_SPACES_NEAR| |
2875 | U_SHAPE_TEXT_DIRECTION_LOGICAL, | |
2876 | &errorCode); | |
2877 | ||
b331163b | 2878 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(unshape_near) || memcmp(dest, unshape_near, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2879 | log_err("failure in u_shapeArabic(unshape_near)\n"); |
2880 | } | |
2881 | ||
2882 | errorCode=U_ZERO_ERROR; | |
2883 | ||
b331163b A |
2884 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2885 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2886 | U_SHAPE_LETTERS_UNSHAPE|U_SHAPE_LENGTH_FIXED_SPACES_AT_END| |
2887 | U_SHAPE_TEXT_DIRECTION_LOGICAL, | |
2888 | &errorCode); | |
2889 | ||
b331163b | 2890 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(unshape_at_end) || memcmp(dest, unshape_at_end, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2891 | log_err("failure in u_shapeArabic(unshape_at_end)\n"); |
2892 | } | |
2893 | ||
2894 | errorCode=U_ZERO_ERROR; | |
2895 | ||
b331163b A |
2896 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2897 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2898 | U_SHAPE_LETTERS_UNSHAPE|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING| |
2899 | U_SHAPE_TEXT_DIRECTION_LOGICAL, | |
2900 | &errorCode); | |
2901 | ||
b331163b | 2902 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(unshape_at_begin) || memcmp(dest, unshape_at_begin, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2903 | log_err("failure in u_shapeArabic(unshape_at_begin)\n"); |
2904 | } | |
2905 | ||
2906 | errorCode=U_ZERO_ERROR; | |
2907 | ||
b331163b A |
2908 | length=u_shapeArabic(source, UPRV_LENGTHOF(source), |
2909 | dest, UPRV_LENGTHOF(dest), | |
b75a7d8f A |
2910 | U_SHAPE_LETTERS_UNSHAPE|U_SHAPE_LENGTH_GROW_SHRINK| |
2911 | U_SHAPE_TEXT_DIRECTION_LOGICAL, | |
2912 | &errorCode); | |
2913 | ||
73c04bcf | 2914 | if(U_FAILURE(errorCode) || memcmp(dest, unshape_grow_shrink, length*U_SIZEOF_UCHAR)!=0) { |
b75a7d8f A |
2915 | log_err("failure in u_shapeArabic(unshape_grow_shrink)\n"); |
2916 | } | |
2917 | ||
2918 | } | |
2919 | ||
4388f060 A |
2920 | static void |
2921 | doTailTest(void) { | |
2922 | static const UChar src[] = { 0x0020, 0x0633, 0 }; | |
2923 | static const UChar dst_old[] = { 0xFEB1, 0x200B,0 }; | |
2924 | static const UChar dst_new[] = { 0xFEB1, 0xFE73,0 }; | |
2925 | UChar dst[3] = { 0x0000, 0x0000,0 }; | |
2926 | int32_t length; | |
2927 | UErrorCode status; | |
57a6839d | 2928 | |
4388f060 A |
2929 | log_verbose("SRC: U+%04X U+%04X\n", src[0],src[1]); |
2930 | ||
2931 | log_verbose("Trying old tail\n"); | |
2932 | status = U_ZERO_ERROR; | |
b331163b | 2933 | length = u_shapeArabic(src, -1, dst, UPRV_LENGTHOF(dst), |
4388f060 A |
2934 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_SEEN_TWOCELL_NEAR, &status); |
2935 | if(U_FAILURE(status)) { | |
57a6839d | 2936 | log_err("Fail: status %s\n", u_errorName(status)); |
4388f060 A |
2937 | } else if(length!=2) { |
2938 | log_err("Fail: len %d expected 3\n", length); | |
b331163b | 2939 | } else if(u_strncmp(dst,dst_old,UPRV_LENGTHOF(dst))) { |
4388f060 A |
2940 | log_err("Fail: got U+%04X U+%04X expected U+%04X U+%04X\n", |
2941 | dst[0],dst[1],dst_old[0],dst_old[1]); | |
2942 | } else { | |
2943 | log_verbose("OK: U+%04X U+%04X len %d err %s\n", | |
2944 | dst[0],dst[1],length,u_errorName(status)); | |
2945 | } | |
2946 | ||
2947 | ||
2948 | log_verbose("Trying new tail\n"); | |
2949 | status = U_ZERO_ERROR; | |
b331163b | 2950 | length = u_shapeArabic(src, -1, dst, UPRV_LENGTHOF(dst), |
4388f060 A |
2951 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_SEEN_TWOCELL_NEAR|U_SHAPE_TAIL_NEW_UNICODE, &status); |
2952 | if(U_FAILURE(status)) { | |
57a6839d | 2953 | log_err("Fail: status %s\n", u_errorName(status)); |
4388f060 A |
2954 | } else if(length!=2) { |
2955 | log_err("Fail: len %d expected 3\n", length); | |
b331163b | 2956 | } else if(u_strncmp(dst,dst_new,UPRV_LENGTHOF(dst))) { |
4388f060 A |
2957 | log_err("Fail: got U+%04X U+%04X expected U+%04X U+%04X\n", |
2958 | dst[0],dst[1],dst_new[0],dst_new[1]); | |
2959 | } else { | |
2960 | log_verbose("OK: U+%04X U+%04X len %d err %s\n", | |
2961 | dst[0],dst[1],length,u_errorName(status)); | |
2962 | } | |
2963 | } | |
2964 | ||
46f4442e A |
2965 | static void |
2966 | doArabicShapingTestForBug5421(void) { | |
2967 | static const UChar | |
2968 | persian_letters_source[]={ | |
2969 | 0x0020, 0x0698, 0x067E, 0x0686, 0x06AF, 0x0020 | |
2970 | }, persian_letters[]={ | |
2971 | 0x0020, 0xFB8B, 0xFB59, 0xFB7D, 0xFB94, 0x0020 | |
2972 | }, tashkeel_aggregation_source[]={ | |
2973 | 0x0020, 0x0628, 0x0651, 0x064E, 0x062A, 0x0631, 0x0645, 0x0020, | |
2974 | 0x0628, 0x064E, 0x0651, 0x062A, 0x0631, 0x0645, 0x0020 | |
2975 | }, tashkeel_aggregation[]={ | |
2976 | 0x0020, 0xFE90, 0xFC60, 0xFE97, 0xFEAE, 0xFEE3, | |
2977 | 0x0020, 0xFE90, 0xFC60, 0xFE97, 0xFEAE, 0xFEE3, 0x0020 | |
2978 | }, untouched_presentation_source[]={ | |
2979 | 0x0020 ,0x0627, 0xfe90,0x0020 | |
2980 | }, untouched_presentation[]={ | |
2981 | 0x0020,0xfe8D, 0xfe90,0x0020 | |
2982 | }, untouched_presentation_r_source[]={ | |
2983 | 0x0020 ,0xfe90, 0x0627, 0x0020 | |
2984 | }, untouched_presentation_r[]={ | |
2985 | 0x0020, 0xfe90,0xfe8D,0x0020 | |
2986 | }; | |
2987 | ||
2988 | UChar dest[38]; | |
2989 | UErrorCode errorCode; | |
2990 | int32_t length; | |
2991 | ||
2992 | errorCode=U_ZERO_ERROR; | |
2993 | ||
b331163b A |
2994 | length=u_shapeArabic(persian_letters_source, UPRV_LENGTHOF(persian_letters_source), |
2995 | dest, UPRV_LENGTHOF(dest), | |
46f4442e A |
2996 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, |
2997 | &errorCode); | |
2998 | ||
b331163b | 2999 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(persian_letters) || memcmp(dest, persian_letters, length*U_SIZEOF_UCHAR)!=0) { |
46f4442e A |
3000 | log_err("failure in u_shapeArabic(persian_letters)\n"); |
3001 | } | |
3002 | ||
3003 | errorCode=U_ZERO_ERROR; | |
3004 | ||
b331163b A |
3005 | length=u_shapeArabic(tashkeel_aggregation_source, UPRV_LENGTHOF(tashkeel_aggregation_source), |
3006 | dest, UPRV_LENGTHOF(dest), | |
46f4442e A |
3007 | U_SHAPE_AGGREGATE_TASHKEEL|U_SHAPE_PRESERVE_PRESENTATION| |
3008 | U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
3009 | &errorCode); | |
3010 | ||
b331163b | 3011 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(tashkeel_aggregation) || memcmp(dest, tashkeel_aggregation, length*U_SIZEOF_UCHAR)!=0) { |
46f4442e A |
3012 | log_err("failure in u_shapeArabic(tashkeel_aggregation)\n"); |
3013 | } | |
3014 | ||
3015 | errorCode=U_ZERO_ERROR; | |
3016 | ||
b331163b A |
3017 | length=u_shapeArabic(untouched_presentation_source, UPRV_LENGTHOF(untouched_presentation_source), |
3018 | dest, UPRV_LENGTHOF(dest), | |
46f4442e A |
3019 | U_SHAPE_PRESERVE_PRESENTATION| |
3020 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, | |
3021 | &errorCode); | |
3022 | ||
b331163b | 3023 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(untouched_presentation) || memcmp(dest, untouched_presentation, length*U_SIZEOF_UCHAR)!=0) { |
46f4442e A |
3024 | log_err("failure in u_shapeArabic(untouched_presentation)\n"); |
3025 | } | |
3026 | ||
3027 | errorCode=U_ZERO_ERROR; | |
3028 | ||
b331163b A |
3029 | length=u_shapeArabic(untouched_presentation_r_source, UPRV_LENGTHOF(untouched_presentation_r_source), |
3030 | dest, UPRV_LENGTHOF(dest), | |
46f4442e A |
3031 | U_SHAPE_PRESERVE_PRESENTATION| |
3032 | U_SHAPE_LETTERS_SHAPE|U_SHAPE_TEXT_DIRECTION_LOGICAL, | |
3033 | &errorCode); | |
3034 | ||
b331163b | 3035 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(untouched_presentation_r) || memcmp(dest, untouched_presentation_r, length*U_SIZEOF_UCHAR)!=0) { |
46f4442e A |
3036 | log_err("failure in u_shapeArabic(untouched_presentation_r)\n"); |
3037 | } | |
3038 | } | |
3039 | ||
51004dcb A |
3040 | static void |
3041 | doArabicShapingTestForBug8703(void) { | |
3042 | static const UChar | |
3043 | letters_source1[]={ | |
3044 | 0x0634,0x0651,0x0645,0x0652,0x0633 | |
3045 | }, letters_source2[]={ | |
57a6839d | 3046 | 0x0634,0x0651,0x0645,0x0652,0x0633 |
51004dcb A |
3047 | }, letters_source3[]={ |
3048 | 0x0634,0x0651,0x0645,0x0652,0x0633 | |
3049 | }, letters_source4[]={ | |
57a6839d | 3050 | 0x0634,0x0651,0x0645,0x0652,0x0633 |
51004dcb A |
3051 | }, letters_source5[]={ |
3052 | 0x0633,0x0652,0x0645,0x0651,0x0634 | |
3053 | }, letters_source6[]={ | |
57a6839d | 3054 | 0x0633,0x0652,0x0645,0x0651,0x0634 |
51004dcb A |
3055 | }, letters_source7[]={ |
3056 | 0x0633,0x0652,0x0645,0x0651,0x0634 | |
3057 | }, letters_source8[]={ | |
3058 | 0x0633,0x0652,0x0645,0x0651,0x0634 | |
3059 | }, letters_dest1[]={ | |
57a6839d | 3060 | 0x0020,0xFEB7,0xFE7D,0xFEE4,0xFEB2 |
51004dcb A |
3061 | }, letters_dest2[]={ |
3062 | 0xFEB7,0xFE7D,0xFEE4,0xFEB2,0x0020 | |
3063 | }, letters_dest3[]={ | |
3064 | 0xFEB7,0xFE7D,0xFEE4,0xFEB2 | |
3065 | }, letters_dest4[]={ | |
3066 | 0xFEB7,0xFE7D,0xFEE4,0x0640,0xFEB2 | |
3067 | }, letters_dest5[]={ | |
57a6839d | 3068 | 0x0020,0xFEB2,0xFEE4,0xFE7D,0xFEB7 |
51004dcb A |
3069 | }, letters_dest6[]={ |
3070 | 0xFEB2,0xFEE4,0xFE7D,0xFEB7,0x0020 | |
3071 | }, letters_dest7[]={ | |
3072 | 0xFEB2,0xFEE4,0xFE7D,0xFEB7 | |
3073 | }, letters_dest8[]={ | |
3074 | 0xFEB2,0x0640,0xFEE4,0xFE7D,0xFEB7 | |
3075 | }; | |
3076 | ||
3077 | UChar dest[20]; | |
3078 | UErrorCode errorCode; | |
3079 | int32_t length; | |
3080 | ||
3081 | errorCode=U_ZERO_ERROR; | |
3082 | ||
b331163b A |
3083 | length=u_shapeArabic(letters_source1, UPRV_LENGTHOF(letters_source1), |
3084 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3085 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_BEGIN | U_SHAPE_LETTERS_SHAPE, |
3086 | &errorCode); | |
3087 | ||
b331163b | 3088 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest1) || memcmp(dest, letters_dest1, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3089 | log_err("failure in u_shapeArabic(letters_source1)\n"); |
3090 | } | |
3091 | ||
3092 | errorCode=U_ZERO_ERROR; | |
3093 | ||
b331163b A |
3094 | length=u_shapeArabic(letters_source2, UPRV_LENGTHOF(letters_source2), |
3095 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3096 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_END | U_SHAPE_LETTERS_SHAPE, |
3097 | &errorCode); | |
3098 | ||
b331163b | 3099 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest2) || memcmp(dest, letters_dest2, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3100 | log_err("failure in u_shapeArabic(letters_source2)\n"); |
3101 | } | |
3102 | ||
3103 | errorCode=U_ZERO_ERROR; | |
3104 | ||
b331163b A |
3105 | length=u_shapeArabic(letters_source3, UPRV_LENGTHOF(letters_source3), |
3106 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3107 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_RESIZE | U_SHAPE_LETTERS_SHAPE, |
3108 | &errorCode); | |
3109 | ||
b331163b | 3110 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest3) || memcmp(dest, letters_dest3, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3111 | log_err("failure in u_shapeArabic(letters_source3)\n"); |
3112 | } | |
3113 | ||
3114 | errorCode=U_ZERO_ERROR; | |
3115 | ||
b331163b A |
3116 | length=u_shapeArabic(letters_source4, UPRV_LENGTHOF(letters_source4), |
3117 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3118 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_REPLACE_BY_TATWEEL | U_SHAPE_LETTERS_SHAPE, |
3119 | &errorCode); | |
3120 | ||
b331163b | 3121 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest4) || memcmp(dest, letters_dest4, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3122 | log_err("failure in u_shapeArabic(letters_source4)\n"); |
3123 | } | |
3124 | ||
3125 | errorCode=U_ZERO_ERROR; | |
3126 | ||
b331163b A |
3127 | length=u_shapeArabic(letters_source5, UPRV_LENGTHOF(letters_source5), |
3128 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3129 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_TASHKEEL_BEGIN | U_SHAPE_LETTERS_SHAPE, |
3130 | &errorCode); | |
3131 | ||
b331163b | 3132 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest5) || memcmp(dest, letters_dest5, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3133 | log_err("failure in u_shapeArabic(letters_source5)\n"); |
3134 | } | |
3135 | ||
3136 | errorCode=U_ZERO_ERROR; | |
3137 | ||
b331163b A |
3138 | length=u_shapeArabic(letters_source6, UPRV_LENGTHOF(letters_source6), |
3139 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3140 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_TASHKEEL_END | U_SHAPE_LETTERS_SHAPE, |
3141 | &errorCode); | |
3142 | ||
b331163b | 3143 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest6) || memcmp(dest, letters_dest6, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3144 | log_err("failure in u_shapeArabic(letters_source6)\n"); |
3145 | } | |
3146 | ||
3147 | errorCode=U_ZERO_ERROR; | |
3148 | ||
b331163b A |
3149 | length=u_shapeArabic(letters_source7, UPRV_LENGTHOF(letters_source7), |
3150 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3151 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_TASHKEEL_RESIZE | U_SHAPE_LETTERS_SHAPE, |
3152 | &errorCode); | |
3153 | ||
b331163b | 3154 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest7) || memcmp(dest, letters_dest7, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3155 | log_err("failure in u_shapeArabic(letters_source7)\n"); |
3156 | } | |
3157 | ||
3158 | errorCode=U_ZERO_ERROR; | |
3159 | ||
b331163b A |
3160 | length=u_shapeArabic(letters_source8, UPRV_LENGTHOF(letters_source8), |
3161 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3162 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_TASHKEEL_REPLACE_BY_TATWEEL | U_SHAPE_LETTERS_SHAPE, |
3163 | &errorCode); | |
3164 | ||
b331163b | 3165 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest8) || memcmp(dest, letters_dest8, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3166 | log_err("failure in u_shapeArabic(letters_source8)\n"); |
3167 | } | |
3168 | } | |
3169 | ||
3170 | static void | |
3171 | doArabicShapingTestForBug9024(void) { | |
3172 | static const UChar | |
3173 | letters_source1[]={ /* Arabic mathematical Symbols 0x1EE00 - 0x1EE1B */ | |
57a6839d | 3174 | 0xD83B, 0xDE00, 0xD83B, 0xDE01, 0xD83B, 0xDE02, 0xD83B, 0xDE03, 0x20, |
51004dcb A |
3175 | 0xD83B, 0xDE24, 0xD83B, 0xDE05, 0xD83B, 0xDE06, 0x20, |
3176 | 0xD83B, 0xDE07, 0xD83B, 0xDE08, 0xD83B, 0xDE09, 0x20, | |
3177 | 0xD83B, 0xDE0A, 0xD83B, 0xDE0B, 0xD83B, 0xDE0C, 0xD83B, 0xDE0D, 0x20, | |
3178 | 0xD83B, 0xDE0E, 0xD83B, 0xDE0F, 0xD83B, 0xDE10, 0xD83B, 0xDE11, 0x20, | |
3179 | 0xD83B, 0xDE12, 0xD83B, 0xDE13, 0xD83B, 0xDE14, 0xD83B, 0xDE15, 0x20, | |
3180 | 0xD83B, 0xDE16, 0xD83B, 0xDE17, 0xD83B, 0xDE18, 0x20, | |
3181 | 0xD83B, 0xDE19, 0xD83B, 0xDE1A, 0xD83B, 0xDE1B | |
3182 | }, letters_source2[]={/* Arabic mathematical Symbols - Looped Symbols, 0x1EE80 - 0x1EE9B */ | |
57a6839d | 3183 | 0xD83B, 0xDE80, 0xD83B, 0xDE81, 0xD83B, 0xDE82, 0xD83B, 0xDE83, 0x20, |
51004dcb A |
3184 | 0xD83B, 0xDE84, 0xD83B, 0xDE85, 0xD83B, 0xDE86, 0x20, |
3185 | 0xD83B, 0xDE87, 0xD83B, 0xDE88, 0xD83B, 0xDE89, 0x20, | |
3186 | 0xD83B, 0xDE8B, 0xD83B, 0xDE8C, 0xD83B, 0xDE8D, 0x20, | |
3187 | 0xD83B, 0xDE8E, 0xD83B, 0xDE8F, 0xD83B, 0xDE90, 0xD83B, 0xDE91, 0x20, | |
3188 | 0xD83B, 0xDE92, 0xD83B, 0xDE93, 0xD83B, 0xDE94, 0xD83B, 0xDE95, 0x20, | |
3189 | 0xD83B, 0xDE96, 0xD83B, 0xDE97, 0xD83B, 0xDE98, 0x20, | |
3190 | 0xD83B, 0xDE99, 0xD83B, 0xDE9A, 0xD83B, 0xDE9B | |
3191 | }, letters_source3[]={/* Arabic mathematical Symbols - Double-struck Symbols, 0x1EEA1 - 0x1EEBB */ | |
57a6839d | 3192 | 0xD83B, 0xDEA1, 0xD83B, 0xDEA2, 0xD83B, 0xDEA3, 0x20, |
51004dcb A |
3193 | 0xD83B, 0xDEA5, 0xD83B, 0xDEA6, 0x20, |
3194 | 0xD83B, 0xDEA7, 0xD83B, 0xDEA8, 0xD83B, 0xDEA9, 0x20, | |
3195 | 0xD83B, 0xDEAB, 0xD83B, 0xDEAC, 0xD83B, 0xDEAD, 0x20, | |
3196 | 0xD83B, 0xDEAE, 0xD83B, 0xDEAF, 0xD83B, 0xDEB0, 0xD83B, 0xDEB1, 0x20, | |
3197 | 0xD83B, 0xDEB2, 0xD83B, 0xDEB3, 0xD83B, 0xDEB4, 0xD83B, 0xDEB5, 0x20, | |
3198 | 0xD83B, 0xDEB6, 0xD83B, 0xDEB7, 0xD83B, 0xDEB8, 0x20, | |
3199 | 0xD83B, 0xDEB9, 0xD83B, 0xDEBA, 0xD83B, 0xDEBB | |
3200 | }, letters_source4[]={/* Arabic mathematical Symbols - Initial Symbols, 0x1EE21 - 0x1EE3B */ | |
57a6839d | 3201 | 0xD83B, 0xDE21, 0xD83B, 0xDE22, 0x20, |
51004dcb A |
3202 | 0xD83B, 0xDE27, 0xD83B, 0xDE29, 0x20, |
3203 | 0xD83B, 0xDE2A, 0xD83B, 0xDE2B, 0xD83B, 0xDE2C, 0xD83B, 0xDE2D, 0x20, | |
3204 | 0xD83B, 0xDE2E, 0xD83B, 0xDE2F, 0xD83B, 0xDE30, 0xD83B, 0xDE31, 0x20, | |
3205 | 0xD83B, 0xDE32, 0xD83B, 0xDE34, 0xD83B, 0xDE35, 0x20, | |
3206 | 0xD83B, 0xDE36, 0xD83B, 0xDE37, 0x20, | |
3207 | 0xD83B, 0xDE39, 0xD83B, 0xDE3B | |
3208 | }, letters_source5[]={/* Arabic mathematical Symbols - Tailed Symbols */ | |
57a6839d | 3209 | 0xD83B, 0xDE42, 0xD83B, 0xDE47, 0xD83B, 0xDE49, 0xD83B, 0xDE4B, 0x20, |
51004dcb A |
3210 | 0xD83B, 0xDE4D, 0xD83B, 0xDE4E, 0xD83B, 0xDE4F, 0x20, |
3211 | 0xD83B, 0xDE51, 0xD83B, 0xDE52, 0xD83B, 0xDE54, 0xD83B, 0xDE57, 0x20, | |
3212 | 0xD83B, 0xDE59, 0xD83B, 0xDE5B, 0xD83B, 0xDE5D, 0xD83B, 0xDE5F | |
3213 | }, letters_source6[]={/* Arabic mathematical Symbols - Stretched Symbols with 06 range */ | |
3214 | 0xD83B, 0xDE21, 0x0633, 0xD83B, 0xDE62, 0x0647 | |
3215 | }, letters_dest1[]={ | |
57a6839d | 3216 | 0xD83B, 0xDE00, 0xD83B, 0xDE01, 0xD83B, 0xDE02, 0xD83B, 0xDE03, 0x20, |
51004dcb A |
3217 | 0xD83B, 0xDE24, 0xD83B, 0xDE05, 0xD83B, 0xDE06, 0x20, |
3218 | 0xD83B, 0xDE07, 0xD83B, 0xDE08, 0xD83B, 0xDE09, 0x20, | |
3219 | 0xD83B, 0xDE0A, 0xD83B, 0xDE0B, 0xD83B, 0xDE0C, 0xD83B, 0xDE0D, 0x20, | |
3220 | 0xD83B, 0xDE0E, 0xD83B, 0xDE0F, 0xD83B, 0xDE10, 0xD83B, 0xDE11, 0x20, | |
3221 | 0xD83B, 0xDE12, 0xD83B, 0xDE13, 0xD83B, 0xDE14, 0xD83B, 0xDE15, 0x20, | |
3222 | 0xD83B, 0xDE16, 0xD83B, 0xDE17, 0xD83B, 0xDE18, 0x20, | |
3223 | 0xD83B, 0xDE19, 0xD83B, 0xDE1A, 0xD83B, 0xDE1B | |
3224 | }, letters_dest2[]={ | |
57a6839d | 3225 | 0xD83B, 0xDE80, 0xD83B, 0xDE81, 0xD83B, 0xDE82, 0xD83B, 0xDE83, 0x20, |
51004dcb A |
3226 | 0xD83B, 0xDE84, 0xD83B, 0xDE85, 0xD83B, 0xDE86, 0x20, |
3227 | 0xD83B, 0xDE87, 0xD83B, 0xDE88, 0xD83B, 0xDE89, 0x20, | |
3228 | 0xD83B, 0xDE8B, 0xD83B, 0xDE8C, 0xD83B, 0xDE8D, 0x20, | |
3229 | 0xD83B, 0xDE8E, 0xD83B, 0xDE8F, 0xD83B, 0xDE90, 0xD83B, 0xDE91, 0x20, | |
3230 | 0xD83B, 0xDE92, 0xD83B, 0xDE93, 0xD83B, 0xDE94, 0xD83B, 0xDE95, 0x20, | |
3231 | 0xD83B, 0xDE96, 0xD83B, 0xDE97, 0xD83B, 0xDE98, 0x20, | |
3232 | 0xD83B, 0xDE99, 0xD83B, 0xDE9A, 0xD83B, 0xDE9B | |
3233 | }, letters_dest3[]={ | |
57a6839d | 3234 | 0xD83B, 0xDEA1, 0xD83B, 0xDEA2, 0xD83B, 0xDEA3, 0x20, |
51004dcb A |
3235 | 0xD83B, 0xDEA5, 0xD83B, 0xDEA6, 0x20, |
3236 | 0xD83B, 0xDEA7, 0xD83B, 0xDEA8, 0xD83B, 0xDEA9, 0x20, | |
3237 | 0xD83B, 0xDEAB, 0xD83B, 0xDEAC, 0xD83B, 0xDEAD, 0x20, | |
3238 | 0xD83B, 0xDEAE, 0xD83B, 0xDEAF, 0xD83B, 0xDEB0, 0xD83B, 0xDEB1, 0x20, | |
3239 | 0xD83B, 0xDEB2, 0xD83B, 0xDEB3, 0xD83B, 0xDEB4, 0xD83B, 0xDEB5, 0x20, | |
3240 | 0xD83B, 0xDEB6, 0xD83B, 0xDEB7, 0xD83B, 0xDEB8, 0x20, | |
3241 | 0xD83B, 0xDEB9, 0xD83B, 0xDEBA, 0xD83B, 0xDEBB | |
3242 | }, letters_dest4[]={ | |
57a6839d | 3243 | 0xD83B, 0xDE21, 0xD83B, 0xDE22, 0x20, |
51004dcb A |
3244 | 0xD83B, 0xDE27, 0xD83B, 0xDE29, 0x20, |
3245 | 0xD83B, 0xDE2A, 0xD83B, 0xDE2B, 0xD83B, 0xDE2C, 0xD83B, 0xDE2D, 0x20, | |
3246 | 0xD83B, 0xDE2E, 0xD83B, 0xDE2F, 0xD83B, 0xDE30, 0xD83B, 0xDE31, 0x20, | |
3247 | 0xD83B, 0xDE32, 0xD83B, 0xDE34, 0xD83B, 0xDE35, 0x20, | |
3248 | 0xD83B, 0xDE36, 0xD83B, 0xDE37, 0x20, | |
3249 | 0xD83B, 0xDE39, 0xD83B, 0xDE3B | |
3250 | }, letters_dest5[]={ | |
57a6839d | 3251 | 0xD83B, 0xDE42, 0xD83B, 0xDE47, 0xD83B, 0xDE49, 0xD83B, 0xDE4B, 0x20, |
51004dcb A |
3252 | 0xD83B, 0xDE4D, 0xD83B, 0xDE4E, 0xD83B, 0xDE4F, 0x20, |
3253 | 0xD83B, 0xDE51, 0xD83B, 0xDE52, 0xD83B, 0xDE54, 0xD83B, 0xDE57, 0x20, | |
3254 | 0xD83B, 0xDE59, 0xD83B, 0xDE5B, 0xD83B, 0xDE5D, 0xD83B, 0xDE5F | |
3255 | }, letters_dest6[]={ | |
3256 | 0xD83B, 0xDE21, 0xFEB1, 0xD83B, 0xDE62, 0xFEE9 | |
3257 | }; | |
3258 | ||
3259 | UChar dest[MAXLEN]; | |
3260 | UErrorCode errorCode; | |
3261 | int32_t length; | |
3262 | ||
3263 | errorCode=U_ZERO_ERROR; | |
3264 | ||
b331163b A |
3265 | length=u_shapeArabic(letters_source1, UPRV_LENGTHOF(letters_source1), |
3266 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3267 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_BEGIN | U_SHAPE_LETTERS_SHAPE, |
3268 | &errorCode); | |
3269 | ||
b331163b | 3270 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest1) || memcmp(dest, letters_dest1, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3271 | log_err("failure in u_shapeArabic(letters_source1)\n"); |
3272 | } | |
3273 | ||
3274 | errorCode=U_ZERO_ERROR; | |
3275 | ||
b331163b A |
3276 | length=u_shapeArabic(letters_source2, UPRV_LENGTHOF(letters_source2), |
3277 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3278 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_END | U_SHAPE_LETTERS_SHAPE, |
3279 | &errorCode); | |
3280 | ||
b331163b | 3281 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest2) || memcmp(dest, letters_dest2, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3282 | log_err("failure in u_shapeArabic(letters_source2)\n"); |
3283 | } | |
3284 | ||
3285 | errorCode=U_ZERO_ERROR; | |
3286 | ||
b331163b A |
3287 | length=u_shapeArabic(letters_source3, UPRV_LENGTHOF(letters_source3), |
3288 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3289 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_RESIZE | U_SHAPE_LETTERS_SHAPE, |
3290 | &errorCode); | |
3291 | ||
b331163b | 3292 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest3) || memcmp(dest, letters_dest3, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3293 | log_err("failure in u_shapeArabic(letters_source3)\n"); |
3294 | } | |
3295 | ||
3296 | errorCode=U_ZERO_ERROR; | |
3297 | ||
b331163b A |
3298 | length=u_shapeArabic(letters_source4, UPRV_LENGTHOF(letters_source4), |
3299 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3300 | U_SHAPE_TEXT_DIRECTION_VISUAL_RTL | U_SHAPE_TASHKEEL_REPLACE_BY_TATWEEL | U_SHAPE_LETTERS_SHAPE, |
3301 | &errorCode); | |
3302 | ||
b331163b | 3303 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest4) || memcmp(dest, letters_dest4, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3304 | log_err("failure in u_shapeArabic(letters_source4)\n"); |
3305 | } | |
3306 | ||
3307 | errorCode=U_ZERO_ERROR; | |
3308 | ||
b331163b A |
3309 | length=u_shapeArabic(letters_source5, UPRV_LENGTHOF(letters_source5), |
3310 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3311 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_TASHKEEL_BEGIN | U_SHAPE_LETTERS_SHAPE, |
3312 | &errorCode); | |
3313 | ||
b331163b | 3314 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest5) || memcmp(dest, letters_dest5, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3315 | log_err("failure in u_shapeArabic(letters_source5)\n"); |
3316 | } | |
3317 | ||
3318 | errorCode=U_ZERO_ERROR; | |
3319 | ||
b331163b A |
3320 | length=u_shapeArabic(letters_source6, UPRV_LENGTHOF(letters_source6), |
3321 | dest, UPRV_LENGTHOF(dest), | |
51004dcb A |
3322 | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_TASHKEEL_END | U_SHAPE_LETTERS_SHAPE, |
3323 | &errorCode); | |
3324 | ||
b331163b | 3325 | if(U_FAILURE(errorCode) || length!=UPRV_LENGTHOF(letters_dest6) || memcmp(dest, letters_dest6, length*U_SIZEOF_UCHAR)!=0) { |
51004dcb A |
3326 | log_err("failure in u_shapeArabic(letters_source6)\n"); |
3327 | } | |
3328 | ||
3329 | } | |
3330 | ||
57a6839d A |
3331 | static void _testPresentationForms(const UChar* in) { |
3332 | enum Forms { GENERIC, ISOLATED, FINAL, INITIAL, MEDIAL }; | |
3333 | /* This character is used to check whether the in-character is rewritten correctly | |
3334 | and whether the surrounding characters are shaped correctly as well. */ | |
3335 | UChar otherChar[] = {0x0628, 0xfe8f, 0xfe90, 0xfe91, 0xfe92}; | |
3336 | UChar src[3]; | |
3337 | UChar dst[3]; | |
3338 | UErrorCode errorCode; | |
3339 | int32_t length; | |
3340 | ||
3341 | /* Testing isolated shaping */ | |
3342 | src[0] = in[GENERIC]; | |
3343 | errorCode=U_ZERO_ERROR; | |
3344 | length=u_shapeArabic(src, 1, | |
3345 | dst, 1, | |
3346 | U_SHAPE_LETTERS_SHAPE, | |
3347 | &errorCode); | |
3348 | if(U_FAILURE(errorCode) || length!=1 || dst[0] != in[ISOLATED]) { | |
3349 | log_err("failure in u_shapeArabic(_testAllForms: shaping isolated): %x\n", in[GENERIC]); | |
3350 | } | |
3351 | errorCode=U_ZERO_ERROR; | |
3352 | length=u_shapeArabic(dst, 1, | |
3353 | src, 1, | |
3354 | U_SHAPE_LETTERS_UNSHAPE, | |
3355 | &errorCode); | |
3356 | if(U_FAILURE(errorCode) || length!=1 || src[0] != in[GENERIC]) { | |
3357 | log_err("failure in u_shapeArabic(_testAllForms: unshaping isolated): %x\n", in[GENERIC]); | |
3358 | } | |
3359 | ||
3360 | /* Testing final shaping */ | |
3361 | src[0] = otherChar[GENERIC]; | |
3362 | src[1] = in[GENERIC]; | |
3363 | if (in[FINAL] != 0) { | |
3364 | errorCode=U_ZERO_ERROR; | |
3365 | length=u_shapeArabic(src, 2, | |
3366 | dst, 2, | |
3367 | U_SHAPE_LETTERS_SHAPE, | |
3368 | &errorCode); | |
3369 | if(U_FAILURE(errorCode) || length!=2 || dst[0] != otherChar[INITIAL] || dst[1] != in[FINAL]) { | |
3370 | log_err("failure in u_shapeArabic(_testAllForms: shaping final): %x\n", in[GENERIC]); | |
3371 | } | |
3372 | errorCode=U_ZERO_ERROR; | |
3373 | length=u_shapeArabic(dst, 2, | |
3374 | src, 2, | |
3375 | U_SHAPE_LETTERS_UNSHAPE, | |
3376 | &errorCode); | |
3377 | if(U_FAILURE(errorCode) || length!=2 || src[0] != otherChar[GENERIC] || src[1] != in[GENERIC]) { | |
3378 | log_err("failure in u_shapeArabic(_testAllForms: unshaping final): %x\n", in[GENERIC]); | |
3379 | } | |
3380 | } else { | |
3381 | errorCode=U_ZERO_ERROR; | |
3382 | length=u_shapeArabic(src, 2, | |
3383 | dst, 2, | |
3384 | U_SHAPE_LETTERS_SHAPE, | |
3385 | &errorCode); | |
3386 | if(U_FAILURE(errorCode) || length!=2 || dst[0] != otherChar[ISOLATED] || dst[1] != in[ISOLATED]) { | |
3387 | log_err("failure in u_shapeArabic(_testAllForms: shaping final): %x\n", in[GENERIC]); | |
3388 | } | |
3389 | errorCode=U_ZERO_ERROR; | |
3390 | length=u_shapeArabic(dst, 2, | |
3391 | src, 2, | |
3392 | U_SHAPE_LETTERS_UNSHAPE, | |
3393 | &errorCode); | |
3394 | if(U_FAILURE(errorCode) || length!=2 || src[0] != otherChar[GENERIC] || src[1] != in[GENERIC]) { | |
3395 | log_err("failure in u_shapeArabic(_testAllForms: unshaping final): %x\n", in[GENERIC]); | |
3396 | } | |
3397 | } | |
3398 | ||
3399 | /* Testing initial shaping */ | |
3400 | src[0] = in[GENERIC]; | |
3401 | src[1] = otherChar[GENERIC]; | |
3402 | if (in[INITIAL] != 0) { | |
3403 | /* Testing characters that have an initial form */ | |
3404 | errorCode=U_ZERO_ERROR; | |
3405 | length=u_shapeArabic(src, 2, | |
3406 | dst, 2, | |
3407 | U_SHAPE_LETTERS_SHAPE, | |
3408 | &errorCode); | |
3409 | if(U_FAILURE(errorCode) || length!=2 || dst[0] != in[INITIAL] || dst[1] != otherChar[FINAL]) { | |
3410 | log_err("failure in u_shapeArabic(_testAllForms: shaping initial): %x\n", in[GENERIC]); | |
3411 | } | |
3412 | errorCode=U_ZERO_ERROR; | |
3413 | length=u_shapeArabic(dst, 2, | |
3414 | src, 2, | |
3415 | U_SHAPE_LETTERS_UNSHAPE, | |
3416 | &errorCode); | |
3417 | if(U_FAILURE(errorCode) || length!=2 || src[0] != in[GENERIC] || src[1] != otherChar[GENERIC]) { | |
3418 | log_err("failure in u_shapeArabic(_testAllForms: unshaping initial): %x\n", in[GENERIC]); | |
3419 | } | |
3420 | } else { | |
3421 | /* Testing characters that do not have an initial form */ | |
3422 | errorCode=U_ZERO_ERROR; | |
3423 | length=u_shapeArabic(src, 2, | |
3424 | dst, 2, | |
3425 | U_SHAPE_LETTERS_SHAPE, | |
3426 | &errorCode); | |
3427 | if(U_FAILURE(errorCode) || length!=2 || dst[0] != in[ISOLATED] || dst[1] != otherChar[ISOLATED]) { | |
3428 | log_err("failure in u_shapeArabic(_testTwoForms: shaping initial): %x\n", in[GENERIC]); | |
3429 | } | |
3430 | errorCode=U_ZERO_ERROR; | |
3431 | length=u_shapeArabic(dst, 2, | |
3432 | src, 2, | |
3433 | U_SHAPE_LETTERS_UNSHAPE, | |
3434 | &errorCode); | |
3435 | if(U_FAILURE(errorCode) || length!=2 || src[0] != in[GENERIC] || src[1] != otherChar[GENERIC]) { | |
3436 | log_err("failure in u_shapeArabic(_testTwoForms: unshaping initial): %x\n", in[GENERIC]); | |
3437 | } | |
3438 | } | |
3439 | ||
3440 | /* Testing medial shaping */ | |
3441 | src[0] = otherChar[0]; | |
3442 | src[1] = in[GENERIC]; | |
3443 | src[2] = otherChar[0]; | |
3444 | errorCode=U_ZERO_ERROR; | |
3445 | if (in[MEDIAL] != 0) { | |
3446 | /* Testing characters that have an medial form */ | |
3447 | length=u_shapeArabic(src, 3, | |
3448 | dst, 3, | |
3449 | U_SHAPE_LETTERS_SHAPE, | |
3450 | &errorCode); | |
3451 | if(U_FAILURE(errorCode) || length!=3 || dst[0] != otherChar[INITIAL] || dst[1] != in[MEDIAL] || dst[2] != otherChar[FINAL]) { | |
3452 | log_err("failure in u_shapeArabic(_testAllForms: shaping medial): %x\n", in[GENERIC]); | |
3453 | } | |
3454 | errorCode=U_ZERO_ERROR; | |
3455 | length=u_shapeArabic(dst, 3, | |
3456 | src, 3, | |
3457 | U_SHAPE_LETTERS_UNSHAPE, | |
3458 | &errorCode); | |
3459 | if(U_FAILURE(errorCode) || length!=3 || src[0] != otherChar[GENERIC] || src[1] != in[GENERIC] || src[2] != otherChar[GENERIC]) { | |
3460 | log_err("failure in u_shapeArabic(_testAllForms: unshaping medial): %x\n", in[GENERIC]); | |
3461 | } | |
3462 | } else { | |
3463 | /* Testing characters that do not have an medial form */ | |
3464 | errorCode=U_ZERO_ERROR; | |
3465 | length=u_shapeArabic(src, 3, | |
3466 | dst, 3, | |
3467 | U_SHAPE_LETTERS_SHAPE, | |
3468 | &errorCode); | |
3469 | if(U_FAILURE(errorCode) || length!=3 || dst[0] != otherChar[INITIAL] || dst[1] != in[FINAL] || dst[2] != otherChar[ISOLATED]) { | |
3470 | log_err("failure in u_shapeArabic(_testTwoForms: shaping medial): %x\n", in[GENERIC]); | |
3471 | } | |
3472 | errorCode=U_ZERO_ERROR; | |
3473 | length=u_shapeArabic(dst, 3, | |
3474 | src, 3, | |
3475 | U_SHAPE_LETTERS_UNSHAPE, | |
3476 | &errorCode); | |
3477 | if(U_FAILURE(errorCode) || length!=3 || src[0] != otherChar[GENERIC] || src[1] != in[GENERIC] || src[2] != otherChar[GENERIC]) { | |
3478 | log_err("failure in u_shapeArabic(_testTwoForms: unshaping medial): %x\n", in[GENERIC]); | |
3479 | } | |
3480 | } | |
3481 | } | |
3482 | ||
3483 | static void | |
3484 | doArabicShapingTestForNewCharacters(void) { | |
3485 | static const UChar letterForms[][5]={ | |
3486 | { 0x0679, 0xFB66, 0xFB67, 0xFB68, 0xFB69 }, /* TTEH */ | |
3487 | { 0x067A, 0xFB5E, 0xFB5F, 0xFB60, 0xFB61 }, /* TTEHEH */ | |
3488 | { 0x067B, 0xFB52, 0xFB53, 0xFB54, 0xFB55 }, /* BEEH */ | |
3489 | { 0x0688, 0xFB88, 0xFB89, 0, 0 }, /* DDAL */ | |
3490 | { 0x068C, 0xFB84, 0xFB85, 0, 0 }, /* DAHAL */ | |
3491 | { 0x068D, 0xFB82, 0xFB83, 0, 0 }, /* DDAHAL */ | |
3492 | { 0x068E, 0xFB86, 0xFB87, 0, 0 }, /* DUL */ | |
3493 | { 0x0691, 0xFB8C, 0xFB8D, 0, 0 }, /* RREH */ | |
3494 | { 0x06BA, 0xFB9E, 0xFB9F, 0, 0 }, /* NOON GHUNNA */ | |
3495 | { 0x06BB, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3 }, /* RNOON */ | |
3496 | { 0x06BE, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD }, /* HEH DOACHASHMEE */ | |
3497 | { 0x06C0, 0xFBA4, 0xFBA5, 0, 0 }, /* HEH WITH YEH ABOVE */ | |
3498 | { 0x06C1, 0xFBA6, 0xFBA7, 0xFBA8, 0xFBA9 }, /* HEH GOAL */ | |
3499 | { 0x06C5, 0xFBE0, 0xFBE1, 0, 0 }, /* KIRGIHIZ OE */ | |
3500 | { 0x06C6, 0xFBD9, 0xFBDA, 0, 0 }, /* OE */ | |
3501 | { 0x06C7, 0xFBD7, 0xFBD8, 0, 0 }, /* U */ | |
3502 | { 0x06C8, 0xFBDB, 0xFBDC, 0, 0 }, /* YU */ | |
3503 | { 0x06C9, 0xFBE2, 0xFBE3, 0, 0 }, /* KIRGIZ YU */ | |
3504 | { 0x06CB, 0xFBDE, 0xFBDF, 0, 0}, /* VE */ | |
3505 | { 0x06D0, 0xFBE4, 0xFBE5, 0xFBE6, 0xFBE7 }, /* E */ | |
3506 | { 0x06D2, 0xFBAE, 0xFBAF, 0, 0 }, /* YEH BARREE */ | |
3507 | { 0x06D3, 0xFBB0, 0xFBB1, 0, 0 }, /* YEH BARREE WITH HAMZA ABOVE */ | |
3508 | { 0x0622, 0xFE81, 0xFE82, 0, 0, }, /* ALEF WITH MADDA ABOVE */ | |
3509 | { 0x0623, 0xFE83, 0xFE84, 0, 0, }, /* ALEF WITH HAMZA ABOVE */ | |
3510 | { 0x0624, 0xFE85, 0xFE86, 0, 0, }, /* WAW WITH HAMZA ABOVE */ | |
3511 | { 0x0625, 0xFE87, 0xFE88, 0, 0, }, /* ALEF WITH HAMZA BELOW */ | |
3512 | { 0x0626, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, }, /* YEH WITH HAMZA ABOVE */ | |
3513 | { 0x0627, 0xFE8D, 0xFE8E, 0, 0, }, /* ALEF */ | |
3514 | { 0x0628, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, }, /* BEH */ | |
3515 | { 0x0629, 0xFE93, 0xFE94, 0, 0, }, /* TEH MARBUTA */ | |
3516 | { 0x062A, 0xFE95, 0xFE96, 0xFE97, 0xFE98, }, /* TEH */ | |
3517 | { 0x062B, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, }, /* THEH */ | |
3518 | { 0x062C, 0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0, }, /* JEEM */ | |
3519 | { 0x062D, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, }, /* HAH */ | |
3520 | { 0x062E, 0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8, }, /* KHAH */ | |
3521 | { 0x062F, 0xFEA9, 0xFEAA, 0, 0, }, /* DAL */ | |
3522 | { 0x0630, 0xFEAB, 0xFEAC, 0, 0, }, /* THAL */ | |
3523 | { 0x0631, 0xFEAD, 0xFEAE, 0, 0, }, /* REH */ | |
3524 | { 0x0632, 0xFEAF, 0xFEB0, 0, 0, }, /* ZAIN */ | |
3525 | { 0x0633, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, }, /* SEEN */ | |
3526 | { 0x0634, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, }, /* SHEEN */ | |
3527 | { 0x0635, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC, }, /* SAD */ | |
3528 | { 0x0636, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, }, /* DAD */ | |
3529 | { 0x0637, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, }, /* TAH */ | |
3530 | { 0x0638, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, }, /* ZAH */ | |
3531 | { 0x0639, 0xFEC9, 0xFECA, 0xFECB, 0xFECC, }, /* AIN */ | |
3532 | { 0x063A, 0xFECD, 0xFECE, 0xFECF, 0xFED0, }, /* GHAIN */ | |
3533 | { 0x0641, 0xFED1, 0xFED2, 0xFED3, 0xFED4, }, /* FEH */ | |
3534 | { 0x0642, 0xFED5, 0xFED6, 0xFED7, 0xFED8, }, /* QAF */ | |
3535 | { 0x0643, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, }, /* KAF */ | |
3536 | { 0x0644, 0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0, }, /* LAM */ | |
3537 | { 0x0645, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, }, /* MEEM */ | |
3538 | { 0x0646, 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8, }, /* NOON */ | |
3539 | { 0x0647, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, }, /* HEH */ | |
3540 | { 0x0648, 0xFEED, 0xFEEE, 0, 0, }, /* WAW */ | |
3541 | { 0x0649, 0xFEEF, 0xFEF0, 0, 0, }, /* ALEF MAKSURA */ | |
3542 | { 0x064A, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, }, /* YEH */ | |
3543 | { 0x064E, 0xFE76, 0, 0, 0xFE77, }, /* FATHA */ | |
3544 | { 0x064F, 0xFE78, 0, 0, 0xFE79, }, /* DAMMA */ | |
3545 | { 0x0650, 0xFE7A, 0, 0, 0xFE7B, }, /* KASRA */ | |
3546 | { 0x0651, 0xFE7C, 0, 0, 0xFE7D, }, /* SHADDA */ | |
3547 | { 0x0652, 0xFE7E, 0, 0, 0xFE7F, }, /* SUKUN */ | |
3548 | { 0x0679, 0xFB66, 0xFB67, 0xFB68, 0xFB69, }, /* TTEH */ | |
3549 | { 0x067E, 0xFB56, 0xFB57, 0xFB58, 0xFB59, }, /* PEH */ | |
3550 | { 0x0686, 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, }, /* TCHEH */ | |
3551 | { 0x0688, 0xFB88, 0xFB89, 0, 0, }, /* DDAL */ | |
3552 | { 0x0691, 0xFB8C, 0xFB8D, 0, 0, }, /* RREH */ | |
3553 | { 0x0698, 0xFB8A, 0xFB8B, 0, 0, }, /* JEH */ | |
3554 | { 0x06A9, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, }, /* KEHEH */ | |
3555 | { 0x06AF, 0xFB92, 0xFB93, 0xFB94, 0xFB95, }, /* GAF */ | |
3556 | { 0x06BA, 0xFB9E, 0xFB9F, 0, 0, }, /* NOON GHUNNA */ | |
3557 | { 0x06BE, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, }, /* HEH DOACHASHMEE */ | |
3558 | { 0x06C0, 0xFBA4, 0xFBA5, 0, 0, }, /* HEH WITH YEH ABOVE */ | |
3559 | { 0x06C1, 0xFBA6, 0xFBA7, 0xFBA8, 0xFBA9, }, /* HEH GOAL */ | |
3560 | { 0x06CC, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF, }, /* FARSI YEH */ | |
3561 | { 0x06D2, 0xFBAE, 0xFBAF, 0, 0, }, /* YEH BARREE */ | |
3562 | { 0x06D3, 0xFBB0, 0xFBB1, 0, 0, }}; /* YEH BARREE WITH HAMZA ABOVE */ | |
3563 | int32_t i; | |
b331163b | 3564 | for (i = 0; i < UPRV_LENGTHOF(letterForms); ++i) { |
57a6839d A |
3565 | _testPresentationForms(letterForms[i]); |
3566 | } | |
3567 | } | |
3568 | ||
b75a7d8f A |
3569 | /* helpers ------------------------------------------------------------------ */ |
3570 | ||
46f4442e | 3571 | static void initCharFromDirProps(void) { |
374ca955 A |
3572 | static const UVersionInfo ucd401={ 4, 0, 1, 0 }; |
3573 | static UVersionInfo ucdVersion={ 0, 0, 0, 0 }; | |
3574 | ||
3575 | /* lazy initialization */ | |
3576 | if(ucdVersion[0]>0) { | |
3577 | return; | |
3578 | } | |
3579 | ||
3580 | u_getUnicodeVersion(ucdVersion); | |
3581 | if(memcmp(ucdVersion, ucd401, sizeof(UVersionInfo))>=0) { | |
3582 | /* Unicode 4.0.1 changes bidi classes for +-/ */ | |
3583 | charFromDirProp[U_EUROPEAN_NUMBER_SEPARATOR]=0x2b; /* change ES character from / to + */ | |
3584 | } | |
3585 | } | |
3586 | ||
b75a7d8f A |
3587 | /* return a string with characters according to the desired directional properties */ |
3588 | static UChar * | |
73c04bcf | 3589 | getStringFromDirProps(const uint8_t *dirProps, int32_t length, UChar *buffer) { |
b75a7d8f A |
3590 | int32_t i; |
3591 | ||
374ca955 A |
3592 | initCharFromDirProps(); |
3593 | ||
b75a7d8f A |
3594 | /* this part would have to be modified for UTF-x */ |
3595 | for(i=0; i<length; ++i) { | |
73c04bcf | 3596 | buffer[i]=charFromDirProp[dirProps[i]]; |
b75a7d8f | 3597 | } |
73c04bcf A |
3598 | buffer[length]=0; |
3599 | return buffer; | |
b75a7d8f A |
3600 | } |
3601 | ||
46f4442e | 3602 | static void printUnicode(const UChar *s, int32_t length, const UBiDiLevel *levels) { |
b75a7d8f A |
3603 | int32_t i; |
3604 | ||
3605 | log_verbose("{ "); | |
3606 | for(i=0; i<length; ++i) { | |
3607 | if(levels!=NULL) { | |
3608 | log_verbose("%4x.%u ", s[i], levels[i]); | |
3609 | } else { | |
3610 | log_verbose("%4x ", s[i]); | |
3611 | } | |
3612 | } | |
3613 | log_verbose(" }"); | |
3614 | } | |
73c04bcf A |
3615 | |
3616 | /* new BIDI API */ | |
3617 | ||
3618 | /* Reordering Mode BiDi --------------------------------------------------------- */ | |
3619 | ||
3620 | static const UBiDiLevel paraLevels[] = { UBIDI_LTR, UBIDI_RTL }; | |
3621 | ||
3622 | static UBool | |
3623 | assertSuccessful(const char* message, UErrorCode* rc) { | |
3624 | if (rc != NULL && U_FAILURE(*rc)) { | |
3625 | log_err("%s() failed with error %s.\n", message, myErrorName(*rc)); | |
3626 | return FALSE; | |
3627 | } | |
3628 | return TRUE; | |
3629 | } | |
3630 | ||
3631 | static UBool | |
3632 | assertStringsEqual(const char* expected, const char* actual, const char* src, | |
3633 | const char* mode, const char* option, UBiDi* pBiDi) { | |
3634 | if (uprv_strcmp(expected, actual)) { | |
3635 | char formatChars[MAXLEN]; | |
3636 | log_err("\nActual and expected output mismatch.\n" | |
3637 | "%20s %s\n%20s %s\n%20s %s\n%20s %s\n%20s %d %s\n%20s %u\n%20s %d %s\n", | |
3638 | "Input:", src, | |
3639 | "Actual output:", actual, | |
3640 | "Expected output:", expected, | |
3641 | "Levels:", formatLevels(pBiDi, formatChars), | |
3642 | "Reordering mode:", ubidi_getReorderingMode(pBiDi), mode, | |
3643 | "Paragraph level:", ubidi_getParaLevel(pBiDi), | |
3644 | "Reordering option:", ubidi_getReorderingOptions(pBiDi), option); | |
3645 | return FALSE; | |
3646 | } | |
3647 | return TRUE; | |
3648 | } | |
3649 | ||
3650 | static UBiDi* | |
3651 | getBiDiObject(void) { | |
3652 | UBiDi* pBiDi = ubidi_open(); | |
3653 | if (pBiDi == NULL) { | |
3654 | log_err("Unable to allocate a UBiDi object. Tests are skipped.\n"); | |
3655 | } | |
3656 | return pBiDi; | |
3657 | } | |
3658 | ||
3659 | #define MAKE_ITEMS(val) val, #val | |
3660 | ||
3661 | static const struct { | |
46f4442e | 3662 | UBiDiReorderingMode value; |
73c04bcf A |
3663 | const char* description; |
3664 | } | |
3665 | modes[] = { | |
3666 | { MAKE_ITEMS(UBIDI_REORDER_GROUP_NUMBERS_WITH_R) }, | |
3667 | { MAKE_ITEMS(UBIDI_REORDER_INVERSE_LIKE_DIRECT) }, | |
3668 | { MAKE_ITEMS(UBIDI_REORDER_NUMBERS_SPECIAL) }, | |
3669 | { MAKE_ITEMS(UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL) }, | |
3670 | { MAKE_ITEMS(UBIDI_REORDER_INVERSE_NUMBERS_AS_L) } | |
46f4442e A |
3671 | }; |
3672 | static const struct { | |
3673 | uint32_t value; | |
3674 | const char* description; | |
3675 | } | |
73c04bcf A |
3676 | options[] = { |
3677 | { MAKE_ITEMS(UBIDI_OPTION_INSERT_MARKS) }, | |
3678 | { MAKE_ITEMS(0) } | |
3679 | }; | |
3680 | ||
b331163b A |
3681 | #define TC_COUNT UPRV_LENGTHOF(textIn) |
3682 | #define MODES_COUNT UPRV_LENGTHOF(modes) | |
3683 | #define OPTIONS_COUNT UPRV_LENGTHOF(options) | |
3684 | #define LEVELS_COUNT UPRV_LENGTHOF(paraLevels) | |
73c04bcf A |
3685 | |
3686 | static const char* const textIn[] = { | |
3687 | /* (0) 123 */ | |
3688 | "123", | |
3689 | /* (1) .123->4.5 */ | |
3690 | ".123->4.5", | |
3691 | /* (2) 678 */ | |
3692 | "678", | |
3693 | /* (3) .678->8.9 */ | |
3694 | ".678->8.9", | |
3695 | /* (4) JIH1.2,3MLK */ | |
3696 | "JIH1.2,3MLK", | |
3697 | /* (5) FE.>12-> */ | |
3698 | "FE.>12->", | |
3699 | /* (6) JIH.>12->a */ | |
3700 | "JIH.>12->a", | |
3701 | /* (7) CBA.>67->89=a */ | |
3702 | "CBA.>67->89=a", | |
3703 | /* (8) CBA.123->xyz */ | |
3704 | "CBA.123->xyz", | |
3705 | /* (9) .>12->xyz */ | |
3706 | ".>12->xyz", | |
3707 | /* (10) a.>67->xyz */ | |
3708 | "a.>67->xyz", | |
3709 | /* (11) 123JIH */ | |
3710 | "123JIH", | |
3711 | /* (12) 123 JIH */ | |
3712 | "123 JIH" | |
3713 | }; | |
3714 | ||
3715 | static const char* const textOut[] = { | |
3716 | /* TC 0: 123 */ | |
3717 | "123", /* (0) */ | |
3718 | /* TC 1: .123->4.5 */ | |
3719 | ".123->4.5", /* (1) */ | |
3720 | "4.5<-123.", /* (2) */ | |
3721 | /* TC 2: 678 */ | |
3722 | "678", /* (3) */ | |
3723 | /* TC 3: .678->8.9 */ | |
3724 | ".8.9<-678", /* (4) */ | |
3725 | "8.9<-678.", /* (5) */ | |
3726 | ".678->8.9", /* (6) */ | |
3727 | /* TC 4: MLK1.2,3JIH */ | |
3728 | "KLM1.2,3HIJ", /* (7) */ | |
3729 | /* TC 5: FE.>12-> */ | |
3730 | "12<.EF->", /* (8) */ | |
3731 | "<-12<.EF", /* (9) */ | |
3732 | "EF.>@12->", /* (10) */ | |
3733 | /* TC 6: JIH.>12->a */ | |
3734 | "12<.HIJ->a", /* (11) */ | |
3735 | "a<-12<.HIJ", /* (12) */ | |
3736 | "HIJ.>@12->a", /* (13) */ | |
3737 | "a&<-12<.HIJ", /* (14) */ | |
3738 | /* TC 7: CBA.>67->89=a */ | |
3739 | "ABC.>@67->89=a", /* (15) */ | |
3740 | "a=89<-67<.ABC", /* (16) */ | |
3741 | "a&=89<-67<.ABC", /* (17) */ | |
3742 | "89<-67<.ABC=a", /* (18) */ | |
3743 | /* TC 8: CBA.123->xyz */ | |
3744 | "123.ABC->xyz", /* (19) */ | |
3745 | "xyz<-123.ABC", /* (20) */ | |
3746 | "ABC.@123->xyz", /* (21) */ | |
3747 | "xyz&<-123.ABC", /* (22) */ | |
3748 | /* TC 9: .>12->xyz */ | |
3749 | ".>12->xyz", /* (23) */ | |
3750 | "xyz<-12<.", /* (24) */ | |
3751 | "xyz&<-12<.", /* (25) */ | |
3752 | /* TC 10: a.>67->xyz */ | |
3753 | "a.>67->xyz", /* (26) */ | |
3754 | "a.>@67@->xyz", /* (27) */ | |
3755 | "xyz<-67<.a", /* (28) */ | |
3756 | /* TC 11: 123JIH */ | |
3757 | "123HIJ", /* (29) */ | |
3758 | "HIJ123", /* (30) */ | |
3759 | /* TC 12: 123 JIH */ | |
3760 | "123 HIJ", /* (31) */ | |
3761 | "HIJ 123", /* (32) */ | |
3762 | }; | |
3763 | ||
3764 | #define NO UBIDI_MAP_NOWHERE | |
3765 | #define MAX_MAP_LENGTH 20 | |
3766 | ||
3767 | static const int32_t forwardMap[][MAX_MAP_LENGTH] = { | |
3768 | /* TC 0: 123 */ | |
3769 | { 0, 1, 2 }, /* (0) */ | |
3770 | /* TC 1: .123->4.5 */ | |
3771 | { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (1) */ | |
3772 | { 8, 5, 6, 7, 4, 3, 0, 1, 2 }, /* (2) */ | |
3773 | /* TC 2: 678 */ | |
3774 | { 0, 1, 2 }, /* (3) */ | |
3775 | /* TC 3: .678->8.9 */ | |
3776 | { 0, 6, 7, 8, 5, 4, 1, 2, 3 }, /* (4) */ | |
3777 | { 8, 5, 6, 7, 4, 3, 0, 1, 2 }, /* (5) */ | |
3778 | { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (6) */ | |
3779 | /* TC 4: MLK1.2,3JIH */ | |
3780 | { 10, 9, 8, 3, 4, 5, 6, 7, 2, 1, 0 }, /* (7) */ | |
3781 | /* TC 5: FE.>12-> */ | |
3782 | { 5, 4, 3, 2, 0, 1, 6, 7 }, /* (8) */ | |
3783 | { 7, 6, 5, 4, 2, 3, 1, 0 }, /* (9) */ | |
3784 | { 1, 0, 2, 3, 5, 6, 7, 8 }, /* (10) */ | |
3785 | /* TC 6: JIH.>12->a */ | |
3786 | { 6, 5, 4, 3, 2, 0, 1, 7, 8, 9 }, /* (11) */ | |
3787 | { 9, 8, 7, 6, 5, 3, 4, 2, 1, 0 }, /* (12) */ | |
3788 | { 2, 1, 0, 3, 4, 6, 7, 8, 9, 10 }, /* (13) */ | |
3789 | { 10, 9, 8, 7, 6, 4, 5, 3, 2, 0 }, /* (14) */ | |
3790 | /* TC 7: CBA.>67->89=a */ | |
3791 | { 2, 1, 0, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 }, /* (15) */ | |
3792 | { 12, 11, 10, 9, 8, 6, 7, 5, 4, 2, 3, 1, 0 }, /* (16) */ | |
3793 | { 13, 12, 11, 10, 9, 7, 8, 6, 5, 3, 4, 2, 0 }, /* (17) */ | |
3794 | { 10, 9, 8, 7, 6, 4, 5, 3, 2, 0, 1, 11, 12 }, /* (18) */ | |
3795 | /* TC 8: CBA.123->xyz */ | |
3796 | { 6, 5, 4, 3, 0, 1, 2, 7, 8, 9, 10, 11 }, /* (19) */ | |
3797 | { 11, 10, 9, 8, 5, 6, 7, 4, 3, 0, 1, 2 }, /* (20) */ | |
3798 | { 2, 1, 0, 3, 5, 6, 7, 8, 9, 10, 11, 12 }, /* (21) */ | |
3799 | { 12, 11, 10, 9, 6, 7, 8, 5, 4, 0, 1, 2 }, /* (22) */ | |
3800 | /* TC 9: .>12->xyz */ | |
3801 | { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (23) */ | |
3802 | { 8, 7, 5, 6, 4, 3, 0, 1, 2 }, /* (24) */ | |
3803 | { 9, 8, 6, 7, 5, 4, 0, 1, 2 }, /* (25) */ | |
3804 | /* TC 10: a.>67->xyz */ | |
3805 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, /* (26) */ | |
3806 | { 0, 1, 2, 4, 5, 7, 8, 9, 10, 11 }, /* (27) */ | |
3807 | { 9, 8, 7, 5, 6, 4, 3, 0, 1, 2 }, /* (28) */ | |
3808 | /* TC 11: 123JIH */ | |
3809 | { 0, 1, 2, 5, 4, 3 }, /* (29) */ | |
3810 | { 3, 4, 5, 2, 1, 0 }, /* (30) */ | |
3811 | /* TC 12: 123 JIH */ | |
3812 | { 0, 1, 2, 3, 6, 5, 4 }, /* (31) */ | |
3813 | { 4, 5, 6, 3, 2, 1, 0 }, /* (32) */ | |
3814 | }; | |
3815 | ||
3816 | static const int32_t inverseMap[][MAX_MAP_LENGTH] = { | |
3817 | /* TC 0: 123 */ | |
3818 | { 0, 1, 2 }, /* (0) */ | |
3819 | /* TC 1: .123->4.5 */ | |
3820 | { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (1) */ | |
3821 | { 6, 7, 8, 5, 4, 1, 2, 3, 0 }, /* (2) */ | |
3822 | /* TC 2: 678 */ | |
3823 | { 0, 1, 2 }, /* (3) */ | |
3824 | /* TC 3: .678->8.9 */ | |
3825 | { 0, 6, 7, 8, 5, 4, 1, 2, 3 }, /* (4) */ | |
3826 | { 6, 7, 8, 5, 4, 1, 2, 3, 0 }, /* (5) */ | |
3827 | { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (6) */ | |
3828 | /* TC 4: MLK1.2,3JIH */ | |
3829 | { 10, 9, 8, 3, 4, 5, 6, 7, 2, 1, 0 }, /* (7) */ | |
3830 | /* TC 5: FE.>12-> */ | |
3831 | { 4, 5, 3, 2, 1, 0, 6, 7 }, /* (8) */ | |
3832 | { 7, 6, 4, 5, 3, 2, 1, 0 }, /* (9) */ | |
3833 | { 1, 0, 2, 3, NO, 4, 5, 6, 7 }, /* (10) */ | |
3834 | /* TC 6: JIH.>12->a */ | |
3835 | { 5, 6, 4, 3, 2, 1, 0, 7, 8, 9 }, /* (11) */ | |
3836 | { 9, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (12) */ | |
3837 | { 2, 1, 0, 3, 4, NO, 5, 6, 7, 8, 9 }, /* (13) */ | |
3838 | { 9, NO, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (14) */ | |
3839 | /* TC 7: CBA.>67->89=a */ | |
3840 | { 2, 1, 0, 3, 4, NO, 5, 6, 7, 8, 9, 10, 11, 12 }, /* (15) */ | |
3841 | { 12, 11, 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (16) */ | |
3842 | { 12, NO, 11, 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (17) */ | |
3843 | { 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0, 11, 12 }, /* (18) */ | |
3844 | /* TC 8: CBA.123->xyz */ | |
3845 | { 4, 5, 6, 3, 2, 1, 0, 7, 8, 9, 10, 11 }, /* (19) */ | |
3846 | { 9, 10, 11, 8, 7, 4, 5, 6, 3, 2, 1, 0 }, /* (20) */ | |
3847 | { 2, 1, 0, 3, NO, 4, 5, 6, 7, 8, 9, 10, 11 }, /* (21) */ | |
3848 | { 9, 10, 11, NO, 8, 7, 4, 5, 6, 3, 2, 1, 0 }, /* (22) */ | |
3849 | /* TC 9: .>12->xyz */ | |
3850 | { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (23) */ | |
3851 | { 6, 7, 8, 5, 4, 2, 3, 1, 0 }, /* (24) */ | |
3852 | { 6, 7, 8, NO, 5, 4, 2, 3, 1, 0 }, /* (25) */ | |
3853 | /* TC 10: a.>67->xyz */ | |
3854 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, /* (26) */ | |
3855 | { 0, 1, 2, NO, 3, 4, NO, 5, 6, 7, 8, 9 }, /* (27) */ | |
3856 | { 7, 8, 9, 6, 5, 3, 4, 2, 1, 0 }, /* (28) */ | |
3857 | /* TC 11: 123JIH */ | |
3858 | { 0, 1, 2, 5, 4, 3 }, /* (29) */ | |
3859 | { 5, 4, 3, 0, 1, 2 }, /* (30) */ | |
3860 | /* TC 12: 123 JIH */ | |
3861 | { 0, 1, 2, 3, 6, 5, 4 }, /* (31) */ | |
3862 | { 6, 5, 4, 3, 0, 1, 2 }, /* (32) */ | |
3863 | }; | |
3864 | ||
3865 | static const char outIndices[TC_COUNT][MODES_COUNT - 1][OPTIONS_COUNT] | |
3866 | [LEVELS_COUNT] = { | |
3867 | { /* TC 0: 123 */ | |
3868 | {{ 0, 0}, { 0, 0}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3869 | {{ 0, 0}, { 0, 0}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3870 | {{ 0, 0}, { 0, 0}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3871 | {{ 0, 0}, { 0, 0}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3872 | }, | |
3873 | { /* TC 1: .123->4.5 */ | |
3874 | {{ 1, 2}, { 1, 2}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3875 | {{ 1, 2}, { 1, 2}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3876 | {{ 1, 2}, { 1, 2}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3877 | {{ 1, 2}, { 1, 2}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3878 | }, | |
3879 | { /* TC 2: 678 */ | |
3880 | {{ 3, 3}, { 3, 3}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3881 | {{ 3, 3}, { 3, 3}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3882 | {{ 3, 3}, { 3, 3}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3883 | {{ 3, 3}, { 3, 3}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3884 | }, | |
3885 | { /* TC 3: .678->8.9 */ | |
3886 | {{ 6, 5}, { 6, 5}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3887 | {{ 4, 5}, { 4, 5}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3888 | {{ 6, 5}, { 6, 5}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3889 | {{ 6, 5}, { 6, 5}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3890 | }, | |
3891 | { /* TC 4: MLK1.2,3JIH */ | |
3892 | {{ 7, 7}, { 7, 7}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3893 | {{ 7, 7}, { 7, 7}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3894 | {{ 7, 7}, { 7, 7}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3895 | {{ 7, 7}, { 7, 7}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3896 | }, | |
3897 | { /* TC 5: FE.>12-> */ | |
3898 | {{ 8, 9}, { 8, 9}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3899 | {{10, 9}, { 8, 9}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3900 | {{ 8, 9}, { 8, 9}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3901 | {{10, 9}, { 8, 9}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3902 | }, | |
3903 | { /* TC 6: JIH.>12->a */ | |
3904 | {{11, 12}, {11, 12}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3905 | {{13, 14}, {11, 12}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3906 | {{11, 12}, {11, 12}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3907 | {{13, 14}, {11, 12}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3908 | }, | |
3909 | { /* TC 7: CBA.>67->89=a */ | |
3910 | {{18, 16}, {18, 16}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3911 | {{18, 17}, {18, 16}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3912 | {{18, 16}, {18, 16}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3913 | {{15, 17}, {18, 16}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3914 | }, | |
3915 | { /* TC 8: CBA.>124->xyz */ | |
3916 | {{19, 20}, {19, 20}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3917 | {{21, 22}, {19, 20}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3918 | {{19, 20}, {19, 20}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3919 | {{21, 22}, {19, 20}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3920 | }, | |
3921 | { /* TC 9: .>12->xyz */ | |
3922 | {{23, 24}, {23, 24}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3923 | {{23, 25}, {23, 24}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3924 | {{23, 24}, {23, 24}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3925 | {{23, 25}, {23, 24}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3926 | }, | |
3927 | { /* TC 10: a.>67->xyz */ | |
3928 | {{26, 26}, {26, 26}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3929 | {{26, 27}, {26, 28}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3930 | {{26, 28}, {26, 28}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3931 | {{26, 27}, {26, 28}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3932 | }, | |
3933 | { /* TC 11: 124JIH */ | |
3934 | {{30, 30}, {30, 30}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3935 | {{29, 30}, {29, 30}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3936 | {{30, 30}, {30, 30}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3937 | {{30, 30}, {30, 30}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3938 | }, | |
3939 | { /* TC 12: 124 JIH */ | |
3940 | {{32, 32}, {32, 32}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3941 | {{31, 32}, {31, 32}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3942 | {{31, 32}, {31, 32}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3943 | {{31, 32}, {31, 32}} /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3944 | } | |
3945 | }; | |
3946 | ||
3947 | static UBool | |
3948 | assertRoundTrip(UBiDi *pBiDi, int32_t tc, int32_t outIndex, const char *srcChars, | |
3949 | const char *destChars, const UChar *dest, int32_t destLen, | |
3950 | int mode, int option, UBiDiLevel level) { | |
3951 | ||
3952 | static const char roundtrip[TC_COUNT][MODES_COUNT][OPTIONS_COUNT] | |
3953 | [LEVELS_COUNT] = { | |
3954 | { /* TC 0: 123 */ | |
3955 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3956 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3957 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3958 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3959 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
3960 | }, | |
3961 | { /* TC 1: .123->4.5 */ | |
3962 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3963 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3964 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3965 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3966 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
3967 | }, | |
3968 | { /* TC 2: 678 */ | |
3969 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3970 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3971 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3972 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3973 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
3974 | }, | |
3975 | { /* TC 3: .678->8.9 */ | |
3976 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3977 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3978 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3979 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3980 | {{ 0, 0}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
3981 | }, | |
3982 | { /* TC 4: MLK1.2,3JIH */ | |
3983 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3984 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3985 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3986 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3987 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
3988 | }, | |
3989 | { /* TC 5: FE.>12-> */ | |
3990 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3991 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3992 | {{ 0, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
3993 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
3994 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
3995 | }, | |
3996 | { /* TC 6: JIH.>12->a */ | |
3997 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
3998 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
3999 | {{ 0, 0}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
4000 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
4001 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
4002 | }, | |
4003 | { /* TC 7: CBA.>67->89=a */ | |
4004 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
4005 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
4006 | {{ 0, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
4007 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
4008 | {{ 0, 0}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
4009 | }, | |
4010 | { /* TC 8: CBA.>123->xyz */ | |
4011 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
4012 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
4013 | {{ 0, 0}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
4014 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
4015 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
4016 | }, | |
4017 | { /* TC 9: .>12->xyz */ | |
4018 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
4019 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
4020 | {{ 1, 0}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
4021 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
4022 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
4023 | }, | |
4024 | { /* TC 10: a.>67->xyz */ | |
4025 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
4026 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
4027 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
4028 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
4029 | {{ 1, 0}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
4030 | }, | |
4031 | { /* TC 11: 123JIH */ | |
4032 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
4033 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
4034 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
4035 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
4036 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
4037 | }, | |
4038 | { /* TC 12: 123 JIH */ | |
4039 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_GROUP_NUMBERS_WITH_R */ | |
4040 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_LIKE_DIRECT */ | |
4041 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_NUMBERS_SPECIAL */ | |
4042 | {{ 1, 1}, { 1, 1}}, /* UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ | |
4043 | {{ 1, 1}, { 1, 1}} /* UBIDI_REORDER_INVERSE_NUMBERS_AS_L */ | |
4044 | } | |
4045 | }; | |
4046 | ||
4047 | #define SET_ROUND_TRIP_MODE(mode) \ | |
4048 | ubidi_setReorderingMode(pBiDi, mode); \ | |
4049 | desc = #mode; \ | |
4050 | break; | |
4051 | ||
4052 | UErrorCode rc = U_ZERO_ERROR; | |
4053 | UChar dest2[MAXLEN]; | |
4054 | int32_t destLen2; | |
4055 | const char* desc; | |
4056 | char destChars2[MAXLEN]; | |
4057 | char destChars3[MAXLEN]; | |
4058 | ||
4059 | switch (modes[mode].value) { | |
4060 | case UBIDI_REORDER_NUMBERS_SPECIAL: | |
4061 | SET_ROUND_TRIP_MODE(UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL) | |
4062 | case UBIDI_REORDER_GROUP_NUMBERS_WITH_R: | |
4063 | SET_ROUND_TRIP_MODE(UBIDI_REORDER_GROUP_NUMBERS_WITH_R) | |
4064 | case UBIDI_REORDER_RUNS_ONLY: | |
4065 | SET_ROUND_TRIP_MODE(UBIDI_REORDER_RUNS_ONLY) | |
4066 | case UBIDI_REORDER_INVERSE_NUMBERS_AS_L: | |
4067 | SET_ROUND_TRIP_MODE(UBIDI_REORDER_DEFAULT) | |
4068 | case UBIDI_REORDER_INVERSE_LIKE_DIRECT: | |
4069 | SET_ROUND_TRIP_MODE(UBIDI_REORDER_DEFAULT) | |
4070 | case UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL: | |
4071 | SET_ROUND_TRIP_MODE(UBIDI_REORDER_NUMBERS_SPECIAL) | |
4072 | default: | |
4073 | SET_ROUND_TRIP_MODE(UBIDI_REORDER_INVERSE_LIKE_DIRECT) | |
4074 | } | |
4075 | ubidi_setReorderingOptions(pBiDi, UBIDI_OPTION_REMOVE_CONTROLS); | |
4076 | ||
4077 | ubidi_setPara(pBiDi, dest, destLen, level, NULL, &rc); | |
4078 | assertSuccessful("ubidi_setPara", &rc); | |
4079 | *dest2 = 0; | |
4080 | destLen2 = ubidi_writeReordered(pBiDi, dest2, MAXLEN, UBIDI_DO_MIRRORING, | |
4081 | &rc); | |
4082 | assertSuccessful("ubidi_writeReordered", &rc); | |
4083 | ||
4084 | u16ToPseudo(destLen, dest, destChars3); | |
4085 | u16ToPseudo(destLen2, dest2, destChars2); | |
46f4442e | 4086 | checkWhatYouCan(pBiDi, destChars3, destChars2); |
73c04bcf A |
4087 | if (strcmp(srcChars, destChars2)) { |
4088 | if (roundtrip[tc][mode][option][level]) { | |
4089 | log_err("\nRound trip failed for case=%d mode=%d option=%d.\n" | |
4090 | "%20s %s\n%20s %s\n%20s %s\n%20s %s\n%20s %s" | |
4091 | "\n%20s %u\n", tc, mode, option, | |
4092 | "Original text:", srcChars, | |
4093 | "Round-tripped text:", destChars2, | |
4094 | "Intermediate text:", destChars3, | |
4095 | "Reordering mode:", modes[mode].description, | |
4096 | "Reordering option:", options[option].description, | |
4097 | "Paragraph level:", level); | |
4098 | } | |
4099 | else { | |
4100 | log_verbose("\nExpected round trip failure for case=%d mode=%d option=%d.\n" | |
4101 | "%20s %s\n%20s %s\n%20s %s\n%20s %s\n%20s %s" | |
4102 | "\n%20s %u\n", tc, mode, option, | |
4103 | "Original text:", srcChars, | |
4104 | "Round-tripped text:", destChars2, | |
4105 | "Intermediate text:", destChars3, | |
4106 | "Reordering mode:", modes[mode].description, | |
4107 | "Reordering option:", options[option].description, | |
4108 | "Paragraph level:", level); | |
4109 | } | |
4110 | return FALSE; | |
4111 | } | |
46f4442e | 4112 | if (!checkResultLength(pBiDi, destChars, destChars2, destLen2, |
73c04bcf A |
4113 | desc, "UBIDI_OPTION_REMOVE_CONTROLS", level)) { |
4114 | return FALSE; | |
4115 | } | |
46f4442e A |
4116 | if (outIndex > -1 && !checkMaps(pBiDi, outIndex, srcChars, destChars, |
4117 | desc, "UBIDI_OPTION_REMOVE_CONTROLS", | |
4118 | level, FALSE)) { | |
73c04bcf A |
4119 | return FALSE; |
4120 | } | |
4121 | return TRUE; | |
4122 | } | |
4123 | ||
4124 | static UBool | |
4125 | checkResultLength(UBiDi *pBiDi, const char *srcChars, const char *destChars, | |
46f4442e | 4126 | int32_t destLen, const char* mode, |
73c04bcf A |
4127 | const char* option, UBiDiLevel level) { |
4128 | int32_t actualLen; | |
4129 | if (strcmp(mode, "UBIDI_REORDER_INVERSE_NUMBERS_AS_L") == 0) | |
3d1f044b | 4130 | actualLen = (int32_t)strlen(destChars); |
73c04bcf A |
4131 | else |
4132 | actualLen = ubidi_getResultLength(pBiDi); | |
4133 | if (actualLen != destLen) { | |
4134 | log_err("\nubidi_getResultLength failed.\n%20s %7d\n%20s %7d\n" | |
4135 | "%20s %s\n%20s %s\n%20s %s\n%20s %s\n%20s %u\n", | |
4136 | "Expected:", destLen, "Actual:", actualLen, | |
4137 | "Input:", srcChars, "Output:", destChars, | |
4138 | "Reordering mode:", mode, "Reordering option:", option, | |
4139 | "Paragraph level:", level); | |
4140 | return FALSE; | |
4141 | } | |
4142 | return TRUE; | |
4143 | } | |
4144 | ||
4145 | static void | |
46f4442e | 4146 | testReorderRunsOnly(void) { |
73c04bcf A |
4147 | static const struct { |
4148 | const char* textIn; | |
4149 | const char* textOut[2][2]; | |
4150 | const char noroundtrip[2]; | |
4151 | } testCases[] = { | |
46f4442e | 4152 | {"ab 234 896 de", {{"de 896 ab 234", "de 896 ab 234"}, /*0*/ |
73c04bcf | 4153 | {"ab 234 @896@ de", "de 896 ab 234"}}, {0, 0}}, |
46f4442e A |
4154 | {"abcGHI", {{"GHIabc", "GHIabc"}, {"GHIabc", "GHIabc"}}, {0, 0}}, /*1*/ |
4155 | {"a.>67->", {{"<-67<.a", "<-67<.a"}, {"<-67<.a", "<-67<.a"}}, {0, 0}}, /*2*/ | |
4156 | {"-=%$123/ *", {{"* /%$123=-", "* /%$123=-"}, /*3*/ | |
73c04bcf | 4157 | {"* /%$123=-", "* /%$123=-"}}, {0, 0}}, |
46f4442e | 4158 | {"abc->12..>JKL", {{"JKL<..12<-abc", "JKL<..abc->12"}, /*4*/ |
73c04bcf | 4159 | {"JKL<..12<-abc", "JKL<..abc->12"}}, {0, 0}}, |
46f4442e | 4160 | {"JKL->12..>abc", {{"abc<..JKL->12", "abc<..12<-JKL"}, /*5*/ |
73c04bcf | 4161 | {"abc<..JKL->12", "abc<..12<-JKL"}}, {0, 0}}, |
46f4442e | 4162 | {"123->abc", {{"abc<-123", "abc<-123"}, /*6*/ |
73c04bcf | 4163 | {"abc&<-123", "abc<-123"}}, {1, 0}}, |
46f4442e | 4164 | {"123->JKL", {{"JKL<-123", "123->JKL"}, /*7*/ |
73c04bcf | 4165 | {"JKL<-123", "JKL<-@123"}}, {0, 1}}, |
46f4442e | 4166 | {"*>12.>34->JKL", {{"JKL<-34<.12<*", "12.>34->JKL<*"}, /*8*/ |
73c04bcf | 4167 | {"JKL<-34<.12<*", "JKL<-@34<.12<*"}}, {0, 1}}, |
46f4442e | 4168 | {"*>67.>89->JKL", {{"67.>89->JKL<*", "67.>89->JKL<*"}, /*9*/ |
73c04bcf | 4169 | {"67.>89->JKL<*", "67.>89->JKL<*"}}, {0, 0}}, |
46f4442e | 4170 | {"* /abc-=$%123", {{"$%123=-abc/ *", "abc-=$%123/ *"}, /*10*/ |
73c04bcf | 4171 | {"$%123=-abc/ *", "abc-=$%123/ *"}}, {0, 0}}, |
46f4442e | 4172 | {"* /$%def-=123", {{"123=-def%$/ *", "def-=123%$/ *"}, /*11*/ |
73c04bcf | 4173 | {"123=-def%$/ *", "def-=123%$/ *"}}, {0, 0}}, |
46f4442e | 4174 | {"-=GHI* /123%$", {{"GHI* /123%$=-", "123%$/ *GHI=-"}, /*12*/ |
73c04bcf | 4175 | {"GHI* /123%$=-", "123%$/ *GHI=-"}}, {0, 0}}, |
46f4442e | 4176 | {"-=%$JKL* /123", {{"JKL* /%$123=-", "123/ *JKL$%=-"}, /*13*/ |
73c04bcf | 4177 | {"JKL* /%$123=-", "123/ *JKL$%=-"}}, {0, 0}}, |
46f4442e | 4178 | {"ab =#CD *?450", {{"CD *?450#= ab", "450?* CD#= ab"}, /*14*/ |
73c04bcf | 4179 | {"CD *?450#= ab", "450?* CD#= ab"}}, {0, 0}}, |
46f4442e | 4180 | {"ab 234 896 de", {{"de 896 ab 234", "de 896 ab 234"}, /*15*/ |
73c04bcf | 4181 | {"ab 234 @896@ de", "de 896 ab 234"}}, {0, 0}}, |
46f4442e | 4182 | {"abc-=%$LMN* /123", {{"LMN* /%$123=-abc", "123/ *LMN$%=-abc"}, /*16*/ |
73c04bcf | 4183 | {"LMN* /%$123=-abc", "123/ *LMN$%=-abc"}}, {0, 0}}, |
46f4442e A |
4184 | {"123->JKL&MN&P", {{"JKLMNP<-123", "123->JKLMNP"}, /*17*/ |
4185 | {"JKLMNP<-123", "JKLMNP<-@123"}}, {0, 1}}, | |
4186 | {"123", {{"123", "123"}, /* just one run */ /*18*/ | |
4187 | {"123", "123"}}, {0, 0}} | |
73c04bcf A |
4188 | }; |
4189 | UBiDi *pBiDi = getBiDiObject(); | |
4190 | UBiDi *pL2VBiDi = getBiDiObject(); | |
4191 | UChar src[MAXLEN], dest[MAXLEN], visual1[MAXLEN], visual2[MAXLEN]; | |
4192 | char destChars[MAXLEN], vis1Chars[MAXLEN], vis2Chars[MAXLEN]; | |
46f4442e | 4193 | int32_t srcLen, destLen, vis1Len, vis2Len, option, i, j, nCases, paras; |
73c04bcf A |
4194 | UErrorCode rc = U_ZERO_ERROR; |
4195 | UBiDiLevel level; | |
46f4442e A |
4196 | |
4197 | log_verbose("\nEntering TestReorderRunsOnly\n\n"); | |
4198 | ||
73c04bcf A |
4199 | if(!pL2VBiDi) { |
4200 | ubidi_close(pBiDi); /* in case this one was allocated */ | |
4201 | return; | |
4202 | } | |
4203 | ubidi_setReorderingMode(pBiDi, UBIDI_REORDER_RUNS_ONLY); | |
4204 | ubidi_setReorderingOptions(pL2VBiDi, UBIDI_OPTION_REMOVE_CONTROLS); | |
4205 | ||
4206 | for (option = 0; option < 2; option++) { | |
4207 | ubidi_setReorderingOptions(pBiDi, option==0 ? UBIDI_OPTION_REMOVE_CONTROLS | |
4208 | : UBIDI_OPTION_INSERT_MARKS); | |
b331163b | 4209 | for (i = 0, nCases = UPRV_LENGTHOF(testCases); i < nCases; i++) { |
3d1f044b | 4210 | srcLen = (int32_t)strlen(testCases[i].textIn); |
73c04bcf A |
4211 | pseudoToU16(srcLen, testCases[i].textIn, src); |
4212 | for(j = 0; j < 2; j++) { | |
46f4442e A |
4213 | log_verbose("Now doing test for option %d, case %d, level %d\n", |
4214 | i, option, j); | |
73c04bcf A |
4215 | level = paraLevels[j]; |
4216 | ubidi_setPara(pBiDi, src, srcLen, level, NULL, &rc); | |
4217 | assertSuccessful("ubidi_setPara", &rc); | |
4218 | *dest = 0; | |
4219 | destLen = ubidi_writeReordered(pBiDi, dest, MAXLEN, UBIDI_DO_MIRRORING, &rc); | |
4220 | assertSuccessful("ubidi_writeReordered", &rc); | |
4221 | u16ToPseudo(destLen, dest, destChars); | |
46f4442e | 4222 | checkWhatYouCan(pBiDi, testCases[i].textIn, destChars); |
73c04bcf A |
4223 | assertStringsEqual(testCases[i].textOut[option][level], destChars, |
4224 | testCases[i].textIn, "UBIDI_REORDER_RUNS_ONLY", | |
4225 | option==0 ? "0" : "UBIDI_OPTION_INSERT_MARKS", | |
4226 | pBiDi); | |
4227 | ||
4228 | if((option==0) && testCases[i].noroundtrip[level]) { | |
4229 | continue; | |
4230 | } | |
4231 | ubidi_setPara(pL2VBiDi, src, srcLen, level, NULL, &rc); | |
4232 | assertSuccessful("ubidi_setPara1", &rc); | |
4233 | *visual1 = 0; | |
4234 | vis1Len = ubidi_writeReordered(pL2VBiDi, visual1, MAXLEN, UBIDI_DO_MIRRORING, &rc); | |
4235 | assertSuccessful("ubidi_writeReordered1", &rc); | |
4236 | u16ToPseudo(vis1Len, visual1, vis1Chars); | |
46f4442e | 4237 | checkWhatYouCan(pL2VBiDi, testCases[i].textIn, vis1Chars); |
73c04bcf A |
4238 | ubidi_setPara(pL2VBiDi, dest, destLen, level^1, NULL, &rc); |
4239 | assertSuccessful("ubidi_setPara2", &rc); | |
4240 | *visual2 = 0; | |
4241 | vis2Len = ubidi_writeReordered(pL2VBiDi, visual2, MAXLEN, UBIDI_DO_MIRRORING, &rc); | |
4242 | assertSuccessful("ubidi_writeReordered2", &rc); | |
4243 | u16ToPseudo(vis2Len, visual2, vis2Chars); | |
46f4442e | 4244 | checkWhatYouCan(pL2VBiDi, destChars, vis2Chars); |
73c04bcf A |
4245 | assertStringsEqual(vis1Chars, vis2Chars, |
4246 | testCases[i].textIn, "UBIDI_REORDER_RUNS_ONLY (2)", | |
4247 | option==0 ? "0" : "UBIDI_OPTION_INSERT_MARKS", | |
4248 | pBiDi); | |
4249 | } | |
4250 | } | |
4251 | } | |
46f4442e A |
4252 | |
4253 | /* test with null or empty text */ | |
4254 | ubidi_setPara(pBiDi, src, 0, UBIDI_LTR, NULL, &rc); | |
4255 | assertSuccessful("ubidi_setPara3", &rc); | |
4256 | paras = ubidi_countParagraphs(pBiDi); | |
4257 | if (paras != 0) { | |
4258 | log_err("\nInvalid number of paras (should be 0): %d\n", paras); | |
4259 | } | |
4260 | ||
73c04bcf A |
4261 | ubidi_close(pBiDi); |
4262 | ubidi_close(pL2VBiDi); | |
46f4442e A |
4263 | |
4264 | log_verbose("\nExiting TestReorderRunsOnly\n\n"); | |
73c04bcf A |
4265 | } |
4266 | ||
4267 | static void | |
46f4442e | 4268 | testReorderingMode(void) { |
73c04bcf A |
4269 | |
4270 | UChar src[MAXLEN], dest[MAXLEN]; | |
4271 | char destChars[MAXLEN]; | |
4272 | UBiDi *pBiDi = NULL, *pBiDi2 = NULL, *pBiDi3 = NULL; | |
4273 | UErrorCode rc; | |
4274 | int tc, mode, option, level; | |
46f4442e A |
4275 | uint32_t optionValue, optionBack; |
4276 | UBiDiReorderingMode modeValue, modeBack; | |
51004dcb | 4277 | int32_t srcLen, destLen, idx; |
73c04bcf A |
4278 | const char *expectedChars; |
4279 | UBool testOK = TRUE; | |
4280 | ||
46f4442e | 4281 | log_verbose("\nEntering TestReorderingMode\n\n"); |
73c04bcf A |
4282 | |
4283 | pBiDi = getBiDiObject(); | |
4284 | pBiDi2 = getBiDiObject(); | |
4285 | pBiDi3 = getBiDiObject(); | |
4286 | if(!pBiDi3) { | |
4287 | ubidi_close(pBiDi); /* in case this one was allocated */ | |
4288 | ubidi_close(pBiDi2); /* in case this one was allocated */ | |
4289 | return; | |
4290 | } | |
4291 | ||
4292 | ubidi_setInverse(pBiDi2, TRUE); | |
4293 | ||
4294 | for (tc = 0; tc < TC_COUNT; tc++) { | |
46f4442e | 4295 | const char *srcChars = textIn[tc]; |
3d1f044b | 4296 | srcLen = (int32_t)strlen(srcChars); |
73c04bcf A |
4297 | pseudoToU16(srcLen, srcChars, src); |
4298 | ||
4299 | for (mode = 0; mode < MODES_COUNT; mode++) { | |
4300 | modeValue = modes[mode].value; | |
4301 | ubidi_setReorderingMode(pBiDi, modeValue); | |
4302 | modeBack = ubidi_getReorderingMode(pBiDi); | |
4303 | if (modeValue != modeBack) { | |
4304 | log_err("Error while setting reordering mode to %d, returned %d\n", | |
4305 | modeValue, modeBack); | |
4306 | } | |
4307 | ||
4308 | for (option = 0; option < OPTIONS_COUNT; option++) { | |
4309 | optionValue = options[option].value; | |
4310 | ubidi_setReorderingOptions(pBiDi, optionValue); | |
4311 | optionBack = ubidi_getReorderingOptions(pBiDi); | |
4312 | if (optionValue != optionBack) { | |
4313 | log_err("Error while setting reordering option to %d, returned %d\n", | |
4314 | optionValue, optionBack); | |
4315 | } | |
4316 | ||
4317 | for (level = 0; level < LEVELS_COUNT; level++) { | |
4318 | log_verbose("starting test %d mode=%d option=%d level=%d\n", | |
4319 | tc, modes[mode].value, options[option].value, level); | |
4320 | rc = U_ZERO_ERROR; | |
4321 | ubidi_setPara(pBiDi, src, srcLen, paraLevels[level], NULL, &rc); | |
4322 | assertSuccessful("ubidi_setPara", &rc); | |
4323 | ||
4324 | *dest = 0; | |
4325 | destLen = ubidi_writeReordered(pBiDi, dest, MAXLEN, | |
4326 | UBIDI_DO_MIRRORING, &rc); | |
4327 | assertSuccessful("ubidi_writeReordered", &rc); | |
4328 | u16ToPseudo(destLen, dest, destChars); | |
46f4442e A |
4329 | if (!((modes[mode].value == UBIDI_REORDER_INVERSE_NUMBERS_AS_L) && |
4330 | (options[option].value == UBIDI_OPTION_INSERT_MARKS))) { | |
4331 | checkWhatYouCan(pBiDi, srcChars, destChars); | |
4332 | } | |
73c04bcf A |
4333 | |
4334 | if (modes[mode].value == UBIDI_REORDER_INVERSE_NUMBERS_AS_L) { | |
51004dcb | 4335 | idx = -1; |
46f4442e | 4336 | expectedChars = inverseBasic(pBiDi2, srcChars, srcLen, |
73c04bcf A |
4337 | options[option].value, paraLevels[level], destChars); |
4338 | } | |
4339 | else { | |
51004dcb A |
4340 | idx = outIndices[tc][mode][option][level]; |
4341 | expectedChars = textOut[idx]; | |
73c04bcf A |
4342 | } |
4343 | if (!assertStringsEqual(expectedChars, destChars, srcChars, | |
4344 | modes[mode].description, | |
4345 | options[option].description, | |
4346 | pBiDi)) { | |
4347 | testOK = FALSE; | |
4348 | } | |
46f4442e | 4349 | if (options[option].value == UBIDI_OPTION_INSERT_MARKS && |
51004dcb | 4350 | !assertRoundTrip(pBiDi3, tc, idx, srcChars, |
73c04bcf A |
4351 | destChars, dest, destLen, |
4352 | mode, option, paraLevels[level])) { | |
4353 | testOK = FALSE; | |
4354 | } | |
4355 | else if (!checkResultLength(pBiDi, srcChars, destChars, | |
46f4442e | 4356 | destLen, modes[mode].description, |
73c04bcf A |
4357 | options[option].description, |
4358 | paraLevels[level])) { | |
4359 | testOK = FALSE; | |
4360 | } | |
51004dcb | 4361 | else if (idx > -1 && !checkMaps(pBiDi, idx, srcChars, |
73c04bcf A |
4362 | destChars, modes[mode].description, |
4363 | options[option].description, paraLevels[level], | |
4364 | TRUE)) { | |
4365 | testOK = FALSE; | |
4366 | } | |
4367 | } | |
4368 | } | |
4369 | } | |
4370 | } | |
4371 | if (testOK == TRUE) { | |
4372 | log_verbose("\nReordering mode test OK\n"); | |
4373 | } | |
4374 | ubidi_close(pBiDi3); | |
4375 | ubidi_close(pBiDi2); | |
4376 | ubidi_close(pBiDi); | |
46f4442e A |
4377 | |
4378 | log_verbose("\nExiting TestReorderingMode\n\n"); | |
73c04bcf A |
4379 | } |
4380 | ||
46f4442e | 4381 | static const char* inverseBasic(UBiDi *pBiDi, const char *srcChars, int32_t srcLen, |
73c04bcf A |
4382 | uint32_t option, UBiDiLevel level, char *result) { |
4383 | UErrorCode rc = U_ZERO_ERROR; | |
4384 | int32_t destLen; | |
46f4442e | 4385 | UChar src[MAXLEN], dest2[MAXLEN]; |
73c04bcf | 4386 | |
b331163b | 4387 | if (pBiDi == NULL || srcChars == NULL) { |
73c04bcf A |
4388 | return NULL; |
4389 | } | |
4390 | ubidi_setReorderingOptions(pBiDi, option); | |
46f4442e | 4391 | pseudoToU16(srcLen, srcChars, src); |
73c04bcf A |
4392 | ubidi_setPara(pBiDi, src, srcLen, level, NULL, &rc); |
4393 | assertSuccessful("ubidi_setPara", &rc); | |
4394 | ||
4395 | *dest2 = 0; | |
4396 | destLen = ubidi_writeReordered(pBiDi, dest2, MAXLEN, | |
4397 | UBIDI_DO_MIRRORING, &rc); | |
4398 | assertSuccessful("ubidi_writeReordered", &rc); | |
4399 | u16ToPseudo(destLen, dest2, result); | |
46f4442e A |
4400 | if (!(option == UBIDI_OPTION_INSERT_MARKS)) { |
4401 | checkWhatYouCan(pBiDi, srcChars, result); | |
4402 | } | |
73c04bcf A |
4403 | return result; |
4404 | } | |
4405 | ||
4406 | #define NULL_CHAR '\0' | |
4407 | ||
4408 | static void | |
46f4442e | 4409 | testStreaming(void) { |
73c04bcf A |
4410 | #define MAXPORTIONS 10 |
4411 | ||
4412 | static const struct { | |
4413 | const char* textIn; | |
4414 | short int chunk; | |
4415 | short int nPortions[2]; | |
4416 | char portionLens[2][MAXPORTIONS]; | |
4417 | const char* message[2]; | |
4418 | } testData[] = { | |
4419 | { "123\\u000A" | |
4420 | "abc45\\u000D" | |
4421 | "67890\\u000A" | |
4422 | "\\u000D" | |
4423 | "02468\\u000D" | |
4424 | "ghi", | |
57a6839d A |
4425 | 6, { 6, 6 }, {{ 4, 6, 6, 1, 6, 3}, { 4, 6, 6, 1, 6, 3 }}, |
4426 | {"4, 6, 6, 1, 6, 3", "4, 6, 6, 1, 6, 3"} | |
73c04bcf A |
4427 | }, |
4428 | { "abcd\\u000Afgh\\u000D12345\\u000A456", | |
57a6839d A |
4429 | 6, { 4, 4 }, {{ 5, 4, 6, 3 }, { 5, 4, 6, 3 }}, |
4430 | {"5, 4, 6, 3", "5, 4, 6, 3"} | |
73c04bcf A |
4431 | }, |
4432 | { "abcd\\u000Afgh\\u000D12345\\u000A45\\u000D", | |
57a6839d A |
4433 | 6, { 4, 4 }, {{ 5, 4, 6, 3 }, { 5, 4, 6, 3 }}, |
4434 | {"5, 4, 6, 3", "5, 4, 6, 3"} | |
73c04bcf A |
4435 | }, |
4436 | { "abcde\\u000Afghi", | |
57a6839d A |
4437 | 10, { 2, 2 }, {{ 6, 4 }, { 6, 4 }}, |
4438 | {"6, 4", "6, 4"} | |
73c04bcf A |
4439 | } |
4440 | }; | |
4441 | UChar src[MAXLEN]; | |
4442 | UBiDi *pBiDi = NULL; | |
4443 | UChar *pSrc; | |
4444 | UErrorCode rc = U_ZERO_ERROR; | |
4445 | int32_t srcLen, processedLen, chunk, len, nPortions; | |
4446 | int i, j, levelIndex; | |
4447 | UBiDiLevel level; | |
b331163b | 4448 | int nTests = UPRV_LENGTHOF(testData), nLevels = UPRV_LENGTHOF(paraLevels); |
73c04bcf | 4449 | UBool mismatch, testOK = TRUE; |
57a6839d | 4450 | char processedLenStr[MAXPORTIONS * 5]; |
73c04bcf | 4451 | |
46f4442e | 4452 | log_verbose("\nEntering TestStreaming\n\n"); |
73c04bcf A |
4453 | |
4454 | pBiDi = getBiDiObject(); | |
4455 | ||
4456 | ubidi_orderParagraphsLTR(pBiDi, TRUE); | |
4457 | ||
4458 | for (levelIndex = 0; levelIndex < nLevels; levelIndex++) { | |
4459 | for (i = 0; i < nTests; i++) { | |
4460 | srcLen = u_unescape(testData[i].textIn, src, MAXLEN); | |
4461 | chunk = testData[i].chunk; | |
4462 | nPortions = testData[i].nPortions[levelIndex]; | |
4463 | level = paraLevels[levelIndex]; | |
57a6839d | 4464 | processedLenStr[0] = NULL_CHAR; |
46f4442e | 4465 | log_verbose("Testing level %d, case %d\n", level, i); |
73c04bcf A |
4466 | |
4467 | mismatch = FALSE; | |
4468 | ||
4469 | ubidi_setReorderingOptions(pBiDi, UBIDI_OPTION_STREAMING); | |
4470 | for (j = 0, pSrc = src; j < MAXPORTIONS && srcLen > 0; j++) { | |
4471 | ||
4472 | len = chunk < srcLen ? chunk : srcLen; | |
4473 | ubidi_setPara(pBiDi, pSrc, len, level, NULL, &rc); | |
46f4442e A |
4474 | if (!assertSuccessful("ubidi_setPara", &rc)) { |
4475 | break; | |
4476 | } | |
73c04bcf A |
4477 | |
4478 | processedLen = ubidi_getProcessedLength(pBiDi); | |
4479 | if (processedLen == 0) { | |
4480 | ubidi_setReorderingOptions(pBiDi, UBIDI_OPTION_DEFAULT); | |
4481 | j--; | |
4482 | continue; | |
4483 | } | |
4484 | ubidi_setReorderingOptions(pBiDi, UBIDI_OPTION_STREAMING); | |
4485 | ||
57a6839d | 4486 | mismatch |= (UBool)(j >= nPortions || |
46f4442e | 4487 | processedLen != testData[i].portionLens[levelIndex][j]); |
73c04bcf A |
4488 | |
4489 | sprintf(processedLenStr + j * 4, "%4d", processedLen); | |
4490 | srcLen -= processedLen, pSrc += processedLen; | |
4491 | } | |
4492 | ||
4493 | if (mismatch || j != nPortions) { | |
4494 | testOK = FALSE; | |
4495 | log_err("\nProcessed lengths mismatch.\n" | |
4496 | "\tParagraph level: %u\n" | |
4497 | "\tInput string: %s\n" | |
4498 | "\tActually processed portion lengths: { %s }\n" | |
4499 | "\tExpected portion lengths : { %s }\n", | |
4500 | paraLevels[levelIndex], testData[i].textIn, | |
4501 | processedLenStr, testData[i].message[levelIndex]); | |
4502 | } | |
4503 | } | |
4504 | } | |
4505 | ubidi_close(pBiDi); | |
4506 | if (testOK == TRUE) { | |
4507 | log_verbose("\nBiDi streaming test OK\n"); | |
4508 | } | |
46f4442e | 4509 | log_verbose("\nExiting TestStreaming\n\n"); |
73c04bcf A |
4510 | } |
4511 | ||
4512 | U_CDECL_BEGIN | |
4513 | ||
4514 | static UCharDirection U_CALLCONV | |
4515 | overrideBidiClass(const void *context, UChar32 c) { | |
4516 | ||
4517 | #define DEF U_BIDI_CLASS_DEFAULT | |
4518 | ||
4519 | static const UCharDirection customClasses[] = { | |
4520 | /* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ | |
4521 | DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 00-07 */ | |
4522 | DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 08-0F */ | |
4523 | DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 10-17 */ | |
4524 | DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 18-1F */ | |
4525 | DEF, DEF, DEF, DEF, DEF, DEF, R, DEF, /* 20-27 */ | |
4526 | DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 28-2F */ | |
4527 | EN, EN, EN, EN, EN, EN, AN, AN, /* 30-37 */ | |
4528 | AN, AN, DEF, DEF, DEF, DEF, DEF, DEF, /* 38-3F */ | |
4529 | L, AL, AL, AL, AL, AL, AL, R, /* 40-47 */ | |
4530 | R, R, R, R, R, R, R, R, /* 48-4F */ | |
4531 | R, R, R, R, R, R, R, R, /* 50-57 */ | |
4532 | R, R, R, LRE, DEF, RLE, PDF, S, /* 58-5F */ | |
4533 | NSM, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 60-67 */ | |
4534 | DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 68-6F */ | |
4535 | DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, /* 70-77 */ | |
4536 | DEF, DEF, DEF, LRO, B, RLO, BN, DEF /* 78-7F */ | |
4537 | }; | |
b331163b | 4538 | static const int nEntries = UPRV_LENGTHOF(customClasses); |
46f4442e A |
4539 | const char *dummy = context; /* just to avoid a compiler warning */ |
4540 | dummy++; | |
73c04bcf A |
4541 | |
4542 | return c >= nEntries ? U_BIDI_CLASS_DEFAULT : customClasses[c]; | |
4543 | } | |
4544 | ||
4545 | U_CDECL_END | |
4546 | ||
4547 | static void verifyCallbackParams(UBiDiClassCallback* fn, const void* context, | |
4548 | UBiDiClassCallback* expectedFn, | |
4549 | const void* expectedContext, | |
4550 | int32_t sizeOfContext) { | |
4551 | if (fn != expectedFn) { | |
4552 | log_err("Class callback pointer is not set properly.\n"); | |
4553 | } | |
4554 | if (context != expectedContext) { | |
4555 | log_err("Class callback context is not set properly.\n"); | |
4556 | } | |
4557 | else if (context != NULL && | |
4558 | memcmp(context, expectedContext, sizeOfContext)) { | |
4559 | log_err("Callback context content doesn't match the expected one.\n"); | |
4560 | } | |
4561 | } | |
4562 | ||
46f4442e A |
4563 | static void |
4564 | testClassOverride(void) { | |
73c04bcf A |
4565 | static const char* const textSrc = "JIH.>12->a \\u05D0\\u05D1 6 ABC78"; |
4566 | static const char* const textResult = "12<.HIJ->a 78CBA 6 \\u05D1\\u05D0"; | |
4567 | ||
4568 | UChar src[MAXLEN], dest[MAXLEN]; | |
4569 | UErrorCode rc = U_ZERO_ERROR; | |
4570 | UBiDi *pBiDi = NULL; | |
4571 | UBiDiClassCallback* oldFn = NULL; | |
4572 | UBiDiClassCallback* newFn = overrideBidiClass; | |
4573 | const void* oldContext = NULL; | |
4574 | int32_t srcLen, destLen, textSrcSize = (int32_t)uprv_strlen(textSrc); | |
4575 | char* destChars = NULL; | |
4576 | ||
46f4442e | 4577 | log_verbose("\nEntering TestClassOverride\n\n"); |
73c04bcf A |
4578 | |
4579 | pBiDi = getBiDiObject(); | |
4580 | if(!pBiDi) { | |
4581 | return; | |
4582 | } | |
4583 | ||
4584 | ubidi_getClassCallback(pBiDi, &oldFn, &oldContext); | |
4585 | verifyCallbackParams(oldFn, oldContext, NULL, NULL, 0); | |
4586 | ||
4587 | ubidi_setClassCallback(pBiDi, newFn, textSrc, &oldFn, &oldContext, &rc); | |
4588 | if (!assertSuccessful("ubidi_setClassCallback", &rc)) { | |
4589 | ubidi_close(pBiDi); | |
4590 | return; | |
4591 | } | |
4592 | verifyCallbackParams(oldFn, oldContext, NULL, NULL, 0); | |
4593 | ||
4594 | ubidi_getClassCallback(pBiDi, &oldFn, &oldContext); | |
4595 | verifyCallbackParams(oldFn, oldContext, newFn, textSrc, textSrcSize); | |
4596 | ||
4597 | ubidi_setClassCallback(pBiDi, newFn, textSrc, &oldFn, &oldContext, &rc); | |
4598 | if (!assertSuccessful("ubidi_setClassCallback", &rc)) { | |
4599 | ubidi_close(pBiDi); | |
4600 | return; | |
4601 | } | |
4602 | verifyCallbackParams(oldFn, oldContext, newFn, textSrc, textSrcSize); | |
4603 | ||
4604 | srcLen = u_unescape(textSrc, src, MAXLEN); | |
4605 | ubidi_setPara(pBiDi, src, srcLen, UBIDI_LTR, NULL, &rc); | |
4606 | assertSuccessful("ubidi_setPara", &rc); | |
4607 | ||
4608 | destLen = ubidi_writeReordered(pBiDi, dest, MAXLEN, | |
4609 | UBIDI_DO_MIRRORING, &rc); | |
4610 | assertSuccessful("ubidi_writeReordered", &rc); | |
4611 | ||
4612 | destChars = aescstrdup(dest, destLen); | |
4613 | if (uprv_strcmp(textResult, destChars)) { | |
4614 | log_err("\nActual and expected output mismatch.\n" | |
4615 | "%20s %s\n%20s %s\n%20s %s\n", | |
4616 | "Input:", textSrc, "Actual output:", destChars, | |
4617 | "Expected output:", textResult); | |
4618 | } | |
4619 | else { | |
4620 | log_verbose("\nClass override test OK\n"); | |
4621 | } | |
4622 | ubidi_close(pBiDi); | |
46f4442e | 4623 | log_verbose("\nExiting TestClassOverride\n\n"); |
73c04bcf A |
4624 | } |
4625 | ||
4626 | static char * formatMap(const int32_t * map, int len, char * buffer) | |
4627 | { | |
4628 | int32_t i, k; | |
4629 | char c; | |
4630 | for (i = 0; i < len; i++) { | |
4631 | k = map[i]; | |
4632 | if (k < 0) | |
4633 | c = '-'; | |
340931cb | 4634 | else if (k >= (int32_t)sizeof(columns)) |
73c04bcf A |
4635 | c = '+'; |
4636 | else | |
4637 | c = columns[k]; | |
4638 | buffer[i] = c; | |
4639 | } | |
4640 | buffer[len] = '\0'; | |
4641 | return buffer; | |
4642 | } | |
4643 | ||
4644 | static UBool | |
46f4442e A |
4645 | checkMaps(UBiDi *pBiDi, int32_t stringIndex, const char *src, const char *dest, |
4646 | const char *mode, const char* option, UBiDiLevel level, UBool forward) | |
73c04bcf A |
4647 | { |
4648 | int32_t actualLogicalMap[MAX_MAP_LENGTH]; | |
4649 | int32_t actualVisualMap[MAX_MAP_LENGTH]; | |
4650 | int32_t getIndexMap[MAX_MAP_LENGTH]; | |
51004dcb | 4651 | int32_t i, srcLen, resLen, idx; |
73c04bcf A |
4652 | const int32_t *expectedLogicalMap, *expectedVisualMap; |
4653 | UErrorCode rc = U_ZERO_ERROR; | |
4654 | UBool testOK = TRUE; | |
4655 | ||
4656 | if (forward) { | |
4657 | expectedLogicalMap = forwardMap[stringIndex]; | |
4658 | expectedVisualMap = inverseMap[stringIndex]; | |
4659 | } | |
4660 | else { | |
4661 | expectedLogicalMap = inverseMap[stringIndex]; | |
4662 | expectedVisualMap = forwardMap[stringIndex]; | |
4663 | } | |
4664 | ubidi_getLogicalMap(pBiDi, actualLogicalMap, &rc); | |
4665 | if (!assertSuccessful("ubidi_getLogicalMap", &rc)) { | |
4666 | testOK = FALSE; | |
4667 | } | |
4668 | srcLen = ubidi_getProcessedLength(pBiDi); | |
4669 | if (memcmp(expectedLogicalMap, actualLogicalMap, srcLen * sizeof(int32_t))) { | |
4670 | char expChars[MAX_MAP_LENGTH]; | |
4671 | char actChars[MAX_MAP_LENGTH]; | |
4672 | log_err("\nubidi_getLogicalMap() returns unexpected map for output string " | |
4673 | "index %d\n" | |
4674 | "source: %s\n" | |
4675 | "dest : %s\n" | |
4676 | "Scale : %s\n" | |
4677 | "ExpMap: %s\n" | |
4678 | "Actual: %s\n" | |
4679 | "Paragraph level : %d == %d\n" | |
4680 | "Reordering mode : %s == %d\n" | |
4681 | "Reordering option: %s == %d\n" | |
4682 | "Forward flag : %d\n", | |
4683 | stringIndex, src, dest, columns, | |
4684 | formatMap(expectedLogicalMap, srcLen, expChars), | |
4685 | formatMap(actualLogicalMap, srcLen, actChars), | |
4686 | level, ubidi_getParaLevel(pBiDi), | |
4687 | mode, ubidi_getReorderingMode(pBiDi), | |
4688 | option, ubidi_getReorderingOptions(pBiDi), | |
4689 | forward | |
4690 | ); | |
4691 | testOK = FALSE; | |
4692 | } | |
4693 | resLen = ubidi_getResultLength(pBiDi); | |
4694 | ubidi_getVisualMap(pBiDi, actualVisualMap, &rc); | |
4695 | assertSuccessful("ubidi_getVisualMap", &rc); | |
4696 | if (memcmp(expectedVisualMap, actualVisualMap, resLen * sizeof(int32_t))) { | |
4697 | char expChars[MAX_MAP_LENGTH]; | |
4698 | char actChars[MAX_MAP_LENGTH]; | |
4699 | log_err("\nubidi_getVisualMap() returns unexpected map for output string " | |
4700 | "index %d\n" | |
4701 | "source: %s\n" | |
4702 | "dest : %s\n" | |
4703 | "Scale : %s\n" | |
4704 | "ExpMap: %s\n" | |
4705 | "Actual: %s\n" | |
4706 | "Paragraph level : %d == %d\n" | |
4707 | "Reordering mode : %s == %d\n" | |
4708 | "Reordering option: %s == %d\n" | |
4709 | "Forward flag : %d\n", | |
4710 | stringIndex, src, dest, columns, | |
4711 | formatMap(expectedVisualMap, resLen, expChars), | |
4712 | formatMap(actualVisualMap, resLen, actChars), | |
4713 | level, ubidi_getParaLevel(pBiDi), | |
4714 | mode, ubidi_getReorderingMode(pBiDi), | |
4715 | option, ubidi_getReorderingOptions(pBiDi), | |
4716 | forward | |
4717 | ); | |
4718 | testOK = FALSE; | |
4719 | } | |
4720 | for (i = 0; i < srcLen; i++) { | |
51004dcb | 4721 | idx = ubidi_getVisualIndex(pBiDi, i, &rc); |
73c04bcf | 4722 | assertSuccessful("ubidi_getVisualIndex", &rc); |
51004dcb | 4723 | getIndexMap[i] = idx; |
73c04bcf A |
4724 | } |
4725 | if (memcmp(actualLogicalMap, getIndexMap, srcLen * sizeof(int32_t))) { | |
4726 | char actChars[MAX_MAP_LENGTH]; | |
4727 | char gotChars[MAX_MAP_LENGTH]; | |
4728 | log_err("\nMismatch between ubidi_getLogicalMap and ubidi_getVisualIndex for output string " | |
4729 | "index %d\n" | |
4730 | "source: %s\n" | |
4731 | "dest : %s\n" | |
4732 | "Scale : %s\n" | |
4733 | "ActMap: %s\n" | |
4734 | "IdxMap: %s\n" | |
4735 | "Paragraph level : %d == %d\n" | |
4736 | "Reordering mode : %s == %d\n" | |
4737 | "Reordering option: %s == %d\n" | |
4738 | "Forward flag : %d\n", | |
4739 | stringIndex, src, dest, columns, | |
4740 | formatMap(actualLogicalMap, srcLen, actChars), | |
4741 | formatMap(getIndexMap, srcLen, gotChars), | |
4742 | level, ubidi_getParaLevel(pBiDi), | |
4743 | mode, ubidi_getReorderingMode(pBiDi), | |
4744 | option, ubidi_getReorderingOptions(pBiDi), | |
4745 | forward | |
4746 | ); | |
4747 | testOK = FALSE; | |
4748 | } | |
4749 | for (i = 0; i < resLen; i++) { | |
51004dcb | 4750 | idx = ubidi_getLogicalIndex(pBiDi, i, &rc); |
73c04bcf | 4751 | assertSuccessful("ubidi_getLogicalIndex", &rc); |
51004dcb | 4752 | getIndexMap[i] = idx; |
73c04bcf A |
4753 | } |
4754 | if (memcmp(actualVisualMap, getIndexMap, resLen * sizeof(int32_t))) { | |
4755 | char actChars[MAX_MAP_LENGTH]; | |
4756 | char gotChars[MAX_MAP_LENGTH]; | |
4757 | log_err("\nMismatch between ubidi_getVisualMap and ubidi_getLogicalIndex for output string " | |
4758 | "index %d\n" | |
4759 | "source: %s\n" | |
4760 | "dest : %s\n" | |
4761 | "Scale : %s\n" | |
4762 | "ActMap: %s\n" | |
4763 | "IdxMap: %s\n" | |
4764 | "Paragraph level : %d == %d\n" | |
4765 | "Reordering mode : %s == %d\n" | |
4766 | "Reordering option: %s == %d\n" | |
4767 | "Forward flag : %d\n", | |
4768 | stringIndex, src, dest, columns, | |
4769 | formatMap(actualVisualMap, resLen, actChars), | |
4770 | formatMap(getIndexMap, resLen, gotChars), | |
4771 | level, ubidi_getParaLevel(pBiDi), | |
4772 | mode, ubidi_getReorderingMode(pBiDi), | |
4773 | option, ubidi_getReorderingOptions(pBiDi), | |
4774 | forward | |
4775 | ); | |
4776 | testOK = FALSE; | |
4777 | } | |
4778 | return testOK; | |
4779 | } | |
4780 | ||
4388f060 A |
4781 | static UBool |
4782 | assertIllegalArgument(const char* message, UErrorCode* rc) { | |
4783 | if (*rc != U_ILLEGAL_ARGUMENT_ERROR) { | |
4784 | log_err("%s() failed with error %s.\n", message, myErrorName(*rc)); | |
4785 | return FALSE; | |
4786 | } | |
4787 | return TRUE; | |
4788 | } | |
4789 | ||
4790 | typedef struct { | |
4791 | const char* prologue; | |
4792 | const char* source; | |
4793 | const char* epilogue; | |
4794 | const char* expected; | |
4795 | UBiDiLevel paraLevel; | |
4796 | } contextCase; | |
4797 | ||
4798 | static const contextCase contextData[] = { | |
4799 | /*00*/ {"", "", "", "", UBIDI_LTR}, | |
4800 | /*01*/ {"", ".-=JKL-+*", "", ".-=LKJ-+*", UBIDI_LTR}, | |
4801 | /*02*/ {" ", ".-=JKL-+*", " ", ".-=LKJ-+*", UBIDI_LTR}, | |
4802 | /*03*/ {"a", ".-=JKL-+*", "b", ".-=LKJ-+*", UBIDI_LTR}, | |
4803 | /*04*/ {"D", ".-=JKL-+*", "", "LKJ=-.-+*", UBIDI_LTR}, | |
4804 | /*05*/ {"", ".-=JKL-+*", " D", ".-=*+-LKJ", UBIDI_LTR}, | |
4805 | /*06*/ {"", ".-=JKL-+*", " 2", ".-=*+-LKJ", UBIDI_LTR}, | |
4806 | /*07*/ {"", ".-=JKL-+*", " 7", ".-=*+-LKJ", UBIDI_LTR}, | |
4807 | /*08*/ {" G 1", ".-=JKL-+*", " H", "*+-LKJ=-.", UBIDI_LTR}, | |
4808 | /*09*/ {"7", ".-=JKL-+*", " H", ".-=*+-LKJ", UBIDI_LTR}, | |
4809 | /*10*/ {"", ".-=abc-+*", "", "*+-abc=-.", UBIDI_RTL}, | |
4810 | /*11*/ {" ", ".-=abc-+*", " ", "*+-abc=-.", UBIDI_RTL}, | |
4811 | /*12*/ {"D", ".-=abc-+*", "G", "*+-abc=-.", UBIDI_RTL}, | |
4812 | /*13*/ {"x", ".-=abc-+*", "", "*+-.-=abc", UBIDI_RTL}, | |
4813 | /*14*/ {"", ".-=abc-+*", " y", "abc-+*=-.", UBIDI_RTL}, | |
4814 | /*15*/ {"", ".-=abc-+*", " 2", "abc-+*=-.", UBIDI_RTL}, | |
4815 | /*16*/ {" x 1", ".-=abc-+*", " 2", ".-=abc-+*", UBIDI_RTL}, | |
4816 | /*17*/ {" x 7", ".-=abc-+*", " 8", "*+-.-=abc", UBIDI_RTL}, | |
4817 | /*18*/ {"x|", ".-=abc-+*", " 8", "*+-abc=-.", UBIDI_RTL}, | |
4818 | /*19*/ {"G|y", ".-=abc-+*", " 8", "*+-.-=abc", UBIDI_RTL}, | |
4819 | /*20*/ {"", ".-=", "", ".-=", UBIDI_DEFAULT_LTR}, | |
4820 | /*21*/ {"D", ".-=", "", "=-.", UBIDI_DEFAULT_LTR}, | |
4821 | /*22*/ {"G", ".-=", "", "=-.", UBIDI_DEFAULT_LTR}, | |
4822 | /*23*/ {"xG", ".-=", "", ".-=", UBIDI_DEFAULT_LTR}, | |
4823 | /*24*/ {"x|G", ".-=", "", "=-.", UBIDI_DEFAULT_LTR}, | |
4824 | /*25*/ {"x|G", ".-=|-+*", "", "=-.|-+*", UBIDI_DEFAULT_LTR}, | |
4825 | }; | |
b331163b | 4826 | #define CONTEXT_COUNT UPRV_LENGTHOF(contextData) |
4388f060 A |
4827 | |
4828 | static void | |
4829 | testContext(void) { | |
4830 | ||
4831 | UChar prologue[MAXLEN], epilogue[MAXLEN], src[MAXLEN], dest[MAXLEN]; | |
4832 | char destChars[MAXLEN]; | |
4833 | UBiDi *pBiDi = NULL; | |
4834 | UErrorCode rc; | |
4835 | int32_t proLength, epiLength, srcLen, destLen, tc; | |
4836 | contextCase cc; | |
4837 | UBool testOK = TRUE; | |
4838 | ||
4839 | log_verbose("\nEntering TestContext \n\n"); | |
4840 | ||
4841 | /* test null BiDi object */ | |
4842 | rc = U_ZERO_ERROR; | |
4843 | ubidi_setContext(pBiDi, NULL, 0, NULL, 0, &rc); | |
4844 | testOK &= assertIllegalArgument("Error when BiDi object is null", &rc); | |
4845 | ||
4846 | pBiDi = getBiDiObject(); | |
4847 | ubidi_orderParagraphsLTR(pBiDi, TRUE); | |
4848 | ||
4849 | /* test proLength < -1 */ | |
4850 | rc = U_ZERO_ERROR; | |
4851 | ubidi_setContext(pBiDi, NULL, -2, NULL, 0, &rc); | |
4852 | testOK &= assertIllegalArgument("Error when proLength < -1", &rc); | |
4853 | /* test epiLength < -1 */ | |
4854 | rc = U_ZERO_ERROR; | |
4855 | ubidi_setContext(pBiDi, NULL, 0, NULL, -2, &rc); | |
4856 | testOK &= assertIllegalArgument("Error when epiLength < -1", &rc); | |
4857 | /* test prologue == NULL */ | |
4858 | rc = U_ZERO_ERROR; | |
4859 | ubidi_setContext(pBiDi, NULL, 3, NULL, 0, &rc); | |
4860 | testOK &= assertIllegalArgument("Prologue is NULL", &rc); | |
4861 | /* test epilogue == NULL */ | |
4862 | rc = U_ZERO_ERROR; | |
4863 | ubidi_setContext(pBiDi, NULL, 0, NULL, 4, &rc); | |
4864 | testOK &= assertIllegalArgument("Epilogue is NULL", &rc); | |
4865 | ||
4866 | for (tc = 0; tc < CONTEXT_COUNT; tc++) { | |
4867 | cc = contextData[tc]; | |
3d1f044b | 4868 | proLength = (int32_t)strlen(cc.prologue); |
4388f060 | 4869 | pseudoToU16(proLength, cc.prologue, prologue); |
3d1f044b | 4870 | epiLength = (int32_t)strlen(cc.epilogue); |
4388f060 A |
4871 | pseudoToU16(epiLength, cc.epilogue, epilogue); |
4872 | /* in the call below, prologue and epilogue are swapped to show | |
4873 | that the next call will override this call */ | |
4874 | rc = U_ZERO_ERROR; | |
4875 | ubidi_setContext(pBiDi, epilogue, epiLength, prologue, proLength, &rc); | |
4876 | testOK &= assertSuccessful("swapped ubidi_setContext", &rc); | |
4877 | ubidi_setContext(pBiDi, prologue, -1, epilogue, -1, &rc); | |
4878 | testOK &= assertSuccessful("regular ubidi_setContext", &rc); | |
3d1f044b | 4879 | srcLen = (int32_t)strlen(cc.source); |
4388f060 A |
4880 | pseudoToU16(srcLen, cc.source, src); |
4881 | ubidi_setPara(pBiDi, src, srcLen, cc.paraLevel, NULL, &rc); | |
4882 | testOK &= assertSuccessful("ubidi_setPara", &rc); | |
4883 | destLen = ubidi_writeReordered(pBiDi, dest, MAXLEN, UBIDI_DO_MIRRORING, &rc); | |
4884 | assertSuccessful("ubidi_writeReordered", &rc); | |
4885 | u16ToPseudo(destLen, dest, destChars); | |
4886 | if (uprv_strcmp(cc.expected, destChars)) { | |
4887 | char formatChars[MAXLEN]; | |
4888 | log_err("\nActual and expected output mismatch on case %d.\n" | |
4889 | "%20s %s\n%20s %s\n%20s %s\n%20s %s\n%20s %s\n%20s %s\n%20s %d\n%20s %u\n%20s %d\n", | |
4890 | tc, | |
4891 | "Prologue:", cc.prologue, | |
4892 | "Input:", cc.source, | |
4893 | "Epilogue:", cc.epilogue, | |
4894 | "Expected output:", cc.expected, | |
4895 | "Actual output:", destChars, | |
4896 | "Levels:", formatLevels(pBiDi, formatChars), | |
4897 | "Reordering mode:", ubidi_getReorderingMode(pBiDi), | |
4898 | "Paragraph level:", ubidi_getParaLevel(pBiDi), | |
4899 | "Reordering option:", ubidi_getReorderingOptions(pBiDi)); | |
4900 | testOK = FALSE; | |
4901 | } | |
4902 | } | |
4903 | if (testOK == TRUE) { | |
4904 | log_verbose("\nContext test OK\n"); | |
4905 | } | |
4906 | ubidi_close(pBiDi); | |
4907 | ||
4908 | log_verbose("\nExiting TestContext \n\n"); | |
4909 | } | |
b331163b A |
4910 | |
4911 | /* Ticket#11054 ubidi_setPara crash with heavily nested brackets */ | |
4912 | static void | |
4913 | testBracketOverflow(void) { | |
4914 | static const char* TEXT = "(((((((((((((((((((((((((((((((((((((((((a)(A)))))))))))))))))))))))))))))))))))))))))"; | |
4915 | UErrorCode status = U_ZERO_ERROR; | |
4916 | UBiDi* bidi; | |
4917 | UChar src[100]; | |
4918 | int32_t len; | |
4919 | ||
4920 | bidi = ubidi_open(); | |
3d1f044b | 4921 | len = (int32_t)uprv_strlen(TEXT); |
b331163b A |
4922 | pseudoToU16(len, TEXT, src); |
4923 | ubidi_setPara(bidi, src, len, UBIDI_DEFAULT_LTR , NULL, &status); | |
4924 | if (U_FAILURE(status)) { | |
4925 | log_err("setPara failed with heavily nested brackets - %s", u_errorName(status)); | |
4926 | } | |
4927 | ||
4928 | ubidi_close(bidi); | |
4929 | } | |
4930 | ||
3d1f044b | 4931 | static void TestExplicitLevel0(void) { |
f3c0d7a5 A |
4932 | // The following used to fail with an error, see ICU ticket #12922. |
4933 | static const UChar text[2] = { 0x202d, 0x05d0 }; | |
4934 | static UBiDiLevel embeddings[2] = { 0, 0 }; | |
4935 | UErrorCode errorCode = U_ZERO_ERROR; | |
4936 | UBiDi *bidi = ubidi_open(); | |
4937 | ubidi_setPara(bidi, text, 2, UBIDI_DEFAULT_LTR , embeddings, &errorCode); | |
4938 | if (U_FAILURE(errorCode)) { | |
4939 | log_err("ubidi_setPara() - %s", u_errorName(errorCode)); | |
4940 | } else { | |
4941 | UBiDiLevel level0 = ubidi_getLevelAt(bidi, 0); | |
4942 | UBiDiLevel level1 = ubidi_getLevelAt(bidi, 1); | |
4943 | if (level0 != 1 || level1 != 1) { | |
4944 | log_err("resolved levels != 1: { %d, %d }\n", level0, level1); | |
4945 | } | |
4946 | if (embeddings[0] != 1 || embeddings[1] != 1) { | |
4947 | log_err("modified embeddings[] levels != 1: { %d, %d }\n", embeddings[0], embeddings[1]); | |
4948 | } | |
4949 | } | |
4950 | ubidi_close(bidi); | |
4951 | } |