1 /********************************************************************
2 * © 2016 and later: Unicode, Inc. and others.
3 * License & terms of use: http://www.unicode.org/copyright.html
4 ********************************************************************/
5 /* file name: cbiditransformtst.c
6 * encoding: UTF-8
7 * tab size: 8 (not used)
8 * indentation:4
9 *
10 * created on: 2016aug21
11 * created by: Lina Kemmel
12 */
13
14 #include "cintltst.h"
15 #include "unicode/ubidi.h"
16 #include "unicode/ubiditransform.h"
17 #include "unicode/ushape.h"
18 #include "unicode/ustring.h"
19 #include "unicode/utf16.h"
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 #define LATN_ZERO 0x0030
26 #define ARAB_ZERO 0x0660
27 #define MIN_HEB_LETTER 0x05D0
28 #define MIN_ARAB_LETTER 0x0630 /* relevant to this test only */
29 #define MIN_SHAPED_LETTER 0xFEAB /* relevant to this test only */
30
31 #define STR_CAPACITY 100
32
33 #define NUM_LETTERS 5 /* Used for arrays hereafter */
34 static const UChar unshapedLetters[NUM_LETTERS + 1] = {0x0630, 0, 0x0631, 0, 0x0632, 2};
35 static const UChar shapedLetters [NUM_LETTERS + 1] = {0xfeab, 0, 0xfead, 0, 0xfeaf, 1};
36
37 typedef struct {
38 UBiDiLevel inLevel;
39 UBiDiOrder inOr;
40 UBiDiLevel outLevel;
41 UBiDiOrder outOr;
42 const char *pReorderNoMirror;
43 const char *pReorderAndMirror;
44 const char *pContextShapes;
45 const char *pMessage;
46 } UBidiTestCases;
47
48 UChar src[STR_CAPACITY] = { 0 };
49 UChar dest[STR_CAPACITY] = { 0 };
50 UChar expected[STR_CAPACITY] = { 0 };
51 UChar temp[STR_CAPACITY * 2] = { 0 };
52 char pseudo[STR_CAPACITY] = { 0 };
53
54 void addBidiTransformTest(TestNode** root);
55
56 static void testAutoDirection(void);
57
58 static void testAllTransformOptions(void);
59
60 static char* pseudoScript(const UChar *str);
61
62 static void shapeDigits(UChar *str, UChar srcZero, UChar destZero);
63
64 static void shapeLetters(UChar *str, const UChar *from, const UChar *to);
65
66 static void logResultsForDir(const UChar *srcText, const UChar *destTxt,
67 const UChar *expectedTxt, UBiDiLevel inLevel, UBiDiLevel outLevel);
68
69 static void verifyResultsForAllOpt(const UBidiTestCases *pTest, const UChar *srcTxt,
70 const UChar *destTxt, const char *expectedChars, uint32_t digits,
71 uint32_t letters);
72
73 #if 0
74 static void substituteByPseudoChar(const UChar *src, char *dest,
75 const UChar baseReal, const char basePseudo, const char max);
76
77
78 /* TODO: This code assumes the codepage is ASCII based. */
79
80 /*
81 * Using the following conventions:
82 * AL unshaped: A-E
83 * AL shaped: F-J
84 * R: K-Z
85 * EN: 0-4
86 * AN: 5-9
87 */
88 static void
89 substituteByPseudoChar(const UChar *src, char *dest, const UChar baseReal,
90 const char basePseudo, const char max) {
91 *dest = basePseudo + (*src - baseReal); /* (range math won't work on EBCDIC) */
92 if (*dest > max) {
93 *dest = max;
94 }
95 }
96
97 static char*
98 pseudoScript(const UChar *str) {
99 char *p = pseudo;
100 if (str) {
101 for (; *str; str++, p++) {
102 switch (u_charDirection(*str)) {
103 case U_RIGHT_TO_LEFT:
104 substituteByPseudoChar(str, p, MIN_HEB_LETTER, 'K', 'Z');
105 break;
106 case U_RIGHT_TO_LEFT_ARABIC:
107 if (*str > 0xFE00) {
108 substituteByPseudoChar(str, p, MIN_SHAPED_LETTER, 'F', 'J');
109 } else {
110 substituteByPseudoChar(str, p, MIN_ARAB_LETTER, 'A', 'E');
111 }
112 break;
113 case U_ARABIC_NUMBER:
114 substituteByPseudoChar(str, p, ARAB_ZERO, '5', '9');
115 break;
116 default:
117 *p = (char)*str;
118 break;
119 }
120 }
121 }
122 *p = '\0';
123 return pseudo;
124 }
125 #else
126 static char*
pseudoScript(const UChar * str)127 pseudoScript(const UChar *str) {
128 return aescstrdup(str, -1);
129 }
130 #endif
131
132 static void
logResultsForDir(const UChar * srcTxt,const UChar * destTxt,const UChar * expectedTxt,UBiDiLevel inLevel,UBiDiLevel outLevel)133 logResultsForDir(const UChar *srcTxt, const UChar *destTxt, const UChar *expectedTxt,
134 UBiDiLevel inLevel, UBiDiLevel outLevel)
135 {
136 if (u_strcmp(expectedTxt, destTxt)) {
137 log_err("Unexpected transform Dest: inLevel: 0x%02x; outLevel: 0x%02x;\ninText: %s; outText: %s; expected: %s\n",
138 inLevel, outLevel, pseudoScript(srcTxt), pseudoScript(destTxt), pseudoScript(expectedTxt));
139 }
140 }
141
142 /**
143 * Tests various combinations of base directions, with the input either
144 * <code>UBIDI_DEFAULT_LTR</code> or <code>UBIDI_DEFAULT_RTL</code>, and the
145 * output either <code>UBIDI_LTR</code> or <code>UBIDI_RTL</code>. Order is
146 * always <code>UBIDI_LOGICAL</code> for the input and <code>UBIDI_VISUAL</code>
147 * for the output.
148 */
149 static void
testAutoDirection(void)150 testAutoDirection(void)
151 {
152 static const UBiDiLevel inLevels[] = {
153 UBIDI_DEFAULT_LTR, UBIDI_DEFAULT_RTL
154 };
155 static const UBiDiLevel outLevels[] = {
156 UBIDI_LTR, UBIDI_RTL
157 };
158 static const char *srcTexts[] = {
159 "abc \\u05d0\\u05d1",
160 "... abc \\u05d0\\u05d1",
161 "\\u05d0\\u05d1 abc",
162 "... \\u05d0\\u05d1 abc",
163 ".*:"
164 };
165 uint32_t nTexts = sizeof(srcTexts) / sizeof(srcTexts[0]);
166 uint32_t i, nInLevels = sizeof(inLevels) / sizeof(inLevels[0]);
167 uint32_t j, nOutLevels = sizeof(outLevels) / sizeof(outLevels[0]);
168
169 UBiDi *pBidi = ubidi_open();
170
171 UErrorCode errorCode = U_ZERO_ERROR;
172 UBiDiTransform *pTransform = ubiditransform_open(&errorCode);
173
174 while (nTexts-- > 0) {
175 uint32_t srcLen;
176 u_unescape(srcTexts[nTexts], src, STR_CAPACITY);
177 srcLen = u_strlen(src);
178 for (i = 0; i < nInLevels; i++) {
179 for (j = 0; j < nOutLevels; j++) {
180 ubiditransform_transform(pTransform, src, -1, dest, STR_CAPACITY - 1,
181 inLevels[i], UBIDI_LOGICAL, outLevels[j], UBIDI_VISUAL,
182 UBIDI_MIRRORING_OFF, 0, &errorCode);
183 /* Use UBiDi as a model we compare to */
184 ubidi_setPara(pBidi, src, srcLen, inLevels[i], NULL, &errorCode);
185 ubidi_writeReordered(pBidi, expected, STR_CAPACITY, UBIDI_REORDER_DEFAULT, &errorCode);
186 if (outLevels[j] == UBIDI_RTL) {
187 ubidi_writeReverse(expected, u_strlen(expected), temp, STR_CAPACITY,
188 UBIDI_OUTPUT_REVERSE, &errorCode);
189 logResultsForDir(src, dest, temp, inLevels[i], outLevels[j]);
190 } else {
191 logResultsForDir(src, dest, expected, inLevels[i], outLevels[j]);
192 }
193 }
194 }
195 }
196 ubidi_close(pBidi);
197 ubiditransform_close(pTransform);
198 }
199
200 static void
shapeDigits(UChar * str,UChar srcZero,UChar destZero)201 shapeDigits(UChar *str, UChar srcZero, UChar destZero)
202 {
203 UChar32 c = 0;
204 uint32_t i = 0, j, length = u_strlen(str);
205 while (i < length) {
206 j = i;
207 U16_NEXT(str, i, length, c);
208 if (c >= srcZero && c <= srcZero + 9) {
209 /* length of c here is always a single UChar16 */
210 str[j] = c + (destZero - srcZero);
211 }
212 }
213 }
214
215 static void
shapeLetters(UChar * str,const UChar * from,const UChar * to)216 shapeLetters(UChar *str, const UChar *from, const UChar *to)
217 {
218 uint32_t i = 0, j, length = u_strlen(expected), index;
219 UChar32 c = 0;
220 while (i < length) {
221 j = i;
222 U16_NEXT(str, i, length, c);
223 index = c - from[0];
224 if (index < NUM_LETTERS && from[index * from[NUM_LETTERS]] != 0) {
225 /* The length of old and new values is always a single UChar16,
226 so can just assign a new value to str[j] */
227 str[j] = to[index * from[NUM_LETTERS]];
228 }
229 }
230 }
231
232 static void
verifyResultsForAllOpt(const UBidiTestCases * pTest,const UChar * srcTxt,const UChar * destTxt,const char * expectedChars,uint32_t digits,uint32_t letters)233 verifyResultsForAllOpt(const UBidiTestCases *pTest, const UChar *srcTxt,
234 const UChar *destTxt, const char *expectedChars, uint32_t digits, uint32_t letters)
235 {
236 u_unescape(expectedChars, expected, STR_CAPACITY);
237
238 switch (digits) {
239 case U_SHAPE_DIGITS_EN2AN:
240 shapeDigits(expected, LATN_ZERO, ARAB_ZERO);
241 break;
242 case U_SHAPE_DIGITS_AN2EN:
243 shapeDigits(expected, ARAB_ZERO, LATN_ZERO);
244 break;
245 default:
246 break;
247 }
248 switch (letters) {
249 case U_SHAPE_LETTERS_SHAPE:
250 shapeLetters(expected, unshapedLetters, shapedLetters);
251 break;
252 case U_SHAPE_LETTERS_UNSHAPE:
253 shapeLetters(expected, shapedLetters, unshapedLetters);
254 break;
255 }
256 if (u_strcmp(expected, dest)) {
257 log_err("Unexpected transform Dest: Test: %s; Digits: 0x%08x; Letters: 0x%08x\ninText: %s; outText: %s; expected: %s\n",
258 pTest->pMessage, digits, letters, pseudoScript(srcTxt), pseudoScript(destTxt), pseudoScript(expected));
259 }
260 }
261
262 /**
263 * This function covers:
264 * <ul>
265 * <li>all possible combinations of ordering schemes and <strong>explicit</strong>
266 * base directions, applied to both input and output,</li>
267 * <li>selected tests for auto direction (systematically, auto direction is
268 * covered in a dedicated test) applied on both input and output,</li>
269 * <li>all possible combinations of mirroring, digits and letters applied
270 * to output only.</li>
271 * </ul>
272 */
273 static void
testAllTransformOptions(void)274 testAllTransformOptions(void)
275 {
276 static const char *inText =
277 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662";
278
279 static const UBidiTestCases testCases[] = {
280 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_LOGICAL,
281 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // reordering no mirroring
282 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring
283 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u0662\\u0663\\u0660 e\\u0631\\u0664 f \\ufeaf \\u0661\\u0662", // context numeric shaping
284 "1: Logical LTR ==> Logical LTR" },
285 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL,
286 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
287 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
288 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf",
289 "2: Logical LTR ==> Visual LTR" },
290 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_LOGICAL,
291 "\\ufeaf \\u0661\\u0662 f \\u0631e4 \\u0630 23\\u0660 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 a[b]c",
292 "\\ufeaf \\u0661\\u0662 f \\u0631e4 \\u0630 23\\u0660 d \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 a[b]c",
293 "\\ufeaf \\u0661\\u0662 f \\u0631e\\u0664 \\u0630 \\u0662\\u0663\\u0660 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 a[b]c",
294 "3: Logical LTR ==> Logical RTL" },
295 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_VISUAL,
296 "\\ufeaf \\u0662\\u0661 f \\u06314e \\u0630 \\u066032 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 c]b[a",
297 "\\ufeaf \\u0662\\u0661 f \\u06314e \\u0630 \\u066032 d \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 c]b[a",
298 "\\ufeaf \\u0662\\u0661 f \\u0631\\u0664e \\u0630 \\u0660\\u0663\\u0662 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 c]b[a",
299 "4: Logical LTR ==> Visual RTL" },
300 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_LOGICAL,
301 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662",
302 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring
303 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662",
304 "5: Logical RTL ==> Logical RTL" },
305 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_VISUAL,
306 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
307 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
308 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
309 "6: Logical RTL ==> Visual RTL" },
310 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_LOGICAL,
311 "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 a[b]c",
312 "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 a[b]c",
313 "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 a[b]c",
314 "7: Logical RTL ==> Logical LTR" },
315 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL,
316 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c",
317 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 a[b]c",
318 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c",
319 "8: Logical RTL ==> Visual LTR" },
320 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_LTR, UBIDI_VISUAL,
321 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662",
322 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring
323 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u0662\\u0663\\u0660 e\\u0631\\u0664 f \\ufeaf \\u0661\\u0662",
324 "9: Visual LTR ==> Visual LTR" },
325 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_LTR, UBIDI_LOGICAL,
326 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
327 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
328 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
329 "10: Visual LTR ==> Logical LTR" },
330 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_RTL, UBIDI_VISUAL,
331 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a",
332 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 c]b[a",
333 "\\u0662\\u0661 \\ufeaf f \\u0664\\u0631e \\u0660\\u0663\\u0662 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a",
334 "11: Visual LTR ==> Visual RTL" },
335 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_RTL, UBIDI_LOGICAL,
336 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c",
337 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 a[b]c",
338 "\\u0661\\u0662 \\ufeaf f \\u0664\\u0631e \\u0662\\u0663\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c",
339 "12: Visual LTR ==> Logical RTL" },
340 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_RTL, UBIDI_VISUAL,
341 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662",
342 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662",
343 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662",
344 "13: Visual RTL ==> Visual RTL" },
345 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_RTL, UBIDI_LOGICAL,
346 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
347 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
348 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
349 "14: Visual RTL ==> Logical RTL" },
350 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_LTR, UBIDI_VISUAL,
351 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a",
352 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 c]b[a",
353 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a",
354 "15: Visual RTL ==> Visual LTR" },
355 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_LTR, UBIDI_LOGICAL,
356 "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 c]b[a",
357 "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 c]b[a",
358 "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 c]b[a",
359 "16: Visual RTL ==> Logical LTR" },
360 { UBIDI_DEFAULT_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL,
361 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
362 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
363 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf",
364 "17: Logical DEFAULT_RTL ==> Visual LTR" },
365 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_DEFAULT_LTR, UBIDI_VISUAL,
366 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
367 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
368 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
369 "18: Logical RTL ==> Visual DEFAULT_LTR" },
370 { UBIDI_DEFAULT_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL,
371 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
372 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf",
373 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf",
374 "19: Logical DEFAULT_LTR ==> Visual LTR" },
375 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_DEFAULT_RTL, UBIDI_VISUAL,
376 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
377 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
378 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661",
379 "20: Logical RTL ==> Visual DEFAULT_RTL" }
380 };
381 static const uint32_t digits[] = {
382 U_SHAPE_DIGITS_NOOP,
383 U_SHAPE_DIGITS_AN2EN,
384 U_SHAPE_DIGITS_EN2AN,
385 U_SHAPE_DIGITS_ALEN2AN_INIT_LR
386 };
387 static const uint32_t letters[] = {
388 U_SHAPE_LETTERS_UNSHAPE,
389 U_SHAPE_LETTERS_SHAPE
390 };
391 const char *expectedStr;
392 uint32_t i, nTestCases = sizeof(testCases) / sizeof(testCases[0]);
393 uint32_t j, nDigits = sizeof(digits) / sizeof(digits[0]);
394 uint32_t k, nLetters = sizeof(letters) / sizeof(letters[0]);
395
396 UErrorCode errorCode = U_ZERO_ERROR;
397 UBiDiTransform *pTransform = ubiditransform_open(&errorCode);
398
399 u_unescape(inText, src, STR_CAPACITY);
400
401 // Test various combinations of base levels, orders, mirroring, digits and letters
402 for (i = 0; i < nTestCases; i++) {
403 expectedStr = testCases[i].pReorderAndMirror;
404 ubiditransform_transform(pTransform, src, -1, dest, STR_CAPACITY,
405 testCases[i].inLevel, testCases[i].inOr,
406 testCases[i].outLevel, testCases[i].outOr,
407 UBIDI_MIRRORING_ON, 0, &errorCode);
408 verifyResultsForAllOpt(&testCases[i], src, dest, expectedStr, U_SHAPE_DIGITS_NOOP,
409 U_SHAPE_LETTERS_NOOP);
410
411 for (j = 0; j < nDigits; j++) {
412 expectedStr = digits[j] == U_SHAPE_DIGITS_ALEN2AN_INIT_LR ? testCases[i].pContextShapes
413 : testCases[i].pReorderNoMirror;
414 for (k = 0; k < nLetters; k++) {
415 /* Use here NULL for pTransform */
416 ubiditransform_transform(NULL, src, -1, dest, STR_CAPACITY,
417 testCases[i].inLevel, testCases[i].inOr,
418 testCases[i].outLevel, testCases[i].outOr,
419 UBIDI_MIRRORING_OFF, digits[j] | letters[k],
420 &errorCode);
421 verifyResultsForAllOpt(&testCases[i], src, dest, expectedStr, digits[j],
422 letters[k]);
423 }
424 }
425 }
426 ubiditransform_close(pTransform);
427 }
428
429 void
addBidiTransformTest(TestNode ** root)430 addBidiTransformTest(TestNode** root)
431 {
432 addTest(root, testAutoDirection, "complex/bidi-transform/TestAutoDirection");
433 addTest(root, testAllTransformOptions, "complex/bidi-transform/TestAllTransformOptions");
434 }
435
436 #ifdef __cplusplus
437 }
438 #endif
439