1 /********************************************************************
3 * Copyright (c) 1997-2001, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /* file name: cbiditst.cpp
8 * tab size: 8 (not used)
11 * created on: 1999sep27
12 * created by: Markus W. Scherer
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"
25 #define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
27 /* prototypes ---------------------------------------------------------------*/
33 doTests(UBiDi
*pBiDi
, UBiDi
*pLine
);
36 doTest(UBiDi
*pBiDi
, int testNumber
, BiDiTestData
*test
, int32_t lineStart
);
39 testReordering(UBiDi
*pBiDi
, int testNumber
);
42 doInverseBiDiTest(void);
45 testManyInverseBiDi(UBiDi
*pBiDi
, UBiDiLevel direction
);
48 testInverseBiDi(UBiDi
*pBiDi
, const UChar
*src
, int32_t srcLength
, UBiDiLevel direction
, UErrorCode
*pErrorCode
);
51 testWriteReverse(void);
54 doArabicShapingTest(void);
57 doLamAlefSpecialVLTRArabicShapingTest(void);
60 doTashkeelSpecialVLTRArabicShapingTest(void);
63 doLOGICALArabicDeShapingTest(void);
65 static void TestReorder(void);
67 /* helpers ------------------------------------------------------------------ */
69 static const char *levelString
="...............................................................";
72 getStringFromDirProps(const uint8_t *dirProps
, int32_t length
);
75 printUnicode(const UChar
*s
, int32_t length
, const UBiDiLevel
*levels
);
77 /* regression tests ---------------------------------------------------------*/
79 void addComplexTest(TestNode
** root
);
82 addComplexTest(TestNode
** root
) {
83 addTest(root
, doBiDiTest
, "complex/bidi/BiDiTest");
84 addTest(root
, doInverseBiDiTest
, "complex/bidi/inverse");
85 addTest(root
, TestReorder
,"complex/bidi/TestReorder");
86 addTest(root
, doArabicShapingTest
, "complex/arabic-shaping/ArabicShapingTest");
87 addTest(root
, doLamAlefSpecialVLTRArabicShapingTest
, "complex/arabic-shaping/lamalef");
88 addTest(root
, doTashkeelSpecialVLTRArabicShapingTest
, "complex/arabic-shaping/tashkeel");
89 addTest(root
, doLOGICALArabicDeShapingTest
, "complex/arabic-shaping/unshaping");
94 UBiDi
*pBiDi
, *pLine
=NULL
;
95 UErrorCode errorCode
=U_ZERO_ERROR
;
97 log_verbose("*** bidi regression test ***\n");
99 pBiDi
=ubidi_openSized(MAX_STRING_LENGTH
, 0, &errorCode
);
103 doTests(pBiDi
, pLine
);
105 log_err("ubidi_open() returned NULL, out of memory\n");
108 log_err("ubidi_openSized() returned NULL, errorCode %s\n", myErrorName(errorCode
));
118 log_verbose("*** bidi regression test finished ***\n");
122 doTests(UBiDi
*pBiDi
, UBiDi
*pLine
) {
125 UErrorCode errorCode
;
127 UBiDiLevel paraLevel
;
129 for(i
=0; i
<bidiTestCount
; ++i
) {
130 errorCode
=U_ZERO_ERROR
;
131 s
=getStringFromDirProps(tests
[i
].text
, tests
[i
].length
);
132 paraLevel
=tests
[i
].paraLevel
;
133 ubidi_setPara(pBiDi
, s
, -1, paraLevel
, NULL
, &errorCode
);
134 if(U_SUCCESS(errorCode
)) {
135 log_verbose("ubidi_setPara(tests[%d], paraLevel %d) ok, direction %d paraLevel=%d\n",
136 i
, paraLevel
, ubidi_getDirection(pBiDi
), ubidi_getParaLevel(pBiDi
));
137 lineStart
=tests
[i
].lineStart
;
139 doTest(pBiDi
, i
, tests
+i
, 0);
141 ubidi_setLine(pBiDi
, lineStart
, tests
[i
].lineLimit
, pLine
, &errorCode
);
142 if(U_SUCCESS(errorCode
)) {
143 log_verbose("ubidi_setLine(%d, %d) ok, direction %d paraLevel=%d\n",
144 lineStart
, tests
[i
].lineLimit
, ubidi_getDirection(pLine
), ubidi_getParaLevel(pLine
));
145 doTest(pLine
, i
, tests
+i
, lineStart
);
147 log_err("ubidi_setLine(tests[%d], %d, %d) failed with errorCode %s\n",
148 i
, lineStart
, tests
[i
].lineLimit
, myErrorName(errorCode
));
152 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
153 i
, paraLevel
, myErrorName(errorCode
));
157 static void TestReorder(){
158 static const char* const logicalOrder
[] ={
159 "DEL(\\u062F\\u0625)ADD(\\u062F.\\u0625.\\u200F)",
160 "DEL(\\u0645\\u0627\\u064A\\u0648) ADD(\\u0623\\u064A\\u0627\\u0631)",
161 "DEL(\\u0644\\u0644)ADD(\\u0644.\\u0644.\\u0029\\u0644)\\u0644.\\u200F",
162 "DEL(\\u0631\\u064A)ADD(\\u0631.\\u064A.) \\u0631.\\u064A.\\u200F",
163 "DAY 2 \\u0646 \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646 DAYABBR",
164 "DAY 3 \\u062B \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621 DAYABBR",
165 "DAY 4 \\u0631 \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621 DAYABBR",
166 "DAY 5 \\u062E \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633 DAYABBR",
167 "DAY 6 \\u062C \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629 DAYABBR",
168 "DAY 7 \\u0633 \\u0627\\u0644\\u0633\\u0628\\u062A DAYABBR",
169 "HELLO\\u0627\\u0644\\u0633\\u0628\\u062A",
171 static const char* const visualOrder
[]={
172 "DEL(\\u0625\\u062F)ADD(\\u200F.\\u0625.\\u062F)",
173 "DEL(\\u0648\\u064A\\u0627\\u0645) ADD(\\u0631\\u0627\\u064A\\u0623)",
174 "DEL(\\u0644\\u0644)ADD(\\u0644\\u0029.\\u0644.\\u0644)\\u200F.\\u0644",
175 /* I am doutful about this...
176 * what I would expect is :
177 * DEL(\\u064A\\u0631)ADD(.\\u064A.\\u0631) \\u200F.\\u064A.\\u0631
179 "DEL(\\u064A\\u0631)ADD(\\u200F.\\u064A.\\u0631 (.\\u064A.\\u0631",
180 "DAY 2 \\u0646\\u064A\\u0646\\u062B\\u0627\\u0644\\u0627 \\u0646 DAYABBR",
181 "DAY 3 \\u0621\\u0627\\u062B\\u0627\\u0644\\u062B\\u0644\\u0627 \\u062B DAYABBR",
182 "DAY 4 \\u0621\\u0627\\u0639\\u0628\\u0631\\u0623\\u0644\\u0627 \\u0631 DAYABBR",
183 "DAY 5 \\u0633\\u064A\\u0645\\u062E\\u0644\\u0627 \\u062E DAYABBR",
184 "DAY 6 \\u0629\\u0639\\u0645\\u062C\\u0644\\u0627 \\u062C DAYABBR",
185 "DAY 7 \\u062A\\u0628\\u0633\\u0644\\u0627 \\u0633 DAYABBR",
186 "HELLO\\u062A\\u0628\\u0633\\u0644\\u0627",
188 static const char* const visualOrder1
[]={
189 ")\\u062F.\\u0625.\\u200F(DDA)\\u062F\\u0625(LED",
190 ")\\u0623\\u064A\\u0627\\u0631(DDA )\\u0645\\u0627\\u064A\\u0648(LED",
191 "\\u0644.\\u0644.(\\u0644(\\u0644.\\u200F(DDA)\\u0644\\u0644(LED",
192 "\\u0631.\\u064A.( \\u0631.\\u064A.\\u200F(DDA)\\u0631\\u064A(LED",
193 "RBBAYAD \\u0646 \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646 2 YAD",
194 "RBBAYAD \\u062B \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621 3 YAD",
195 "RBBAYAD \\u0631 \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621 4 YAD",
196 "RBBAYAD \\u062E \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633 5 YAD",
197 "RBBAYAD \\u062C \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629 6 YAD",
198 "RBBAYAD \\u0633 \\u0627\\u0644\\u0633\\u0628\\u062A 7 YAD",
199 "\\u0627\\u0644\\u0633\\u0628\\u062AOLLEH",
202 static const char* const visualOrder2
[]={
203 "\\u200E)\\u200E\\u062F.\\u0625.\\u200F\\u200E(DDA)\\u200E\\u062F\\u0625\\u200E(LED",
204 "\\u200E)\\u200E\\u0623\\u064A\\u0627\\u0631\\u200E(DDA )\\u200E\\u0645\\u0627\\u064A\\u0648\\u200E(LED",
205 "\\u0644.\\u0644.)\\u0644)\\u0644.\\u200F\\u200E(DDA)\\u200E\\u0644\\u0644\\u200E(LED",
206 "\\u0631.\\u064A.) \\u0631.\\u064A.\\u200F\\u200E(DDA)\\u200E\\u0631\\u064A\\u200E(LED",
207 "RBBAYAD \\u200E\\u0646 \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646\\u200E 2 YAD",
208 "RBBAYAD \\u200E\\u062B \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621\\u200E 3 YAD",
209 "RBBAYAD \\u200E\\u0631 \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621\\u200E 4 YAD",
210 "RBBAYAD \\u200E\\u062E \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633\\u200E 5 YAD",
211 "RBBAYAD \\u200E\\u062C \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629\\u200E 6 YAD",
212 "RBBAYAD \\u200E\\u0633 \\u0627\\u0644\\u0633\\u0628\\u062A\\u200E 7 YAD",
213 "\\u0627\\u0644\\u0633\\u0628\\u062AOLLEH",
215 static const char* const visualOrder3
[]={
216 ")\\u062F.\\u0625.\\u200F(DDA)\\u062F\\u0625(LED",
217 ")\\u0623\\u064A\\u0627\\u0631(DDA )\\u0645\\u0627\\u064A\\u0648(LED",
218 "\\u0644.\\u0644.)\\u0644)\\u0644.\\u200F(\\u0644\\u0644)DDA(LED",
219 "\\u0631.\\u064A.) \\u0631.\\u064A.\\u200F(\\u0631\\u064A)DDA(LED",
220 "RBBAYAD \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646 \\u0646 2 YAD",
221 "RBBAYAD \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621 \\u062B 3 YAD",
222 "RBBAYAD \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621 \\u0631 4 YAD",
223 "RBBAYAD \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633 \\u062E 5 YAD",
224 "RBBAYAD \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629 \\u062C",
225 "RBBAYAD \\u0627\\u0644\\u0633\\u0628\\u062A \\u0633 7 YAD",
226 "\\u0627\\u0644\\u0633\\u0628\\u062AOLLEH"
228 static const char* const visualOrder4
[]={
229 "DEL(ADD(\\u0625\\u062F(.\\u0625.\\u062F)",
230 "DEL( (\\u0648\\u064A\\u0627\\u0645ADD(\\u0631\\u0627\\u064A\\u0623)",
231 "DEL(ADD(\\u0644\\u0644(.\\u0644(\\u0644(.\\u0644.\\u0644",
232 "DEL(ADD(\\u064A\\u0631(.\\u064A.\\u0631 (.\\u064A.\\u0631",
233 "DAY 2 \\u0646 \\u0646\\u064A\\u0646\\u062B\\u0627\\u0644\\u0627 DAYABBR",
234 "DAY 3 \\u062B \\u0621\\u0627\\u062B\\u0627\\u0644\\u062B\\u0644\\u0627 DAYABBR",
235 "DAY 4 \\u0631 \\u0621\\u0627\\u0639\\u0628\\u0631\\u0623\\u0644\\u0627 DAYABBR",
236 "DAY 5 \\u062E \\u0633\\u064A\\u0645\\u062E\\u0644\\u0627 DAYABBR",
237 "DAY 6 \\u062C \\u0629\\u0639\\u0645\\u062C\\u0644\\u0627 DAYABBR",
238 "DAY 7 \\u0633 \\u062A\\u0628\\u0633\\u0644\\u0627 DAYABBR ",
239 "HELLO\\u062A\\u0628\\u0633\\u0644\\u0627"
241 UErrorCode ec
= U_ZERO_ERROR
;
242 UBiDi
* bidi
= ubidi_open();
244 for(;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
245 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
246 int32_t destSize
= srcSize
*2;
247 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
248 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
251 u_unescape(logicalOrder
[i
],src
,srcSize
);
252 srcSize
= u_strlen(src
);
253 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,NULL
,&ec
);
255 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
256 i
, UBIDI_DEFAULT_LTR
, u_errorName(ec
));
258 /* try pre-flighting */
259 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_DO_MIRRORING
,&ec
);
260 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
261 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
262 }else if(destSize
!=srcSize
){
263 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize
,destSize
);
267 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_DO_MIRRORING
,&ec
);
268 chars
= aescstrdup(dest
,-1);
269 if(destSize
!=srcSize
){
270 log_err("ubidi_writeReordered() destSize and srcSize do not match\n");
271 }else if(uprv_strncmp(visualOrder
[i
],chars
,destSize
)!=0){
272 log_err("ubidi_writeReordered() did not give expected results. Expected: %s Got: %s At Index: %d\n",visualOrder
[i
],chars
,i
);
280 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
281 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
282 int32_t destSize
= srcSize
*2;
283 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
284 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
287 u_unescape(logicalOrder
[i
],src
,srcSize
);
288 srcSize
=u_strlen(src
);
289 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,NULL
,&ec
);
291 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
292 i
, UBIDI_DEFAULT_LTR
, u_errorName(ec
));
294 /* try pre-flighting */
295 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_DO_MIRRORING
+UBIDI_OUTPUT_REVERSE
,&ec
);
296 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
297 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
298 }else if(destSize
!=srcSize
){
299 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize
,destSize
);
303 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_DO_MIRRORING
+UBIDI_OUTPUT_REVERSE
,&ec
);
304 chars
= aescstrdup(dest
,destSize
);
305 if(destSize
!=srcSize
){
306 log_err("ubidi_writeReordered() destSize and srcSize do not match\n");
307 }else if(uprv_strncmp(visualOrder1
[i
],chars
,destSize
)!=0){
308 log_err("ubidi_writeReordered() did not give expected results for UBIDI_DO_MIRRORING+UBIDI_OUTPUT_REVERSE. Expected: %s Got: %s At Index: %d\n",visualOrder
[i
],chars
,i
);
317 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
318 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
319 int32_t destSize
= srcSize
*2;
320 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
321 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
324 u_unescape(logicalOrder
[i
],src
,srcSize
);
325 srcSize
=u_strlen(src
);
326 ubidi_setInverse(bidi
,TRUE
);
327 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,NULL
,&ec
);
330 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
331 i
, UBIDI_DEFAULT_LTR
, u_errorName(ec
));
333 /* try pre-flighting */
334 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_INSERT_LRM_FOR_NUMERIC
+UBIDI_OUTPUT_REVERSE
,&ec
);
335 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
336 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
340 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_INSERT_LRM_FOR_NUMERIC
+UBIDI_OUTPUT_REVERSE
,&ec
);
341 chars
= aescstrdup(dest
,destSize
);
343 /*if(destSize!=srcSize){
344 log_err("ubidi_writeReordered() destSize and srcSize do not match. Dest Size = %d Source Size = %d\n",destSize,srcSize );
346 if(uprv_strncmp(visualOrder2
[i
],chars
,destSize
)!=0){
347 log_err("ubidi_writeReordered() did not give expected results for UBIDI_INSERT_LRM_FOR_NUMERIC+UBIDI_OUTPUT_REVERSE. Expected: %s Got: %s At Index: %d\n",visualOrder
[i
],chars
,i
);
355 /* Max Explicit level */
356 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
357 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
358 int32_t destSize
= srcSize
*2;
359 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
360 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
362 UBiDiLevel levels
[UBIDI_MAX_EXPLICIT_LEVEL
]={1,2,3,4,5,6,7,8,9,10};
364 u_unescape(logicalOrder
[i
],src
,srcSize
);
365 srcSize
=u_strlen(src
);
366 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,levels
,&ec
);
368 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
369 i
, UBIDI_MAX_EXPLICIT_LEVEL
, u_errorName(ec
));
371 /* try pre-flighting */
372 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_OUTPUT_REVERSE
,&ec
);
373 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
374 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
375 }else if(destSize
!=srcSize
){
376 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize
,destSize
);
380 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_OUTPUT_REVERSE
,&ec
);
381 chars
= aescstrdup(dest
,destSize
);
383 if(destSize
!=srcSize
){
384 log_err("ubidi_writeReordered() destSize and srcSize do not match. Dest Size = %d Source Size = %d\n",destSize
,srcSize
);
385 }else if(uprv_strncmp(visualOrder3
[i
],chars
,destSize
)!=0){
386 log_err("ubidi_writeReordered() did not give expected results for UBIDI_OUTPUT_REVERSE. Expected: %s Got: %s At Index: %d\n",visualOrder
[i
],chars
,i
);
394 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
395 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
396 int32_t destSize
= srcSize
*2;
397 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
398 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
400 UBiDiLevel levels
[UBIDI_MAX_EXPLICIT_LEVEL
]={1,2,3,4,5,6,7,8,9,10};
402 u_unescape(logicalOrder
[i
],src
,srcSize
);
403 srcSize
=u_strlen(src
);
404 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,levels
,&ec
);
406 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
407 i
, UBIDI_MAX_EXPLICIT_LEVEL
, u_errorName(ec
));
410 /* try pre-flighting */
411 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_DO_MIRRORING
+UBIDI_REMOVE_BIDI_CONTROLS
,&ec
);
412 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
413 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
414 /*}else if(destSize!=srcSize){
415 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize,destSize);*/
419 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_DO_MIRRORING
+UBIDI_REMOVE_BIDI_CONTROLS
,&ec
);
420 chars
= aescstrdup(dest
,destSize
);
422 /*if(destSize!=srcSize){
423 log_err("ubidi_writeReordered() destSize and srcSize do not match. Dest Size = %d Source Size = %d\n",destSize,srcSize );
424 }else*/ if(uprv_strncmp(visualOrder4
[i
],chars
,destSize
)!=0){
425 log_err("ubidi_writeReordered() did not give expected results for UBIDI_DO_MIRRORING+UBIDI_REMOVE_BIDI_CONTROLS. Expected: %s Got: %s At Index: %d\n",visualOrder
[i
],chars
,i
);
435 doTest(UBiDi
*pBiDi
, int testNumber
, BiDiTestData
*test
, int32_t lineStart
) {
436 const uint8_t *dirProps
=test
->text
+lineStart
;
437 const UBiDiLevel
*levels
=test
->levels
;
438 const uint8_t *visualMap
=test
->visualMap
;
439 int32_t i
, len
=ubidi_getLength(pBiDi
), logicalIndex
, runCount
;
440 UErrorCode errorCode
=U_ZERO_ERROR
;
441 UBiDiLevel level
, level2
;
443 testReordering(pBiDi
, testNumber
);
445 for(i
=0; i
<len
; ++i
) {
446 log_verbose("%3d %3d %.*s%-3s @%d\n",
447 i
, ubidi_getLevelAt(pBiDi
, i
), ubidi_getLevelAt(pBiDi
, i
), levelString
,
448 dirPropNames
[dirProps
[i
]],
449 ubidi_getVisualIndex(pBiDi
, i
, &errorCode
));
452 log_verbose("\n-----levels:");
453 for(i
=0; i
<len
; ++i
) {
457 log_verbose(" %d", ubidi_getLevelAt(pBiDi
, i
));
460 log_verbose("\n--reordered:");
461 for(i
=0; i
<len
; ++i
) {
465 log_verbose(" %d", ubidi_getVisualIndex(pBiDi
, i
, &errorCode
));
469 if(test
->direction
!=ubidi_getDirection(pBiDi
)) {
470 log_err("ubidi_getDirection(tests[%d]): wrong direction %d\n", testNumber
, ubidi_getDirection(pBiDi
));
473 if(test
->resultLevel
!=ubidi_getParaLevel(pBiDi
)) {
474 log_err("ubidi_getParaLevel(tests[%d]): wrong paragraph level %d\n", testNumber
, ubidi_getParaLevel(pBiDi
));
477 for(i
=0; i
<len
; ++i
) {
478 if(levels
[i
]!=ubidi_getLevelAt(pBiDi
, i
)) {
479 log_err("ubidi_getLevelAt(tests[%d], %d): wrong level %d\n", testNumber
, i
, ubidi_getLevelAt(pBiDi
, i
));
484 for(i
=0; i
<len
; ++i
) {
485 logicalIndex
=ubidi_getVisualIndex(pBiDi
, i
, &errorCode
);
486 if(U_FAILURE(errorCode
)) {
487 log_err("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber
, i
, myErrorName(errorCode
));
490 if(visualMap
[i
]!=logicalIndex
) {
491 log_err("ubidi_getVisualIndex(tests[%d], %d): wrong index %d\n", testNumber
, i
, logicalIndex
);
496 runCount
=ubidi_countRuns(pBiDi
, &errorCode
);
497 if(U_FAILURE(errorCode
)) {
498 log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
502 for(logicalIndex
=0; logicalIndex
<len
;) {
503 level
=ubidi_getLevelAt(pBiDi
, logicalIndex
);
504 ubidi_getLogicalRun(pBiDi
, logicalIndex
, &logicalIndex
, &level2
);
506 log_err("ubidi_getLogicalRun(tests[%d], run ending at index %d): wrong level %d\n", testNumber
, logicalIndex
, level2
);
509 log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs compared to %d=ubidi_getRunCount()\n", testNumber
, ubidi_countRuns(pBiDi
, &errorCode
));
514 log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs compared to %d=ubidi_getRunCount()\n", testNumber
, ubidi_countRuns(pBiDi
, &errorCode
));
522 testReordering(UBiDi
*pBiDi
, int testNumber
) {
524 logicalMap1
[200], logicalMap2
[200], logicalMap3
[200],
525 visualMap1
[200], visualMap2
[200], visualMap3
[200], visualMap4
[200];
526 UErrorCode errorCode
=U_ZERO_ERROR
;
527 UBiDiLevel levels
[200];
528 int32_t i
, length
=ubidi_getLength(pBiDi
);
529 int32_t runCount
, visualIndex
, logicalStart
, runLength
;
536 /* get the logical and visual maps from the object */
537 ubidi_getLogicalMap(pBiDi
, logicalMap1
, &errorCode
);
538 if(U_FAILURE(errorCode
)) {
539 log_err("ubidi_getLogicalMap(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
543 ubidi_getVisualMap(pBiDi
, visualMap1
, &errorCode
);
545 if(U_FAILURE(errorCode
)) {
546 log_err("ubidi_getVisualMap(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
550 /* invert them both */
551 ubidi_invertMap(logicalMap1
, visualMap2
, length
);
552 ubidi_invertMap(visualMap1
, logicalMap2
, length
);
554 /* get them from the levels array, too */
555 uprv_memcpy(levels
, ubidi_getLevels(pBiDi
, &errorCode
), length
);
557 if(U_FAILURE(errorCode
)) {
558 log_err("ubidi_getLevels(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
562 ubidi_reorderLogical(levels
, length
, logicalMap3
);
563 ubidi_reorderVisual(levels
, length
, visualMap3
);
565 /* get the visual map from the runs, too */
566 runCount
=ubidi_countRuns(pBiDi
, &errorCode
);
567 if(U_FAILURE(errorCode
)) {
568 log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
572 log_verbose("\n----%2d runs:", runCount
);
573 for(i
=0; i
<runCount
; ++i
) {
574 odd
=(UBool
)(ubidi_getVisualRun(pBiDi
, i
, &logicalStart
, &runLength
));
575 log_verbose(" (%c @%d[%d])", odd
? 'R' : 'L', logicalStart
, runLength
);
580 for(i
=0; i
<runCount
; ++i
) {
581 if(UBIDI_LTR
==ubidi_getVisualRun(pBiDi
, i
, &logicalStart
, &runLength
)) {
583 visualMap4
[visualIndex
++]=logicalStart
++;
584 } while(--runLength
>0);
586 logicalStart
+=runLength
; /* logicalLimit */
588 visualMap4
[visualIndex
++]=--logicalStart
;
589 } while(--runLength
>0);
593 /* print all the maps */
594 log_verbose("logical maps:\n");
595 for(i
=0; i
<length
; ++i
) {
596 log_verbose("%4d", logicalMap1
[i
]);
599 for(i
=0; i
<length
; ++i
) {
600 log_verbose("%4d", logicalMap2
[i
]);
603 for(i
=0; i
<length
; ++i
) {
604 log_verbose("%4d", logicalMap3
[i
]);
607 log_verbose("\nvisual maps:\n");
608 for(i
=0; i
<length
; ++i
) {
609 log_verbose("%4d", visualMap1
[i
]);
612 for(i
=0; i
<length
; ++i
) {
613 log_verbose("%4d", visualMap2
[i
]);
616 for(i
=0; i
<length
; ++i
) {
617 log_verbose("%4d", visualMap3
[i
]);
620 for(i
=0; i
<length
; ++i
) {
621 log_verbose("%4d", visualMap4
[i
]);
625 /* check that the indexes are the same between these and ubidi_getLogical/VisualIndex() */
626 for(i
=0; i
<length
; ++i
) {
627 if(logicalMap1
[i
]!=logicalMap2
[i
]) {
628 log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap2[i] at i=%d\n", testNumber
, i
);
631 if(logicalMap1
[i
]!=logicalMap3
[i
]) {
632 log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap3[i] at i=%d\n", testNumber
, i
);
636 if(visualMap1
[i
]!=visualMap2
[i
]) {
637 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap2[i] at i=%d\n", testNumber
, i
);
640 if(visualMap1
[i
]!=visualMap3
[i
]) {
641 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap3[i] at i=%d\n", testNumber
, i
);
644 if(visualMap1
[i
]!=visualMap4
[i
]) {
645 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap4[i] at i=%d\n", testNumber
, i
);
649 if(logicalMap1
[i
]!=ubidi_getVisualIndex(pBiDi
, i
, &errorCode
)) {
650 log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=ubidi_getVisualIndex(i) at i=%d\n", testNumber
, i
);
653 if(U_FAILURE(errorCode
)) {
654 log_verbose("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber
, i
, myErrorName(errorCode
));
657 if(visualMap1
[i
]!=ubidi_getLogicalIndex(pBiDi
, i
, &errorCode
)) {
658 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=ubidi_getLogicalIndex(i) at i=%d\n", testNumber
, i
);
661 if(U_FAILURE(errorCode
)) {
662 log_verbose("ubidi_getLogicalIndex(tests[%d], %d): error %s\n", testNumber
, i
, myErrorName(errorCode
));
669 /* inverse BiDi ------------------------------------------------------------- */
672 string0
[]={ 0x6c, 0x61, 0x28, 0x74, 0x69, 0x6e, 0x20, 0x5d0, 0x5d1, 0x29, 0x5d2, 0x5d3 },
673 string1
[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x31, 0x32, 0x33 },
674 string2
[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x28, 0x5d1, 0x5d2, 0x20, 0x31, 0x29, 0x32, 0x33 },
675 string3
[]={ 0x31, 0x32, 0x33, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x34, 0x35, 0x36 },
676 string4
[]={ 0x61, 0x62, 0x20, 0x61, 0x62, 0x20, 0x661, 0x662 };
678 #define STRING_TEST_CASE(s) { (s), LENGTHOF(s) }
680 static const struct {
684 STRING_TEST_CASE(string0
),
685 STRING_TEST_CASE(string1
),
686 STRING_TEST_CASE(string2
),
687 STRING_TEST_CASE(string3
)
690 static int countRoundtrips
=0, countNonRoundtrips
=0;
693 doInverseBiDiTest() {
695 UErrorCode errorCode
;
700 log_err("unable to open a UBiDi object (out of memory)\n");
704 log_verbose("inverse BiDi: testInverseBiDi(L) with %u test cases ---\n", LENGTHOF(testCases
));
705 for(i
=0; i
<LENGTHOF(testCases
); ++i
) {
706 errorCode
=U_ZERO_ERROR
;
707 testInverseBiDi(pBiDi
, testCases
[i
].s
, testCases
[i
].length
, 0, &errorCode
);
710 log_verbose("inverse BiDi: testInverseBiDi(R) with %u test cases ---\n", LENGTHOF(testCases
));
711 for(i
=0; i
<LENGTHOF(testCases
); ++i
) {
712 errorCode
=U_ZERO_ERROR
;
713 testInverseBiDi(pBiDi
, testCases
[i
].s
, testCases
[i
].length
, 1, &errorCode
);
716 testManyInverseBiDi(pBiDi
, 0);
717 testManyInverseBiDi(pBiDi
, 1);
721 log_verbose("inverse BiDi: rountrips: %5u\nnon-roundtrips: %5u\n", countRoundtrips
, countNonRoundtrips
);
726 #define COUNT_REPEAT_SEGMENTS 6
728 static const UChar repeatSegments
[COUNT_REPEAT_SEGMENTS
][2]={
729 { 0x61, 0x62 }, /* L */
730 { 0x5d0, 0x5d1 }, /* R */
731 { 0x627, 0x628 }, /* AL */
732 { 0x31, 0x32 }, /* EN */
733 { 0x661, 0x662 }, /* AN */
734 { 0x20, 0x20 } /* WS (N) */
738 testManyInverseBiDi(UBiDi
*pBiDi
, UBiDiLevel direction
) {
739 static UChar text
[8]={ 0, 0, 0x20, 0, 0, 0x20, 0, 0 };
741 UErrorCode errorCode
;
743 log_verbose("inverse BiDi: testManyInverseBiDi(%c) - test permutations of text snippets ---\n", direction
==0 ? 'L' : 'R');
744 for(i
=0; i
<COUNT_REPEAT_SEGMENTS
; ++i
) {
745 text
[0]=repeatSegments
[i
][0];
746 text
[1]=repeatSegments
[i
][1];
747 for(j
=0; j
<COUNT_REPEAT_SEGMENTS
; ++j
) {
748 text
[3]=repeatSegments
[j
][0];
749 text
[4]=repeatSegments
[j
][1];
750 for(k
=0; k
<COUNT_REPEAT_SEGMENTS
; ++k
) {
751 text
[6]=repeatSegments
[k
][0];
752 text
[7]=repeatSegments
[k
][1];
754 errorCode
=U_ZERO_ERROR
;
755 log_verbose("inverse BiDi: testManyInverseBiDi()[%u %u %u]\n", i
, j
, k
);
756 testInverseBiDi(pBiDi
, text
, 8, direction
, &errorCode
);
763 testInverseBiDi(UBiDi
*pBiDi
, const UChar
*src
, int32_t srcLength
, UBiDiLevel direction
, UErrorCode
*pErrorCode
) {
764 static UChar visualLTR
[200], logicalDest
[200], visualDest
[200];
765 int32_t ltrLength
, logicalLength
, visualLength
;
768 log_verbose("inverse BiDi: testInverseBiDi(L)\n");
770 /* convert visual to logical */
771 ubidi_setInverse(pBiDi
, TRUE
);
772 ubidi_setPara(pBiDi
, src
, srcLength
, 0, NULL
, pErrorCode
);
773 logicalLength
=ubidi_writeReordered(pBiDi
, logicalDest
, LENGTHOF(logicalDest
),
774 UBIDI_DO_MIRRORING
|UBIDI_INSERT_LRM_FOR_NUMERIC
, pErrorCode
);
776 printUnicode(src
, srcLength
, ubidi_getLevels(pBiDi
, pErrorCode
));
779 /* convert back to visual LTR */
780 ubidi_setInverse(pBiDi
, FALSE
);
781 ubidi_setPara(pBiDi
, logicalDest
, logicalLength
, 0, NULL
, pErrorCode
);
782 visualLength
=ubidi_writeReordered(pBiDi
, visualDest
, LENGTHOF(visualDest
),
783 UBIDI_DO_MIRRORING
|UBIDI_REMOVE_BIDI_CONTROLS
, pErrorCode
);
785 log_verbose("inverse BiDi: testInverseBiDi(R)\n");
787 /* reverse visual from RTL to LTR */
788 ltrLength
=ubidi_writeReverse(src
, srcLength
, visualLTR
, LENGTHOF(visualLTR
), 0, pErrorCode
);
790 printUnicode(src
, srcLength
, NULL
);
793 /* convert visual RTL to logical */
794 ubidi_setInverse(pBiDi
, TRUE
);
795 ubidi_setPara(pBiDi
, visualLTR
, ltrLength
, 0, NULL
, pErrorCode
);
796 logicalLength
=ubidi_writeReordered(pBiDi
, logicalDest
, LENGTHOF(logicalDest
),
797 UBIDI_DO_MIRRORING
|UBIDI_INSERT_LRM_FOR_NUMERIC
, pErrorCode
);
799 printUnicode(visualLTR
, ltrLength
, ubidi_getLevels(pBiDi
, pErrorCode
));
802 /* convert back to visual RTL */
803 ubidi_setInverse(pBiDi
, FALSE
);
804 ubidi_setPara(pBiDi
, logicalDest
, logicalLength
, 0, NULL
, pErrorCode
);
805 visualLength
=ubidi_writeReordered(pBiDi
, visualDest
, LENGTHOF(visualDest
),
806 UBIDI_DO_MIRRORING
|UBIDI_REMOVE_BIDI_CONTROLS
|UBIDI_OUTPUT_REVERSE
, pErrorCode
);
809 printUnicode(logicalDest
, logicalLength
, ubidi_getLevels(pBiDi
, pErrorCode
));
812 printUnicode(visualDest
, visualLength
, NULL
);
815 /* check and print results */
816 if(U_FAILURE(*pErrorCode
)) {
817 log_err("inverse BiDi: *** error %s\n"
818 " turn on verbose mode to see details\n", u_errorName(*pErrorCode
));
819 } else if(srcLength
==visualLength
&& uprv_memcmp(src
, visualDest
, srcLength
*U_SIZEOF_UCHAR
)==0) {
821 log_verbose(" + roundtripped\n");
823 ++countNonRoundtrips
;
824 log_verbose(" * did not roundtrip\n");
825 log_err("inverse BiDi: transformation visual->logical->visual did not roundtrip the text;\n"
826 " turn on verbose mode to see details\n");
832 /* U+064e and U+0650 are combining marks (Mn) */
833 static const UChar forward
[]={
834 0x200f, 0x627, 0x64e, 0x650, 0x20, 0x28, 0x31, 0x29
835 }, reverseKeepCombining
[]={
836 0x29, 0x31, 0x28, 0x20, 0x627, 0x64e, 0x650, 0x200f
837 }, reverseRemoveControlsKeepCombiningDoMirror
[]={
838 0x28, 0x31, 0x29, 0x20, 0x627, 0x64e, 0x650
840 static UChar reverse
[10];
841 UErrorCode errorCode
;
844 /* test ubidi_writeReverse() with "interesting" options */
845 errorCode
=U_ZERO_ERROR
;
846 length
=ubidi_writeReverse(forward
, LENGTHOF(forward
),
847 reverse
, LENGTHOF(reverse
),
848 UBIDI_KEEP_BASE_COMBINING
,
850 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(reverseKeepCombining
) || uprv_memcmp(reverse
, reverseKeepCombining
, length
*U_SIZEOF_UCHAR
)!=0) {
851 log_err("failure in ubidi_writeReverse(UBIDI_KEEP_BASE_COMBINING): length=%d (should be %d), error code %s\n",
852 length
, LENGTHOF(reverseKeepCombining
), u_errorName(errorCode
));
855 uprv_memset(reverse
, 0xa5, LENGTHOF(reverse
)*U_SIZEOF_UCHAR
);
856 errorCode
=U_ZERO_ERROR
;
857 length
=ubidi_writeReverse(forward
, LENGTHOF(forward
),
858 reverse
, LENGTHOF(reverse
),
859 UBIDI_REMOVE_BIDI_CONTROLS
|UBIDI_DO_MIRRORING
|UBIDI_KEEP_BASE_COMBINING
,
861 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror
) || uprv_memcmp(reverse
, reverseRemoveControlsKeepCombiningDoMirror
, length
*U_SIZEOF_UCHAR
)!=0) {
862 log_err("failure in ubidi_writeReverse(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING):\n"
863 " length=%d (should be %d), error code %s\n",
864 length
, LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror
), u_errorName(errorCode
));
868 /* arabic shaping ----------------------------------------------------------- */
871 doArabicShapingTest() {
875 0x627, /* arabic:alef */
882 0x661, 0x627, 0x662, 0x6f3, 0x61, 0x664, 0
884 0x31, 0x627, 0x32, 0x33, 0x61, 0x34, 0
885 }, logical_alen2an_init_lr
[]={
886 0x31, 0x627, 0x662, 0x6f3, 0x61, 0x34, 0
887 }, logical_alen2an_init_al
[]={
888 0x6f1, 0x627, 0x6f2, 0x6f3, 0x61, 0x34, 0
889 }, reverse_alen2an_init_lr
[]={
890 0x661, 0x627, 0x32, 0x6f3, 0x61, 0x34, 0
891 }, reverse_alen2an_init_al
[]={
892 0x6f1, 0x627, 0x32, 0x6f3, 0x61, 0x6f4, 0
895 UErrorCode errorCode
;
898 /* test number shaping */
900 /* european->arabic */
901 errorCode
=U_ZERO_ERROR
;
902 length
=u_shapeArabic(source
, LENGTHOF(source
),
903 dest
, LENGTHOF(dest
),
904 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
906 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, en2an
, length
*U_SIZEOF_UCHAR
)!=0) {
907 log_err("failure in u_shapeArabic(en2an)\n");
910 /* arabic->european */
911 errorCode
=U_ZERO_ERROR
;
912 length
=u_shapeArabic(source
, -1,
913 dest
, LENGTHOF(dest
),
914 U_SHAPE_DIGITS_AN2EN
|U_SHAPE_DIGIT_TYPE_AN_EXTENDED
,
916 if(U_FAILURE(errorCode
) || length
!=u_strlen(source
) || uprv_memcmp(dest
, an2en
, length
*U_SIZEOF_UCHAR
)!=0) {
917 log_err("failure in u_shapeArabic(an2en)\n");
920 /* european->arabic with context, logical order, initial state not AL */
921 errorCode
=U_ZERO_ERROR
;
922 length
=u_shapeArabic(source
, LENGTHOF(source
),
923 dest
, LENGTHOF(dest
),
924 U_SHAPE_DIGITS_ALEN2AN_INIT_LR
|U_SHAPE_DIGIT_TYPE_AN
,
926 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, logical_alen2an_init_lr
, length
*U_SIZEOF_UCHAR
)!=0) {
927 log_err("failure in u_shapeArabic(logical_alen2an_init_lr)\n");
930 /* european->arabic with context, logical order, initial state AL */
931 errorCode
=U_ZERO_ERROR
;
932 length
=u_shapeArabic(source
, LENGTHOF(source
),
933 dest
, LENGTHOF(dest
),
934 U_SHAPE_DIGITS_ALEN2AN_INIT_AL
|U_SHAPE_DIGIT_TYPE_AN_EXTENDED
,
936 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, logical_alen2an_init_al
, length
*U_SIZEOF_UCHAR
)!=0) {
937 log_err("failure in u_shapeArabic(logical_alen2an_init_al)\n");
940 /* european->arabic with context, reverse order, initial state not AL */
941 errorCode
=U_ZERO_ERROR
;
942 length
=u_shapeArabic(source
, LENGTHOF(source
),
943 dest
, LENGTHOF(dest
),
944 U_SHAPE_DIGITS_ALEN2AN_INIT_LR
|U_SHAPE_DIGIT_TYPE_AN
|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
946 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, reverse_alen2an_init_lr
, length
*U_SIZEOF_UCHAR
)!=0) {
947 log_err("failure in u_shapeArabic(reverse_alen2an_init_lr)\n");
950 /* european->arabic with context, reverse order, initial state AL */
951 errorCode
=U_ZERO_ERROR
;
952 length
=u_shapeArabic(source
, LENGTHOF(source
),
953 dest
, LENGTHOF(dest
),
954 U_SHAPE_DIGITS_ALEN2AN_INIT_AL
|U_SHAPE_DIGIT_TYPE_AN_EXTENDED
|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
956 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, reverse_alen2an_init_al
, length
*U_SIZEOF_UCHAR
)!=0) {
957 log_err("failure in u_shapeArabic(reverse_alen2an_init_al)\n");
961 errorCode
=U_ZERO_ERROR
;
962 length
=u_shapeArabic(source
, LENGTHOF(source
),
963 dest
, LENGTHOF(dest
),
966 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, source
, length
*U_SIZEOF_UCHAR
)!=0) {
967 log_err("failure in u_shapeArabic(noop)\n");
970 errorCode
=U_ZERO_ERROR
;
971 length
=u_shapeArabic(source
, 0,
972 dest
, LENGTHOF(dest
),
973 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
975 if(U_FAILURE(errorCode
) || length
!=0) {
976 log_err("failure in u_shapeArabic(en2an, sourceLength=0), returned %d/%s\n", u_errorName(errorCode
), LENGTHOF(source
));
979 /* preflight digit shaping */
980 errorCode
=U_ZERO_ERROR
;
981 length
=u_shapeArabic(source
, LENGTHOF(source
),
983 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
985 if(errorCode
!=U_BUFFER_OVERFLOW_ERROR
|| length
!=LENGTHOF(source
)) {
986 log_err("failure in u_shapeArabic(en2an preflighting), returned %d/%s instead of %d/U_BUFFER_OVERFLOW_ERROR\n",
987 length
, u_errorName(errorCode
), LENGTHOF(source
));
990 /* test illegal arguments */
991 errorCode
=U_ZERO_ERROR
;
992 length
=u_shapeArabic(NULL
, LENGTHOF(source
),
993 dest
, LENGTHOF(dest
),
994 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
996 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
997 log_err("failure in u_shapeArabic(source=NULL), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1000 errorCode
=U_ZERO_ERROR
;
1001 length
=u_shapeArabic(source
, -2,
1002 dest
, LENGTHOF(dest
),
1003 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1005 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1006 log_err("failure in u_shapeArabic(sourceLength=-2), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1009 errorCode
=U_ZERO_ERROR
;
1010 length
=u_shapeArabic(source
, LENGTHOF(source
),
1011 NULL
, LENGTHOF(dest
),
1012 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1014 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1015 log_err("failure in u_shapeArabic(dest=NULL), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1018 errorCode
=U_ZERO_ERROR
;
1019 length
=u_shapeArabic(source
, LENGTHOF(source
),
1021 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1023 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1024 log_err("failure in u_shapeArabic(destSize=-1), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1027 errorCode
=U_ZERO_ERROR
;
1028 length
=u_shapeArabic(source
, LENGTHOF(source
),
1029 dest
, LENGTHOF(dest
),
1030 U_SHAPE_DIGITS_RESERVED
|U_SHAPE_DIGIT_TYPE_AN
,
1032 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1033 log_err("failure in u_shapeArabic(U_SHAPE_DIGITS_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1036 errorCode
=U_ZERO_ERROR
;
1037 length
=u_shapeArabic(source
, LENGTHOF(source
),
1038 dest
, LENGTHOF(dest
),
1039 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_RESERVED
,
1041 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1042 log_err("failure in u_shapeArabic(U_SHAPE_DIGIT_TYPE_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1045 errorCode
=U_ZERO_ERROR
;
1046 length
=u_shapeArabic(source
, LENGTHOF(source
),
1047 (UChar
*)(source
+2), LENGTHOF(dest
), /* overlap source and destination */
1048 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1050 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1051 log_err("failure in u_shapeArabic(U_SHAPE_DIGIT_TYPE_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1056 doLamAlefSpecialVLTRArabicShapingTest() {
1059 /*a*/ 0x20 ,0x646,0x622,0x644,0x627,0x20,
1060 /*b*/ 0x646,0x623,0x64E,0x644,0x627,0x20,
1061 /*c*/ 0x646,0x627,0x670,0x644,0x627,0x20,
1062 /*d*/ 0x646,0x622,0x653,0x644,0x627,0x20,
1063 /*e*/ 0x646,0x625,0x655,0x644,0x627,0x20,
1064 /*f*/ 0x646,0x622,0x654,0x644,0x627,0x20,
1067 0x20,0xfee5,0x20,0xfef5,0xfe8d,0x20,0xfee5,0x20,0xfe76,0xfef7,0xfe8d,0x20,
1068 0xfee5,0x20,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x20,0x653,0xfef5,0xfe8d,0x20,
1069 0xfee5,0x20,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x20,0x654,0xfef5,0xfe8d,0x20,
1072 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,0x670,
1073 0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,0xfe8d,
1074 0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb,0x20,0x20,0x20,0x20,0x20,0x20
1075 }, shape_at_begin
[]={
1076 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,
1077 0xfef7,0xfe8d,0x20,0xfee5,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,
1078 0x20,0xfee5,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1079 }, shape_grow_shrink
[]={
1080 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,
1081 0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,
1082 0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1083 }, shape_excepttashkeel_near
[]={
1084 0x20,0xfee5,0x20,0xfef5,0xfe8d,0x20,0xfee5,0x20,0xfe76,0xfef7,0xfe8d,0x20,
1085 0xfee5,0x20,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x20,0x653,0xfef5,0xfe8d,0x20,
1086 0xfee5,0x20,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x20,0x654,0xfef5,0xfe8d,0x20,
1088 }, shape_excepttashkeel_at_end
[]={
1089 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,
1090 0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,
1091 0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb,0x20,0x20,0x20,
1093 }, shape_excepttashkeel_at_begin
[]={
1094 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,
1095 0xfef7,0xfe8d,0x20,0xfee5,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,
1096 0x20,0xfee5,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1097 }, shape_excepttashkeel_grow_shrink
[]={
1098 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,0x670,
1099 0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,0xfe8d,
1100 0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1104 UErrorCode errorCode
;
1107 errorCode
=U_ZERO_ERROR
;
1109 length
=u_shapeArabic(source
, LENGTHOF(source
),
1110 dest
, LENGTHOF(dest
),
1111 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1112 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1115 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_near
) || uprv_memcmp(dest
, shape_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1116 log_err("failure in u_shapeArabic(LAMALEF shape_near)\n");
1119 errorCode
=U_ZERO_ERROR
;
1121 length
=u_shapeArabic(source
, LENGTHOF(source
),
1122 dest
, LENGTHOF(dest
),
1123 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_END
|
1124 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1127 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_at_end
) || uprv_memcmp(dest
, shape_at_end
, length
*U_SIZEOF_UCHAR
)!=0) {
1128 log_err("failure in u_shapeArabic(LAMALEF shape_at_end)\n");
1131 errorCode
=U_ZERO_ERROR
;
1133 length
=u_shapeArabic(source
, LENGTHOF(source
),
1134 dest
, LENGTHOF(dest
),
1135 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING
|
1136 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1139 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_at_begin
) || uprv_memcmp(dest
, shape_at_begin
, length
*U_SIZEOF_UCHAR
)!=0) {
1140 log_err("failure in u_shapeArabic(LAMALEF shape_at_begin)\n");
1143 errorCode
=U_ZERO_ERROR
;
1145 length
=u_shapeArabic(source
, LENGTHOF(source
),
1146 dest
, LENGTHOF(dest
),
1147 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_GROW_SHRINK
|
1148 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1151 if(U_FAILURE(errorCode
) || uprv_memcmp(dest
, shape_grow_shrink
, length
*U_SIZEOF_UCHAR
)!=0) {
1152 log_err("failure in u_shapeArabic(LAMALEF shape_grow_shrink)\n");
1155 /* ==================== U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED ==================== */
1157 errorCode
=U_ZERO_ERROR
;
1159 length
=u_shapeArabic(source
, LENGTHOF(source
),
1160 dest
, LENGTHOF(dest
),
1161 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1162 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1165 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_near
) || uprv_memcmp(dest
, shape_excepttashkeel_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1166 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_near)\n");
1169 errorCode
=U_ZERO_ERROR
;
1171 length
=u_shapeArabic(source
, LENGTHOF(source
),
1172 dest
, LENGTHOF(dest
),
1173 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_AT_END
|
1174 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1177 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_at_end
) || uprv_memcmp(dest
,shape_excepttashkeel_at_end
, length
*U_SIZEOF_UCHAR
)!=0) {
1178 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_at_end)\n");
1181 errorCode
=U_ZERO_ERROR
;
1183 length
=u_shapeArabic(source
, LENGTHOF(source
),
1184 dest
, LENGTHOF(dest
),
1185 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING
|
1186 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1189 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_at_begin
) || uprv_memcmp(dest
, shape_excepttashkeel_at_begin
, length
*U_SIZEOF_UCHAR
)!=0) {
1190 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_at_begin)\n");
1193 errorCode
=U_ZERO_ERROR
;
1195 length
=u_shapeArabic(source
, LENGTHOF(source
),
1196 dest
, LENGTHOF(dest
),
1197 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_GROW_SHRINK
|
1198 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1201 if(U_FAILURE(errorCode
) || uprv_memcmp(dest
, shape_excepttashkeel_grow_shrink
, length
*U_SIZEOF_UCHAR
)!=0) {
1202 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_grow_shrink)\n");
1207 doTashkeelSpecialVLTRArabicShapingTest() {
1210 0x64A,0x628,0x631,0x639,0x20,
1211 0x64A,0x628,0x651,0x631,0x64E,0x639,0x20,
1212 0x64C,0x64A,0x628,0x631,0x64F,0x639,0x20,
1213 0x628,0x670,0x631,0x670,0x639,0x20,
1214 0x628,0x653,0x631,0x653,0x639,0x20,
1215 0x628,0x654,0x631,0x654,0x639,0x20,
1216 0x628,0x655,0x631,0x655,0x639,0x20,
1218 0xfef2,0xfe91,0xfeae,0xfecb,0x20,0xfef2,0xfe91,0xfe7c,0xfeae,0xfe77,0xfecb,
1219 0x20,0xfe72,0xfef2,0xfe91,0xfeae,0xfe79,0xfecb,0x20,0xfe8f,0x670,0xfeae,0x670,
1220 0xfecb,0x20,0xfe8f,0x653,0xfeae,0x653,0xfecb,0x20,0xfe8f,0x654,0xfeae,0x654,
1221 0xfecb,0x20,0xfe8f,0x655,0xfeae,0x655,0xfecb,0x20
1222 }, shape_excepttashkeel_near
[]={
1223 0xfef2,0xfe91,0xfeae,0xfecb,0x20,0xfef2,0xfe91,0xfe7c,0xfeae,0xfe76,0xfecb,0x20,
1224 0xfe72,0xfef2,0xfe91,0xfeae,0xfe78,0xfecb,0x20,0xfe8f,0x670,0xfeae,0x670,0xfecb,
1225 0x20,0xfe8f,0x653,0xfeae,0x653,0xfecb,0x20,0xfe8f,0x654,0xfeae,0x654,0xfecb,0x20,
1226 0xfe8f,0x655,0xfeae,0x655,0xfecb,0x20
1230 UErrorCode errorCode
;
1233 errorCode
=U_ZERO_ERROR
;
1235 length
=u_shapeArabic(source
, LENGTHOF(source
),
1236 dest
, LENGTHOF(dest
),
1237 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1238 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1241 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_near
) || uprv_memcmp(dest
, shape_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1242 log_err("failure in u_shapeArabic(TASHKEEL shape_near)\n");
1245 errorCode
=U_ZERO_ERROR
;
1247 length
=u_shapeArabic(source
, LENGTHOF(source
),
1248 dest
, LENGTHOF(dest
),
1249 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1250 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1253 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_near
) || uprv_memcmp(dest
, shape_excepttashkeel_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1254 log_err("failure in u_shapeArabic(TASHKEEL shape_excepttashkeel_near)\n");
1259 doLOGICALArabicDeShapingTest() {
1262 0x0020,0x0020,0x0020,0xFE8D,0xFEF5,0x0020,0xFEE5,0x0020,0xFE8D,0xFEF7,0x0020,
1263 0xFED7,0xFEFC,0x0020,0xFEE1,0x0020,0xFE8D,0xFEDF,0xFECC,0xFEAE,0xFE91,0xFEF4,
1264 0xFE94,0x0020,0xFE8D,0xFEDF,0xFEA4,0xFEAE,0xFE93,0x0020,0x0020,0x0020,0x0020
1266 0x20,0x20,0x20,0x627,0x644,0x622,0x646,0x20,0x627,0x644,0x623,0x642,0x644,0x627,
1267 0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,0x644,0x62d,0x631,
1268 0x629,0x20,0x20,0x20,0x20
1269 }, unshape_at_end
[]={
1270 0x20,0x20,0x20,0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642,
1271 0x644,0x627,0x20,0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,
1272 0x644,0x62d,0x631,0x629,0x20
1273 }, unshape_at_begin
[]={
1274 0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642,0x644,0x627,0x20,
1275 0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,0x644,0x62d,0x631,
1276 0x629,0x20,0x20,0x20,0x20
1277 }, unshape_grow_shrink
[]={
1278 0x20,0x20,0x20,0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642,
1279 0x644,0x627,0x20,0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,
1280 0x644,0x62d,0x631,0x629,0x20,0x20,0x20,0x20
1284 UErrorCode errorCode
;
1287 errorCode
=U_ZERO_ERROR
;
1289 length
=u_shapeArabic(source
, LENGTHOF(source
),
1290 dest
, LENGTHOF(dest
),
1291 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1292 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1295 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(unshape_near
) || uprv_memcmp(dest
, unshape_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1296 log_err("failure in u_shapeArabic(unshape_near)\n");
1299 errorCode
=U_ZERO_ERROR
;
1301 length
=u_shapeArabic(source
, LENGTHOF(source
),
1302 dest
, LENGTHOF(dest
),
1303 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_END
|
1304 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1307 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(unshape_at_end
) || uprv_memcmp(dest
, unshape_at_end
, length
*U_SIZEOF_UCHAR
)!=0) {
1308 log_err("failure in u_shapeArabic(unshape_at_end)\n");
1311 errorCode
=U_ZERO_ERROR
;
1313 length
=u_shapeArabic(source
, LENGTHOF(source
),
1314 dest
, LENGTHOF(dest
),
1315 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING
|
1316 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1319 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(unshape_at_begin
) || uprv_memcmp(dest
, unshape_at_begin
, length
*U_SIZEOF_UCHAR
)!=0) {
1320 log_err("failure in u_shapeArabic(unshape_at_begin)\n");
1323 errorCode
=U_ZERO_ERROR
;
1325 length
=u_shapeArabic(source
, LENGTHOF(source
),
1326 dest
, LENGTHOF(dest
),
1327 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_GROW_SHRINK
|
1328 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1331 if(U_FAILURE(errorCode
) || uprv_memcmp(dest
, unshape_grow_shrink
, length
*U_SIZEOF_UCHAR
)!=0) {
1332 log_err("failure in u_shapeArabic(unshape_grow_shrink)\n");
1337 /* helpers ------------------------------------------------------------------ */
1339 /* return a string with characters according to the desired directional properties */
1341 getStringFromDirProps(const uint8_t *dirProps
, int32_t length
) {
1342 static UChar s
[MAX_STRING_LENGTH
];
1345 /* this part would have to be modified for UTF-x */
1346 for(i
=0; i
<length
; ++i
) {
1347 s
[i
]=charFromDirProp
[dirProps
[i
]];
1354 printUnicode(const UChar
*s
, int32_t length
, const UBiDiLevel
*levels
) {
1358 for(i
=0; i
<length
; ++i
) {
1360 log_verbose("%4x.%u ", s
[i
], levels
[i
]);
1362 log_verbose("%4x ", s
[i
]);