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