/******************************************************************** * © 2016 and later: Unicode, Inc. and others. * License & terms of use: http://www.unicode.org/copyright.html ********************************************************************/ /* file name: cbiditransformtst.c * encoding: UTF-8 * tab size: 8 (not used) * indentation:4 * * created on: 2016aug21 * created by: Lina Kemmel */ #include "cintltst.h" #include "unicode/ubidi.h" #include "unicode/ubiditransform.h" #include "unicode/ushape.h" #include "unicode/ustring.h" #include "unicode/utf16.h" #ifdef __cplusplus extern "C" { #endif #define LATN_ZERO 0x0030 #define ARAB_ZERO 0x0660 #define MIN_HEB_LETTER 0x05D0 #define MIN_ARAB_LETTER 0x0630 /* relevant to this test only */ #define MIN_SHAPED_LETTER 0xFEAB /* relevant to this test only */ #define STR_CAPACITY 100 #define NUM_LETTERS 5 /* Used for arrays hereafter */ static const UChar unshapedLetters[NUM_LETTERS + 1] = {0x0630, 0, 0x0631, 0, 0x0632, 2}; static const UChar shapedLetters [NUM_LETTERS + 1] = {0xfeab, 0, 0xfead, 0, 0xfeaf, 1}; typedef struct { UBiDiLevel inLevel; UBiDiOrder inOr; UBiDiLevel outLevel; UBiDiOrder outOr; const char *pReorderNoMirror; const char *pReorderAndMirror; const char *pContextShapes; const char *pMessage; } UBidiTestCases; UChar src[STR_CAPACITY] = { 0 }; UChar dest[STR_CAPACITY] = { 0 }; UChar expected[STR_CAPACITY] = { 0 }; UChar temp[STR_CAPACITY * 2] = { 0 }; char pseudo[STR_CAPACITY] = { 0 }; void addBidiTransformTest(TestNode** root); static void testAutoDirection(void); static void testAllTransformOptions(void); static char* pseudoScript(const UChar *str); static void shapeDigits(UChar *str, UChar srcZero, UChar destZero); static void shapeLetters(UChar *str, const UChar *from, const UChar *to); static void logResultsForDir(const UChar *srcText, const UChar *destTxt, const UChar *expectedTxt, UBiDiLevel inLevel, UBiDiLevel outLevel); static void verifyResultsForAllOpt(const UBidiTestCases *pTest, const UChar *srcTxt, const UChar *destTxt, const char *expectedChars, uint32_t digits, uint32_t letters); #if 0 static void substituteByPseudoChar(const UChar *src, char *dest, const UChar baseReal, const char basePseudo, const char max); /* TODO: This code assumes the codepage is ASCII based. */ /* * Using the following conventions: * AL unshaped: A-E * AL shaped: F-J * R: K-Z * EN: 0-4 * AN: 5-9 */ static void substituteByPseudoChar(const UChar *src, char *dest, const UChar baseReal, const char basePseudo, const char max) { *dest = basePseudo + (*src - baseReal); /* (range math won't work on EBCDIC) */ if (*dest > max) { *dest = max; } } static char* pseudoScript(const UChar *str) { char *p = pseudo; if (str) { for (; *str; str++, p++) { switch (u_charDirection(*str)) { case U_RIGHT_TO_LEFT: substituteByPseudoChar(str, p, MIN_HEB_LETTER, 'K', 'Z'); break; case U_RIGHT_TO_LEFT_ARABIC: if (*str > 0xFE00) { substituteByPseudoChar(str, p, MIN_SHAPED_LETTER, 'F', 'J'); } else { substituteByPseudoChar(str, p, MIN_ARAB_LETTER, 'A', 'E'); } break; case U_ARABIC_NUMBER: substituteByPseudoChar(str, p, ARAB_ZERO, '5', '9'); break; default: *p = (char)*str; break; } } } *p = '\0'; return pseudo; } #else static char* pseudoScript(const UChar *str) { return aescstrdup(str, -1); } #endif static void logResultsForDir(const UChar *srcTxt, const UChar *destTxt, const UChar *expectedTxt, UBiDiLevel inLevel, UBiDiLevel outLevel) { if (u_strcmp(expectedTxt, destTxt)) { log_err("Unexpected transform Dest: inLevel: 0x%02x; outLevel: 0x%02x;\ninText: %s; outText: %s; expected: %s\n", inLevel, outLevel, pseudoScript(srcTxt), pseudoScript(destTxt), pseudoScript(expectedTxt)); } } /** * Tests various combinations of base directions, with the input either * UBIDI_DEFAULT_LTR or UBIDI_DEFAULT_RTL, and the * output either UBIDI_LTR or UBIDI_RTL. Order is * always UBIDI_LOGICAL for the input and UBIDI_VISUAL * for the output. */ static void testAutoDirection(void) { static const UBiDiLevel inLevels[] = { UBIDI_DEFAULT_LTR, UBIDI_DEFAULT_RTL }; static const UBiDiLevel outLevels[] = { UBIDI_LTR, UBIDI_RTL }; static const char *srcTexts[] = { "abc \\u05d0\\u05d1", "... abc \\u05d0\\u05d1", "\\u05d0\\u05d1 abc", "... \\u05d0\\u05d1 abc", ".*:" }; uint32_t nTexts = sizeof(srcTexts) / sizeof(srcTexts[0]); uint32_t i, nInLevels = sizeof(inLevels) / sizeof(inLevels[0]); uint32_t j, nOutLevels = sizeof(outLevels) / sizeof(outLevels[0]); UBiDi *pBidi = ubidi_open(); UErrorCode errorCode = U_ZERO_ERROR; UBiDiTransform *pTransform = ubiditransform_open(&errorCode); while (nTexts-- > 0) { uint32_t srcLen; u_unescape(srcTexts[nTexts], src, STR_CAPACITY); srcLen = u_strlen(src); for (i = 0; i < nInLevels; i++) { for (j = 0; j < nOutLevels; j++) { ubiditransform_transform(pTransform, src, -1, dest, STR_CAPACITY - 1, inLevels[i], UBIDI_LOGICAL, outLevels[j], UBIDI_VISUAL, UBIDI_MIRRORING_OFF, 0, &errorCode); /* Use UBiDi as a model we compare to */ ubidi_setPara(pBidi, src, srcLen, inLevels[i], NULL, &errorCode); ubidi_writeReordered(pBidi, expected, STR_CAPACITY, UBIDI_REORDER_DEFAULT, &errorCode); if (outLevels[j] == UBIDI_RTL) { ubidi_writeReverse(expected, u_strlen(expected), temp, STR_CAPACITY, UBIDI_OUTPUT_REVERSE, &errorCode); logResultsForDir(src, dest, temp, inLevels[i], outLevels[j]); } else { logResultsForDir(src, dest, expected, inLevels[i], outLevels[j]); } } } } ubidi_close(pBidi); ubiditransform_close(pTransform); } static void shapeDigits(UChar *str, UChar srcZero, UChar destZero) { UChar32 c = 0; uint32_t i = 0, j, length = u_strlen(str); while (i < length) { j = i; U16_NEXT(str, i, length, c); if (c >= srcZero && c <= srcZero + 9) { /* length of c here is always a single UChar16 */ str[j] = c + (destZero - srcZero); } } } static void shapeLetters(UChar *str, const UChar *from, const UChar *to) { uint32_t i = 0, j, length = u_strlen(expected), index; UChar32 c = 0; while (i < length) { j = i; U16_NEXT(str, i, length, c); index = c - from[0]; if (index < NUM_LETTERS && from[index * from[NUM_LETTERS]] != 0) { /* The length of old and new values is always a single UChar16, so can just assign a new value to str[j] */ str[j] = to[index * from[NUM_LETTERS]]; } } } static void verifyResultsForAllOpt(const UBidiTestCases *pTest, const UChar *srcTxt, const UChar *destTxt, const char *expectedChars, uint32_t digits, uint32_t letters) { u_unescape(expectedChars, expected, STR_CAPACITY); switch (digits) { case U_SHAPE_DIGITS_EN2AN: shapeDigits(expected, LATN_ZERO, ARAB_ZERO); break; case U_SHAPE_DIGITS_AN2EN: shapeDigits(expected, ARAB_ZERO, LATN_ZERO); break; default: break; } switch (letters) { case U_SHAPE_LETTERS_SHAPE: shapeLetters(expected, unshapedLetters, shapedLetters); break; case U_SHAPE_LETTERS_UNSHAPE: shapeLetters(expected, shapedLetters, unshapedLetters); break; } if (u_strcmp(expected, dest)) { log_err("Unexpected transform Dest: Test: %s; Digits: 0x%08x; Letters: 0x%08x\ninText: %s; outText: %s; expected: %s\n", pTest->pMessage, digits, letters, pseudoScript(srcTxt), pseudoScript(destTxt), pseudoScript(expected)); } } /** * This function covers: * */ static void testAllTransformOptions(void) { static const char *inText = "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662"; static const UBidiTestCases testCases[] = { { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_LOGICAL, "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // reordering no mirroring "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u0662\\u0663\\u0660 e\\u0631\\u0664 f \\ufeaf \\u0661\\u0662", // context numeric shaping "1: Logical LTR ==> Logical LTR" }, { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf", "2: Logical LTR ==> Visual LTR" }, { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_LOGICAL, "\\ufeaf \\u0661\\u0662 f \\u0631e4 \\u0630 23\\u0660 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 a[b]c", "\\ufeaf \\u0661\\u0662 f \\u0631e4 \\u0630 23\\u0660 d \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 a[b]c", "\\ufeaf \\u0661\\u0662 f \\u0631e\\u0664 \\u0630 \\u0662\\u0663\\u0660 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 a[b]c", "3: Logical LTR ==> Logical RTL" }, { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_VISUAL, "\\ufeaf \\u0662\\u0661 f \\u06314e \\u0630 \\u066032 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 c]b[a", "\\ufeaf \\u0662\\u0661 f \\u06314e \\u0630 \\u066032 d \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 c]b[a", "\\ufeaf \\u0662\\u0661 f \\u0631\\u0664e \\u0630 \\u0660\\u0663\\u0662 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 c]b[a", "4: Logical LTR ==> Visual RTL" }, { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_LOGICAL, "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", "5: Logical RTL ==> Logical RTL" }, { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_VISUAL, "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "6: Logical RTL ==> Visual RTL" }, { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_LOGICAL, "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 a[b]c", "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 a[b]c", "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 a[b]c", "7: Logical RTL ==> Logical LTR" }, { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 a[b]c", "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", "8: Logical RTL ==> Visual LTR" }, { UBIDI_LTR, UBIDI_VISUAL, UBIDI_LTR, UBIDI_VISUAL, "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u0662\\u0663\\u0660 e\\u0631\\u0664 f \\ufeaf \\u0661\\u0662", "9: Visual LTR ==> Visual LTR" }, { UBIDI_LTR, UBIDI_VISUAL, UBIDI_LTR, UBIDI_LOGICAL, "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "10: Visual LTR ==> Logical LTR" }, { UBIDI_LTR, UBIDI_VISUAL, UBIDI_RTL, UBIDI_VISUAL, "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 c]b[a", "\\u0662\\u0661 \\ufeaf f \\u0664\\u0631e \\u0660\\u0663\\u0662 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", "11: Visual LTR ==> Visual RTL" }, { UBIDI_LTR, UBIDI_VISUAL, UBIDI_RTL, UBIDI_LOGICAL, "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 a[b]c", "\\u0661\\u0662 \\ufeaf f \\u0664\\u0631e \\u0662\\u0663\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", "12: Visual LTR ==> Logical RTL" }, { UBIDI_RTL, UBIDI_VISUAL, UBIDI_RTL, UBIDI_VISUAL, "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", "13: Visual RTL ==> Visual RTL" }, { UBIDI_RTL, UBIDI_VISUAL, UBIDI_RTL, UBIDI_LOGICAL, "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "14: Visual RTL ==> Logical RTL" }, { UBIDI_RTL, UBIDI_VISUAL, UBIDI_LTR, UBIDI_VISUAL, "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 c]b[a", "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", "15: Visual RTL ==> Visual LTR" }, { UBIDI_RTL, UBIDI_VISUAL, UBIDI_LTR, UBIDI_LOGICAL, "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 c]b[a", "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 c]b[a", "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 c]b[a", "16: Visual RTL ==> Logical LTR" }, { UBIDI_DEFAULT_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf", "17: Logical DEFAULT_RTL ==> Visual LTR" }, { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_DEFAULT_LTR, UBIDI_VISUAL, "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "18: Logical RTL ==> Visual DEFAULT_LTR" }, { UBIDI_DEFAULT_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf", "19: Logical DEFAULT_LTR ==> Visual LTR" }, { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_DEFAULT_RTL, UBIDI_VISUAL, "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", "20: Logical RTL ==> Visual DEFAULT_RTL" } }; static const uint32_t digits[] = { U_SHAPE_DIGITS_NOOP, U_SHAPE_DIGITS_AN2EN, U_SHAPE_DIGITS_EN2AN, U_SHAPE_DIGITS_ALEN2AN_INIT_LR }; static const uint32_t letters[] = { U_SHAPE_LETTERS_UNSHAPE, U_SHAPE_LETTERS_SHAPE }; const char *expectedStr; uint32_t i, nTestCases = sizeof(testCases) / sizeof(testCases[0]); uint32_t j, nDigits = sizeof(digits) / sizeof(digits[0]); uint32_t k, nLetters = sizeof(letters) / sizeof(letters[0]); UErrorCode errorCode = U_ZERO_ERROR; UBiDiTransform *pTransform = ubiditransform_open(&errorCode); u_unescape(inText, src, STR_CAPACITY); // Test various combinations of base levels, orders, mirroring, digits and letters for (i = 0; i < nTestCases; i++) { expectedStr = testCases[i].pReorderAndMirror; ubiditransform_transform(pTransform, src, -1, dest, STR_CAPACITY, testCases[i].inLevel, testCases[i].inOr, testCases[i].outLevel, testCases[i].outOr, UBIDI_MIRRORING_ON, 0, &errorCode); verifyResultsForAllOpt(&testCases[i], src, dest, expectedStr, U_SHAPE_DIGITS_NOOP, U_SHAPE_LETTERS_NOOP); for (j = 0; j < nDigits; j++) { expectedStr = digits[j] == U_SHAPE_DIGITS_ALEN2AN_INIT_LR ? testCases[i].pContextShapes : testCases[i].pReorderNoMirror; for (k = 0; k < nLetters; k++) { /* Use here NULL for pTransform */ ubiditransform_transform(NULL, src, -1, dest, STR_CAPACITY, testCases[i].inLevel, testCases[i].inOr, testCases[i].outLevel, testCases[i].outOr, UBIDI_MIRRORING_OFF, digits[j] | letters[k], &errorCode); verifyResultsForAllOpt(&testCases[i], src, dest, expectedStr, digits[j], letters[k]); } } } ubiditransform_close(pTransform); } void addBidiTransformTest(TestNode** root) { addTest(root, testAutoDirection, "complex/bidi-transform/TestAutoDirection"); addTest(root, testAllTransformOptions, "complex/bidi-transform/TestAllTransformOptions"); } #ifdef __cplusplus } #endif