1 /********************************************************************
3 * Copyright (c) 1997-2004, 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 ---------------------------------------------------------------*/
30 charFromDirPropTest(void);
36 doTests(UBiDi
*pBiDi
, UBiDi
*pLine
, UBool countRunsFirst
);
39 doTest(UBiDi
*pBiDi
, int testNumber
, BiDiTestData
*test
, int32_t lineStart
, UBool countRunsFirst
);
42 testReordering(UBiDi
*pBiDi
, int testNumber
);
45 doInverseBiDiTest(void);
48 testManyInverseBiDi(UBiDi
*pBiDi
, UBiDiLevel direction
);
51 testInverseBiDi(UBiDi
*pBiDi
, const UChar
*src
, int32_t srcLength
, UBiDiLevel direction
, UErrorCode
*pErrorCode
);
54 testWriteReverse(void);
57 doArabicShapingTest(void);
60 doLamAlefSpecialVLTRArabicShapingTest(void);
63 doTashkeelSpecialVLTRArabicShapingTest(void);
66 doLOGICALArabicDeShapingTest(void);
68 static void TestReorder(void);
70 /* helpers ------------------------------------------------------------------ */
72 static const char *levelString
="...............................................................";
75 initCharFromDirProps(void);
78 getStringFromDirProps(const uint8_t *dirProps
, int32_t length
);
81 printUnicode(const UChar
*s
, int32_t length
, const UBiDiLevel
*levels
);
83 /* regression tests ---------------------------------------------------------*/
85 void addComplexTest(TestNode
** root
);
88 addComplexTest(TestNode
** root
) {
89 addTest(root
, charFromDirPropTest
, "complex/bidi/charFromDirPropTest");
90 addTest(root
, doBiDiTest
, "complex/bidi/BiDiTest");
91 addTest(root
, doInverseBiDiTest
, "complex/bidi/inverse");
92 addTest(root
, TestReorder
,"complex/bidi/TestReorder");
93 addTest(root
, doArabicShapingTest
, "complex/arabic-shaping/ArabicShapingTest");
94 addTest(root
, doLamAlefSpecialVLTRArabicShapingTest
, "complex/arabic-shaping/lamalef");
95 addTest(root
, doTashkeelSpecialVLTRArabicShapingTest
, "complex/arabic-shaping/tashkeel");
96 addTest(root
, doLOGICALArabicDeShapingTest
, "complex/arabic-shaping/unshaping");
99 /* verify that the exemplar characters have the expected bidi classes */
101 charFromDirPropTest(void) {
104 initCharFromDirProps();
106 for(i
=0; i
<U_CHAR_DIRECTION_COUNT
; ++i
) {
107 if(u_charDirection(charFromDirProp
[i
])!=(UCharDirection
)i
) {
108 log_err("u_charDirection(charFromDirProp[%d]=U+%04x)==%d!=%d\n",
109 i
, charFromDirProp
[i
], u_charDirection(charFromDirProp
[i
]), i
);
116 UBiDi
*pBiDi
, *pLine
=NULL
;
117 UErrorCode errorCode
=U_ZERO_ERROR
;
119 log_verbose("*** bidi regression test ***\n");
121 pBiDi
=ubidi_openSized(MAX_STRING_LENGTH
, 0, &errorCode
);
125 doTests(pBiDi
, pLine
, FALSE
);
126 doTests(pBiDi
, pLine
, TRUE
);
128 log_err("ubidi_open() returned NULL, out of memory\n");
131 log_err("ubidi_openSized() returned NULL, errorCode %s\n", myErrorName(errorCode
));
141 log_verbose("*** bidi regression test finished ***\n");
145 doTests(UBiDi
*pBiDi
, UBiDi
*pLine
, UBool countRunsFirst
) {
148 UErrorCode errorCode
;
150 UBiDiLevel paraLevel
;
152 for(i
=0; i
<bidiTestCount
; ++i
) {
153 errorCode
=U_ZERO_ERROR
;
154 s
=getStringFromDirProps(tests
[i
].text
, tests
[i
].length
);
155 paraLevel
=tests
[i
].paraLevel
;
156 ubidi_setPara(pBiDi
, s
, -1, paraLevel
, NULL
, &errorCode
);
157 if(U_SUCCESS(errorCode
)) {
158 log_verbose("ubidi_setPara(tests[%d], paraLevel %d) ok, direction %d paraLevel=%d\n",
159 i
, paraLevel
, ubidi_getDirection(pBiDi
), ubidi_getParaLevel(pBiDi
));
160 lineStart
=tests
[i
].lineStart
;
162 doTest(pBiDi
, i
, tests
+i
, 0, countRunsFirst
);
164 ubidi_setLine(pBiDi
, lineStart
, tests
[i
].lineLimit
, pLine
, &errorCode
);
165 if(U_SUCCESS(errorCode
)) {
166 log_verbose("ubidi_setLine(%d, %d) ok, direction %d paraLevel=%d\n",
167 lineStart
, tests
[i
].lineLimit
, ubidi_getDirection(pLine
), ubidi_getParaLevel(pLine
));
168 doTest(pLine
, i
, tests
+i
, lineStart
, countRunsFirst
);
170 log_err("ubidi_setLine(tests[%d], %d, %d) failed with errorCode %s\n",
171 i
, lineStart
, tests
[i
].lineLimit
, myErrorName(errorCode
));
175 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
176 i
, paraLevel
, myErrorName(errorCode
));
180 static void TestReorder(){
181 static const char* const logicalOrder
[] ={
182 "DEL(\\u062F\\u0625)ADD(\\u062F.\\u0625.\\u200F)",
183 "DEL(\\u0645\\u0627\\u064A\\u0648) ADD(\\u0623\\u064A\\u0627\\u0631)",
184 "DEL(\\u0644\\u0644)ADD(\\u0644.\\u0644.\\u0029\\u0644)\\u0644.\\u200F",
185 "DEL(\\u0631\\u064A)ADD(\\u0631.\\u064A.) \\u0631.\\u064A.\\u200F",
186 "DAY 2 \\u0646 \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646 DAYABBR",
187 "DAY 3 \\u062B \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621 DAYABBR",
188 "DAY 4 \\u0631 \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621 DAYABBR",
189 "DAY 5 \\u062E \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633 DAYABBR",
190 "DAY 6 \\u062C \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629 DAYABBR",
191 "DAY 7 \\u0633 \\u0627\\u0644\\u0633\\u0628\\u062A DAYABBR",
192 "HELLO\\u0627\\u0644\\u0633\\u0628\\u062A",
194 static const char* const visualOrder
[]={
195 "DEL(\\u0625\\u062F)ADD(\\u200F.\\u0625.\\u062F)",
196 "DEL(\\u0648\\u064A\\u0627\\u0645) ADD(\\u0631\\u0627\\u064A\\u0623)",
197 "DEL(\\u0644\\u0644)ADD(\\u0644\\u0029.\\u0644.\\u0644)\\u200F.\\u0644",
198 /* I am doutful about this...
199 * what I would expect is :
200 * DEL(\\u064A\\u0631)ADD(.\\u064A.\\u0631) \\u200F.\\u064A.\\u0631
202 "DEL(\\u064A\\u0631)ADD(\\u200F.\\u064A.\\u0631 (.\\u064A.\\u0631",
203 "DAY 2 \\u0646\\u064A\\u0646\\u062B\\u0627\\u0644\\u0627 \\u0646 DAYABBR",
204 "DAY 3 \\u0621\\u0627\\u062B\\u0627\\u0644\\u062B\\u0644\\u0627 \\u062B DAYABBR",
205 "DAY 4 \\u0621\\u0627\\u0639\\u0628\\u0631\\u0623\\u0644\\u0627 \\u0631 DAYABBR",
206 "DAY 5 \\u0633\\u064A\\u0645\\u062E\\u0644\\u0627 \\u062E DAYABBR",
207 "DAY 6 \\u0629\\u0639\\u0645\\u062C\\u0644\\u0627 \\u062C DAYABBR",
208 "DAY 7 \\u062A\\u0628\\u0633\\u0644\\u0627 \\u0633 DAYABBR",
209 "HELLO\\u062A\\u0628\\u0633\\u0644\\u0627",
211 static const char* const visualOrder1
[]={
212 ")\\u062F.\\u0625.\\u200F(DDA)\\u062F\\u0625(LED",
213 ")\\u0623\\u064A\\u0627\\u0631(DDA )\\u0645\\u0627\\u064A\\u0648(LED",
214 "\\u0644.\\u0644.(\\u0644(\\u0644.\\u200F(DDA)\\u0644\\u0644(LED",
215 "\\u0631.\\u064A.( \\u0631.\\u064A.\\u200F(DDA)\\u0631\\u064A(LED",
216 "RBBAYAD \\u0646 \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646 2 YAD",
217 "RBBAYAD \\u062B \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621 3 YAD",
218 "RBBAYAD \\u0631 \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621 4 YAD",
219 "RBBAYAD \\u062E \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633 5 YAD",
220 "RBBAYAD \\u062C \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629 6 YAD",
221 "RBBAYAD \\u0633 \\u0627\\u0644\\u0633\\u0628\\u062A 7 YAD",
222 "\\u0627\\u0644\\u0633\\u0628\\u062AOLLEH",
225 static const char* const visualOrder2
[]={
226 "\\u200E)\\u200E\\u062F.\\u0625.\\u200F\\u200E(DDA)\\u200E\\u062F\\u0625\\u200E(LED",
227 "\\u200E)\\u200E\\u0623\\u064A\\u0627\\u0631\\u200E(DDA )\\u200E\\u0645\\u0627\\u064A\\u0648\\u200E(LED",
228 "\\u0644.\\u0644.)\\u0644)\\u0644.\\u200F\\u200E(DDA)\\u200E\\u0644\\u0644\\u200E(LED",
229 "\\u0631.\\u064A.) \\u0631.\\u064A.\\u200F\\u200E(DDA)\\u200E\\u0631\\u064A\\u200E(LED",
230 "RBBAYAD \\u200E\\u0646 \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646\\u200E 2 YAD",
231 "RBBAYAD \\u200E\\u062B \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621\\u200E 3 YAD",
232 "RBBAYAD \\u200E\\u0631 \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621\\u200E 4 YAD",
233 "RBBAYAD \\u200E\\u062E \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633\\u200E 5 YAD",
234 "RBBAYAD \\u200E\\u062C \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629\\u200E 6 YAD",
235 "RBBAYAD \\u200E\\u0633 \\u0627\\u0644\\u0633\\u0628\\u062A\\u200E 7 YAD",
236 "\\u0627\\u0644\\u0633\\u0628\\u062AOLLEH",
238 static const char* const visualOrder3
[]={
239 ")\\u062F.\\u0625.\\u200F(DDA)\\u062F\\u0625(LED",
240 ")\\u0623\\u064A\\u0627\\u0631(DDA )\\u0645\\u0627\\u064A\\u0648(LED",
241 "\\u0644.\\u0644.)\\u0644)\\u0644.\\u200F(\\u0644\\u0644)DDA(LED",
242 "\\u0631.\\u064A.) \\u0631.\\u064A.\\u200F(\\u0631\\u064A)DDA(LED",
243 "RBBAYAD \\u0627\\u0644\\u0627\\u062B\\u0646\\u064A\\u0646 \\u0646 2 YAD",
244 "RBBAYAD \\u0627\\u0644\\u062B\\u0644\\u0627\\u062B\\u0627\\u0621 \\u062B 3 YAD",
245 "RBBAYAD \\u0627\\u0644\\u0623\\u0631\\u0628\\u0639\\u0627\\u0621 \\u0631 4 YAD",
246 "RBBAYAD \\u0627\\u0644\\u062E\\u0645\\u064A\\u0633 \\u062E 5 YAD",
247 "RBBAYAD \\u0627\\u0644\\u062C\\u0645\\u0639\\u0629 \\u062C",
248 "RBBAYAD \\u0627\\u0644\\u0633\\u0628\\u062A \\u0633 7 YAD",
249 "\\u0627\\u0644\\u0633\\u0628\\u062AOLLEH"
251 static const char* const visualOrder4
[]={
252 "DEL(ADD(\\u0625\\u062F(.\\u0625.\\u062F)",
253 "DEL( (\\u0648\\u064A\\u0627\\u0645ADD(\\u0631\\u0627\\u064A\\u0623)",
254 "DEL(ADD(\\u0644\\u0644(.\\u0644(\\u0644(.\\u0644.\\u0644",
255 "DEL(ADD(\\u064A\\u0631(.\\u064A.\\u0631 (.\\u064A.\\u0631",
256 "DAY 2 \\u0646 \\u0646\\u064A\\u0646\\u062B\\u0627\\u0644\\u0627 DAYABBR",
257 "DAY 3 \\u062B \\u0621\\u0627\\u062B\\u0627\\u0644\\u062B\\u0644\\u0627 DAYABBR",
258 "DAY 4 \\u0631 \\u0621\\u0627\\u0639\\u0628\\u0631\\u0623\\u0644\\u0627 DAYABBR",
259 "DAY 5 \\u062E \\u0633\\u064A\\u0645\\u062E\\u0644\\u0627 DAYABBR",
260 "DAY 6 \\u062C \\u0629\\u0639\\u0645\\u062C\\u0644\\u0627 DAYABBR",
261 "DAY 7 \\u0633 \\u062A\\u0628\\u0633\\u0644\\u0627 DAYABBR ",
262 "HELLO\\u062A\\u0628\\u0633\\u0644\\u0627"
264 UErrorCode ec
= U_ZERO_ERROR
;
265 UBiDi
* bidi
= ubidi_open();
267 for(;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
268 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
269 int32_t destSize
= srcSize
*2;
270 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
271 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
274 u_unescape(logicalOrder
[i
],src
,srcSize
);
275 srcSize
= u_strlen(src
);
276 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,NULL
,&ec
);
278 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
279 i
, UBIDI_DEFAULT_LTR
, u_errorName(ec
));
281 /* try pre-flighting */
282 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_DO_MIRRORING
,&ec
);
283 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
284 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
285 }else if(destSize
!=srcSize
){
286 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize
,destSize
);
290 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_DO_MIRRORING
,&ec
);
291 chars
= aescstrdup(dest
,-1);
292 if(destSize
!=srcSize
){
293 log_err("ubidi_writeReordered() destSize and srcSize do not match\n");
294 }else if(uprv_strncmp(visualOrder
[i
],chars
,destSize
)!=0){
295 log_err("ubidi_writeReordered() did not give expected results. Expected: %s Got: %s At Index: %d\n",visualOrder
[i
],chars
,i
);
303 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
304 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
305 int32_t destSize
= srcSize
*2;
306 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
307 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
310 u_unescape(logicalOrder
[i
],src
,srcSize
);
311 srcSize
=u_strlen(src
);
312 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,NULL
,&ec
);
314 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
315 i
, UBIDI_DEFAULT_LTR
, u_errorName(ec
));
317 /* try pre-flighting */
318 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_DO_MIRRORING
+UBIDI_OUTPUT_REVERSE
,&ec
);
319 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
320 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
321 }else if(destSize
!=srcSize
){
322 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize
,destSize
);
326 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_DO_MIRRORING
+UBIDI_OUTPUT_REVERSE
,&ec
);
327 chars
= aescstrdup(dest
,destSize
);
328 if(destSize
!=srcSize
){
329 log_err("ubidi_writeReordered() destSize and srcSize do not match\n");
330 }else if(uprv_strncmp(visualOrder1
[i
],chars
,destSize
)!=0){
331 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
);
340 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
341 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
342 int32_t destSize
= srcSize
*2;
343 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
344 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
347 u_unescape(logicalOrder
[i
],src
,srcSize
);
348 srcSize
=u_strlen(src
);
349 ubidi_setInverse(bidi
,TRUE
);
350 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,NULL
,&ec
);
353 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
354 i
, UBIDI_DEFAULT_LTR
, u_errorName(ec
));
356 /* try pre-flighting */
357 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_INSERT_LRM_FOR_NUMERIC
+UBIDI_OUTPUT_REVERSE
,&ec
);
358 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
359 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
363 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_INSERT_LRM_FOR_NUMERIC
+UBIDI_OUTPUT_REVERSE
,&ec
);
364 chars
= aescstrdup(dest
,destSize
);
366 /*if(destSize!=srcSize){
367 log_err("ubidi_writeReordered() destSize and srcSize do not match. Dest Size = %d Source Size = %d\n",destSize,srcSize );
369 if(uprv_strncmp(visualOrder2
[i
],chars
,destSize
)!=0){
370 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
);
378 /* Max Explicit level */
379 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
380 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
381 int32_t destSize
= srcSize
*2;
382 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
383 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
385 UBiDiLevel levels
[UBIDI_MAX_EXPLICIT_LEVEL
]={1,2,3,4,5,6,7,8,9,10};
387 u_unescape(logicalOrder
[i
],src
,srcSize
);
388 srcSize
=u_strlen(src
);
389 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,levels
,&ec
);
391 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
392 i
, UBIDI_MAX_EXPLICIT_LEVEL
, u_errorName(ec
));
394 /* try pre-flighting */
395 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_OUTPUT_REVERSE
,&ec
);
396 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
397 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
398 }else if(destSize
!=srcSize
){
399 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize
,destSize
);
403 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_OUTPUT_REVERSE
,&ec
);
404 chars
= aescstrdup(dest
,destSize
);
406 if(destSize
!=srcSize
){
407 log_err("ubidi_writeReordered() destSize and srcSize do not match. Dest Size = %d Source Size = %d\n",destSize
,srcSize
);
408 }else if(uprv_strncmp(visualOrder3
[i
],chars
,destSize
)!=0){
409 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
);
417 for(i
=0;i
<(sizeof(logicalOrder
)/sizeof(logicalOrder
[0]));i
++){
418 int32_t srcSize
= (int32_t)uprv_strlen(logicalOrder
[i
]);
419 int32_t destSize
= srcSize
*2;
420 UChar
* src
= (UChar
*) malloc(sizeof(UChar
)*srcSize
);
421 UChar
* dest
= (UChar
*) malloc(sizeof(UChar
)*destSize
);
423 UBiDiLevel levels
[UBIDI_MAX_EXPLICIT_LEVEL
]={1,2,3,4,5,6,7,8,9,10};
425 u_unescape(logicalOrder
[i
],src
,srcSize
);
426 srcSize
=u_strlen(src
);
427 ubidi_setPara(bidi
,src
,srcSize
,UBIDI_DEFAULT_LTR
,levels
,&ec
);
429 log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
430 i
, UBIDI_MAX_EXPLICIT_LEVEL
, u_errorName(ec
));
433 /* try pre-flighting */
434 destSize
= ubidi_writeReordered(bidi
,dest
,0,UBIDI_DO_MIRRORING
+UBIDI_REMOVE_BIDI_CONTROLS
,&ec
);
435 if(ec
!=U_BUFFER_OVERFLOW_ERROR
){
436 log_err("Pre-flighting did not give expected error: Expected: U_BUFFER_OVERFLOW_ERROR. Got: %s \n",u_errorName(ec
));
437 /*}else if(destSize!=srcSize){
438 log_err("Pre-flighting did not give expected size: Expected: %d. Got: %d \n",srcSize,destSize);*/
442 destSize
=ubidi_writeReordered(bidi
,dest
,destSize
+1,UBIDI_DO_MIRRORING
+UBIDI_REMOVE_BIDI_CONTROLS
,&ec
);
443 chars
= aescstrdup(dest
,destSize
);
445 /*if(destSize!=srcSize){
446 log_err("ubidi_writeReordered() destSize and srcSize do not match. Dest Size = %d Source Size = %d\n",destSize,srcSize );
447 }else*/ if(uprv_strncmp(visualOrder4
[i
],chars
,destSize
)!=0){
448 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
);
458 doTest(UBiDi
*pBiDi
, int testNumber
, BiDiTestData
*test
, int32_t lineStart
, UBool countRunsFirst
) {
459 const uint8_t *dirProps
=test
->text
+lineStart
;
460 const UBiDiLevel
*levels
=test
->levels
;
461 const uint8_t *visualMap
=test
->visualMap
;
462 int32_t i
, len
=ubidi_getLength(pBiDi
), logicalIndex
, runCount
= 0;
463 UErrorCode errorCode
=U_ZERO_ERROR
;
464 UBiDiLevel level
, level2
;
466 if (countRunsFirst
) {
467 log_verbose("Calling ubidi_countRuns() first.\n");
469 runCount
= ubidi_countRuns(pBiDi
, &errorCode
);
471 if(U_FAILURE(errorCode
)) {
472 log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
476 log_verbose("Calling ubidi_getLogicalMap() first.\n");
479 testReordering(pBiDi
, testNumber
);
481 for(i
=0; i
<len
; ++i
) {
482 log_verbose("%3d %3d %.*s%-3s @%d\n",
483 i
, ubidi_getLevelAt(pBiDi
, i
), ubidi_getLevelAt(pBiDi
, i
), levelString
,
484 dirPropNames
[dirProps
[i
]],
485 ubidi_getVisualIndex(pBiDi
, i
, &errorCode
));
488 log_verbose("\n-----levels:");
489 for(i
=0; i
<len
; ++i
) {
493 log_verbose(" %d", ubidi_getLevelAt(pBiDi
, i
));
496 log_verbose("\n--reordered:");
497 for(i
=0; i
<len
; ++i
) {
501 log_verbose(" %d", ubidi_getVisualIndex(pBiDi
, i
, &errorCode
));
505 if(test
->direction
!=ubidi_getDirection(pBiDi
)) {
506 log_err("ubidi_getDirection(tests[%d]): wrong direction %d\n", testNumber
, ubidi_getDirection(pBiDi
));
509 if(test
->resultLevel
!=ubidi_getParaLevel(pBiDi
)) {
510 log_err("ubidi_getParaLevel(tests[%d]): wrong paragraph level %d\n", testNumber
, ubidi_getParaLevel(pBiDi
));
513 for(i
=0; i
<len
; ++i
) {
514 if(levels
[i
]!=ubidi_getLevelAt(pBiDi
, i
)) {
515 log_err("ubidi_getLevelAt(tests[%d], %d): wrong level %d\n", testNumber
, i
, ubidi_getLevelAt(pBiDi
, i
));
520 for(i
=0; i
<len
; ++i
) {
521 logicalIndex
=ubidi_getVisualIndex(pBiDi
, i
, &errorCode
);
522 if(U_FAILURE(errorCode
)) {
523 log_err("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber
, i
, myErrorName(errorCode
));
526 if(visualMap
[i
]!=logicalIndex
) {
527 log_err("ubidi_getVisualIndex(tests[%d], %d): wrong index %d\n", testNumber
, i
, logicalIndex
);
532 if (! countRunsFirst
) {
533 runCount
=ubidi_countRuns(pBiDi
, &errorCode
);
534 if(U_FAILURE(errorCode
)) {
535 log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
540 for(logicalIndex
=0; logicalIndex
<len
;) {
541 level
=ubidi_getLevelAt(pBiDi
, logicalIndex
);
542 ubidi_getLogicalRun(pBiDi
, logicalIndex
, &logicalIndex
, &level2
);
544 log_err("ubidi_getLogicalRun(tests[%d], run ending at index %d): wrong level %d\n", testNumber
, logicalIndex
, level2
);
547 log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs compared to %d=ubidi_getRunCount()\n", testNumber
, ubidi_countRuns(pBiDi
, &errorCode
));
552 log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs compared to %d=ubidi_getRunCount()\n", testNumber
, ubidi_countRuns(pBiDi
, &errorCode
));
560 testReordering(UBiDi
*pBiDi
, int testNumber
) {
562 logicalMap1
[200], logicalMap2
[200], logicalMap3
[200],
563 visualMap1
[200], visualMap2
[200], visualMap3
[200], visualMap4
[200];
564 UErrorCode errorCode
=U_ZERO_ERROR
;
565 UBiDiLevel levels
[200];
566 int32_t i
, length
=ubidi_getLength(pBiDi
);
567 int32_t runCount
, visualIndex
, logicalStart
, runLength
;
574 /* get the logical and visual maps from the object */
575 ubidi_getLogicalMap(pBiDi
, logicalMap1
, &errorCode
);
576 if(U_FAILURE(errorCode
)) {
577 log_err("ubidi_getLogicalMap(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
581 ubidi_getVisualMap(pBiDi
, visualMap1
, &errorCode
);
583 if(U_FAILURE(errorCode
)) {
584 log_err("ubidi_getVisualMap(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
588 /* invert them both */
589 ubidi_invertMap(logicalMap1
, visualMap2
, length
);
590 ubidi_invertMap(visualMap1
, logicalMap2
, length
);
592 /* get them from the levels array, too */
593 uprv_memcpy(levels
, ubidi_getLevels(pBiDi
, &errorCode
), length
);
595 if(U_FAILURE(errorCode
)) {
596 log_err("ubidi_getLevels(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
600 ubidi_reorderLogical(levels
, length
, logicalMap3
);
601 ubidi_reorderVisual(levels
, length
, visualMap3
);
603 /* get the visual map from the runs, too */
604 runCount
=ubidi_countRuns(pBiDi
, &errorCode
);
605 if(U_FAILURE(errorCode
)) {
606 log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber
, myErrorName(errorCode
));
610 log_verbose("\n----%2d runs:", runCount
);
611 for(i
=0; i
<runCount
; ++i
) {
612 odd
=(UBool
)(ubidi_getVisualRun(pBiDi
, i
, &logicalStart
, &runLength
));
613 log_verbose(" (%c @%d[%d])", odd
? 'R' : 'L', logicalStart
, runLength
);
618 for(i
=0; i
<runCount
; ++i
) {
619 if(UBIDI_LTR
==ubidi_getVisualRun(pBiDi
, i
, &logicalStart
, &runLength
)) {
621 visualMap4
[visualIndex
++]=logicalStart
++;
622 } while(--runLength
>0);
624 logicalStart
+=runLength
; /* logicalLimit */
626 visualMap4
[visualIndex
++]=--logicalStart
;
627 } while(--runLength
>0);
631 /* print all the maps */
632 log_verbose("logical maps:\n");
633 for(i
=0; i
<length
; ++i
) {
634 log_verbose("%4d", logicalMap1
[i
]);
637 for(i
=0; i
<length
; ++i
) {
638 log_verbose("%4d", logicalMap2
[i
]);
641 for(i
=0; i
<length
; ++i
) {
642 log_verbose("%4d", logicalMap3
[i
]);
645 log_verbose("\nvisual maps:\n");
646 for(i
=0; i
<length
; ++i
) {
647 log_verbose("%4d", visualMap1
[i
]);
650 for(i
=0; i
<length
; ++i
) {
651 log_verbose("%4d", visualMap2
[i
]);
654 for(i
=0; i
<length
; ++i
) {
655 log_verbose("%4d", visualMap3
[i
]);
658 for(i
=0; i
<length
; ++i
) {
659 log_verbose("%4d", visualMap4
[i
]);
663 /* check that the indexes are the same between these and ubidi_getLogical/VisualIndex() */
664 for(i
=0; i
<length
; ++i
) {
665 if(logicalMap1
[i
]!=logicalMap2
[i
]) {
666 log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap2[i] at i=%d\n", testNumber
, i
);
669 if(logicalMap1
[i
]!=logicalMap3
[i
]) {
670 log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap3[i] at i=%d\n", testNumber
, i
);
674 if(visualMap1
[i
]!=visualMap2
[i
]) {
675 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap2[i] at i=%d\n", testNumber
, i
);
678 if(visualMap1
[i
]!=visualMap3
[i
]) {
679 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap3[i] at i=%d\n", testNumber
, i
);
682 if(visualMap1
[i
]!=visualMap4
[i
]) {
683 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap4[i] at i=%d\n", testNumber
, i
);
687 if(logicalMap1
[i
]!=ubidi_getVisualIndex(pBiDi
, i
, &errorCode
)) {
688 log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=ubidi_getVisualIndex(i) at i=%d\n", testNumber
, i
);
691 if(U_FAILURE(errorCode
)) {
692 log_verbose("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber
, i
, myErrorName(errorCode
));
695 if(visualMap1
[i
]!=ubidi_getLogicalIndex(pBiDi
, i
, &errorCode
)) {
696 log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=ubidi_getLogicalIndex(i) at i=%d\n", testNumber
, i
);
699 if(U_FAILURE(errorCode
)) {
700 log_verbose("ubidi_getLogicalIndex(tests[%d], %d): error %s\n", testNumber
, i
, myErrorName(errorCode
));
707 /* inverse BiDi ------------------------------------------------------------- */
710 string0
[]={ 0x6c, 0x61, 0x28, 0x74, 0x69, 0x6e, 0x20, 0x5d0, 0x5d1, 0x29, 0x5d2, 0x5d3 },
711 string1
[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x31, 0x32, 0x33 },
712 string2
[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x28, 0x5d1, 0x5d2, 0x20, 0x31, 0x29, 0x32, 0x33 },
713 string3
[]={ 0x31, 0x32, 0x33, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x34, 0x35, 0x36 },
714 string4
[]={ 0x61, 0x62, 0x20, 0x61, 0x62, 0x20, 0x661, 0x662 };
716 #define STRING_TEST_CASE(s) { (s), LENGTHOF(s) }
718 static const struct {
722 STRING_TEST_CASE(string0
),
723 STRING_TEST_CASE(string1
),
724 STRING_TEST_CASE(string2
),
725 STRING_TEST_CASE(string3
)
728 static int countRoundtrips
=0, countNonRoundtrips
=0;
731 doInverseBiDiTest() {
733 UErrorCode errorCode
;
738 log_err("unable to open a UBiDi object (out of memory)\n");
742 log_verbose("inverse BiDi: testInverseBiDi(L) with %u test cases ---\n", LENGTHOF(testCases
));
743 for(i
=0; i
<LENGTHOF(testCases
); ++i
) {
744 errorCode
=U_ZERO_ERROR
;
745 testInverseBiDi(pBiDi
, testCases
[i
].s
, testCases
[i
].length
, 0, &errorCode
);
748 log_verbose("inverse BiDi: testInverseBiDi(R) with %u test cases ---\n", LENGTHOF(testCases
));
749 for(i
=0; i
<LENGTHOF(testCases
); ++i
) {
750 errorCode
=U_ZERO_ERROR
;
751 testInverseBiDi(pBiDi
, testCases
[i
].s
, testCases
[i
].length
, 1, &errorCode
);
754 testManyInverseBiDi(pBiDi
, 0);
755 testManyInverseBiDi(pBiDi
, 1);
759 log_verbose("inverse BiDi: rountrips: %5u\nnon-roundtrips: %5u\n", countRoundtrips
, countNonRoundtrips
);
764 #define COUNT_REPEAT_SEGMENTS 6
766 static const UChar repeatSegments
[COUNT_REPEAT_SEGMENTS
][2]={
767 { 0x61, 0x62 }, /* L */
768 { 0x5d0, 0x5d1 }, /* R */
769 { 0x627, 0x628 }, /* AL */
770 { 0x31, 0x32 }, /* EN */
771 { 0x661, 0x662 }, /* AN */
772 { 0x20, 0x20 } /* WS (N) */
776 testManyInverseBiDi(UBiDi
*pBiDi
, UBiDiLevel direction
) {
777 static UChar text
[8]={ 0, 0, 0x20, 0, 0, 0x20, 0, 0 };
779 UErrorCode errorCode
;
781 log_verbose("inverse BiDi: testManyInverseBiDi(%c) - test permutations of text snippets ---\n", direction
==0 ? 'L' : 'R');
782 for(i
=0; i
<COUNT_REPEAT_SEGMENTS
; ++i
) {
783 text
[0]=repeatSegments
[i
][0];
784 text
[1]=repeatSegments
[i
][1];
785 for(j
=0; j
<COUNT_REPEAT_SEGMENTS
; ++j
) {
786 text
[3]=repeatSegments
[j
][0];
787 text
[4]=repeatSegments
[j
][1];
788 for(k
=0; k
<COUNT_REPEAT_SEGMENTS
; ++k
) {
789 text
[6]=repeatSegments
[k
][0];
790 text
[7]=repeatSegments
[k
][1];
792 errorCode
=U_ZERO_ERROR
;
793 log_verbose("inverse BiDi: testManyInverseBiDi()[%u %u %u]\n", i
, j
, k
);
794 testInverseBiDi(pBiDi
, text
, 8, direction
, &errorCode
);
801 testInverseBiDi(UBiDi
*pBiDi
, const UChar
*src
, int32_t srcLength
, UBiDiLevel direction
, UErrorCode
*pErrorCode
) {
802 static UChar visualLTR
[200], logicalDest
[200], visualDest
[200];
803 int32_t ltrLength
, logicalLength
, visualLength
;
806 log_verbose("inverse BiDi: testInverseBiDi(L)\n");
808 /* convert visual to logical */
809 ubidi_setInverse(pBiDi
, TRUE
);
810 ubidi_setPara(pBiDi
, src
, srcLength
, 0, NULL
, pErrorCode
);
811 logicalLength
=ubidi_writeReordered(pBiDi
, logicalDest
, LENGTHOF(logicalDest
),
812 UBIDI_DO_MIRRORING
|UBIDI_INSERT_LRM_FOR_NUMERIC
, pErrorCode
);
814 printUnicode(src
, srcLength
, ubidi_getLevels(pBiDi
, pErrorCode
));
817 /* convert back to visual LTR */
818 ubidi_setInverse(pBiDi
, FALSE
);
819 ubidi_setPara(pBiDi
, logicalDest
, logicalLength
, 0, NULL
, pErrorCode
);
820 visualLength
=ubidi_writeReordered(pBiDi
, visualDest
, LENGTHOF(visualDest
),
821 UBIDI_DO_MIRRORING
|UBIDI_REMOVE_BIDI_CONTROLS
, pErrorCode
);
823 log_verbose("inverse BiDi: testInverseBiDi(R)\n");
825 /* reverse visual from RTL to LTR */
826 ltrLength
=ubidi_writeReverse(src
, srcLength
, visualLTR
, LENGTHOF(visualLTR
), 0, pErrorCode
);
828 printUnicode(src
, srcLength
, NULL
);
831 /* convert visual RTL to logical */
832 ubidi_setInverse(pBiDi
, TRUE
);
833 ubidi_setPara(pBiDi
, visualLTR
, ltrLength
, 0, NULL
, pErrorCode
);
834 logicalLength
=ubidi_writeReordered(pBiDi
, logicalDest
, LENGTHOF(logicalDest
),
835 UBIDI_DO_MIRRORING
|UBIDI_INSERT_LRM_FOR_NUMERIC
, pErrorCode
);
837 printUnicode(visualLTR
, ltrLength
, ubidi_getLevels(pBiDi
, pErrorCode
));
840 /* convert back to visual RTL */
841 ubidi_setInverse(pBiDi
, FALSE
);
842 ubidi_setPara(pBiDi
, logicalDest
, logicalLength
, 0, NULL
, pErrorCode
);
843 visualLength
=ubidi_writeReordered(pBiDi
, visualDest
, LENGTHOF(visualDest
),
844 UBIDI_DO_MIRRORING
|UBIDI_REMOVE_BIDI_CONTROLS
|UBIDI_OUTPUT_REVERSE
, pErrorCode
);
847 printUnicode(logicalDest
, logicalLength
, ubidi_getLevels(pBiDi
, pErrorCode
));
850 printUnicode(visualDest
, visualLength
, NULL
);
853 /* check and print results */
854 if(U_FAILURE(*pErrorCode
)) {
855 log_err("inverse BiDi: *** error %s\n"
856 " turn on verbose mode to see details\n", u_errorName(*pErrorCode
));
857 } else if(srcLength
==visualLength
&& uprv_memcmp(src
, visualDest
, srcLength
*U_SIZEOF_UCHAR
)==0) {
859 log_verbose(" + roundtripped\n");
861 ++countNonRoundtrips
;
862 log_verbose(" * did not roundtrip\n");
863 log_err("inverse BiDi: transformation visual->logical->visual did not roundtrip the text;\n"
864 " turn on verbose mode to see details\n");
870 /* U+064e and U+0650 are combining marks (Mn) */
871 static const UChar forward
[]={
872 0x200f, 0x627, 0x64e, 0x650, 0x20, 0x28, 0x31, 0x29
873 }, reverseKeepCombining
[]={
874 0x29, 0x31, 0x28, 0x20, 0x627, 0x64e, 0x650, 0x200f
875 }, reverseRemoveControlsKeepCombiningDoMirror
[]={
876 0x28, 0x31, 0x29, 0x20, 0x627, 0x64e, 0x650
878 static UChar reverse
[10];
879 UErrorCode errorCode
;
882 /* test ubidi_writeReverse() with "interesting" options */
883 errorCode
=U_ZERO_ERROR
;
884 length
=ubidi_writeReverse(forward
, LENGTHOF(forward
),
885 reverse
, LENGTHOF(reverse
),
886 UBIDI_KEEP_BASE_COMBINING
,
888 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(reverseKeepCombining
) || uprv_memcmp(reverse
, reverseKeepCombining
, length
*U_SIZEOF_UCHAR
)!=0) {
889 log_err("failure in ubidi_writeReverse(UBIDI_KEEP_BASE_COMBINING): length=%d (should be %d), error code %s\n",
890 length
, LENGTHOF(reverseKeepCombining
), u_errorName(errorCode
));
893 uprv_memset(reverse
, 0xa5, LENGTHOF(reverse
)*U_SIZEOF_UCHAR
);
894 errorCode
=U_ZERO_ERROR
;
895 length
=ubidi_writeReverse(forward
, LENGTHOF(forward
),
896 reverse
, LENGTHOF(reverse
),
897 UBIDI_REMOVE_BIDI_CONTROLS
|UBIDI_DO_MIRRORING
|UBIDI_KEEP_BASE_COMBINING
,
899 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror
) || uprv_memcmp(reverse
, reverseRemoveControlsKeepCombiningDoMirror
, length
*U_SIZEOF_UCHAR
)!=0) {
900 log_err("failure in ubidi_writeReverse(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING):\n"
901 " length=%d (should be %d), error code %s\n",
902 length
, LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror
), u_errorName(errorCode
));
906 /* arabic shaping ----------------------------------------------------------- */
909 doArabicShapingTest() {
913 0x627, /* arabic:alef */
920 0x661, 0x627, 0x662, 0x6f3, 0x61, 0x664, 0
922 0x31, 0x627, 0x32, 0x33, 0x61, 0x34, 0
923 }, logical_alen2an_init_lr
[]={
924 0x31, 0x627, 0x662, 0x6f3, 0x61, 0x34, 0
925 }, logical_alen2an_init_al
[]={
926 0x6f1, 0x627, 0x6f2, 0x6f3, 0x61, 0x34, 0
927 }, reverse_alen2an_init_lr
[]={
928 0x661, 0x627, 0x32, 0x6f3, 0x61, 0x34, 0
929 }, reverse_alen2an_init_al
[]={
930 0x6f1, 0x627, 0x32, 0x6f3, 0x61, 0x6f4, 0
933 UErrorCode errorCode
;
936 /* test number shaping */
938 /* european->arabic */
939 errorCode
=U_ZERO_ERROR
;
940 length
=u_shapeArabic(source
, LENGTHOF(source
),
941 dest
, LENGTHOF(dest
),
942 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
944 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, en2an
, length
*U_SIZEOF_UCHAR
)!=0) {
945 log_err("failure in u_shapeArabic(en2an)\n");
948 /* arabic->european */
949 errorCode
=U_ZERO_ERROR
;
950 length
=u_shapeArabic(source
, -1,
951 dest
, LENGTHOF(dest
),
952 U_SHAPE_DIGITS_AN2EN
|U_SHAPE_DIGIT_TYPE_AN_EXTENDED
,
954 if(U_FAILURE(errorCode
) || length
!=u_strlen(source
) || uprv_memcmp(dest
, an2en
, length
*U_SIZEOF_UCHAR
)!=0) {
955 log_err("failure in u_shapeArabic(an2en)\n");
958 /* european->arabic with context, logical order, initial state not AL */
959 errorCode
=U_ZERO_ERROR
;
960 length
=u_shapeArabic(source
, LENGTHOF(source
),
961 dest
, LENGTHOF(dest
),
962 U_SHAPE_DIGITS_ALEN2AN_INIT_LR
|U_SHAPE_DIGIT_TYPE_AN
,
964 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, logical_alen2an_init_lr
, length
*U_SIZEOF_UCHAR
)!=0) {
965 log_err("failure in u_shapeArabic(logical_alen2an_init_lr)\n");
968 /* european->arabic with context, logical order, initial state AL */
969 errorCode
=U_ZERO_ERROR
;
970 length
=u_shapeArabic(source
, LENGTHOF(source
),
971 dest
, LENGTHOF(dest
),
972 U_SHAPE_DIGITS_ALEN2AN_INIT_AL
|U_SHAPE_DIGIT_TYPE_AN_EXTENDED
,
974 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, logical_alen2an_init_al
, length
*U_SIZEOF_UCHAR
)!=0) {
975 log_err("failure in u_shapeArabic(logical_alen2an_init_al)\n");
978 /* european->arabic with context, reverse order, initial state not AL */
979 errorCode
=U_ZERO_ERROR
;
980 length
=u_shapeArabic(source
, LENGTHOF(source
),
981 dest
, LENGTHOF(dest
),
982 U_SHAPE_DIGITS_ALEN2AN_INIT_LR
|U_SHAPE_DIGIT_TYPE_AN
|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
984 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, reverse_alen2an_init_lr
, length
*U_SIZEOF_UCHAR
)!=0) {
985 log_err("failure in u_shapeArabic(reverse_alen2an_init_lr)\n");
988 /* european->arabic with context, reverse order, initial state AL */
989 errorCode
=U_ZERO_ERROR
;
990 length
=u_shapeArabic(source
, LENGTHOF(source
),
991 dest
, LENGTHOF(dest
),
992 U_SHAPE_DIGITS_ALEN2AN_INIT_AL
|U_SHAPE_DIGIT_TYPE_AN_EXTENDED
|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
994 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, reverse_alen2an_init_al
, length
*U_SIZEOF_UCHAR
)!=0) {
995 log_err("failure in u_shapeArabic(reverse_alen2an_init_al)\n");
999 errorCode
=U_ZERO_ERROR
;
1000 length
=u_shapeArabic(source
, LENGTHOF(source
),
1001 dest
, LENGTHOF(dest
),
1004 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(source
) || uprv_memcmp(dest
, source
, length
*U_SIZEOF_UCHAR
)!=0) {
1005 log_err("failure in u_shapeArabic(noop)\n");
1008 errorCode
=U_ZERO_ERROR
;
1009 length
=u_shapeArabic(source
, 0,
1010 dest
, LENGTHOF(dest
),
1011 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1013 if(U_FAILURE(errorCode
) || length
!=0) {
1014 log_err("failure in u_shapeArabic(en2an, sourceLength=0), returned %d/%s\n", u_errorName(errorCode
), LENGTHOF(source
));
1017 /* preflight digit shaping */
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_BUFFER_OVERFLOW_ERROR
|| length
!=LENGTHOF(source
)) {
1024 log_err("failure in u_shapeArabic(en2an preflighting), returned %d/%s instead of %d/U_BUFFER_OVERFLOW_ERROR\n",
1025 length
, u_errorName(errorCode
), LENGTHOF(source
));
1028 /* test illegal arguments */
1029 errorCode
=U_ZERO_ERROR
;
1030 length
=u_shapeArabic(NULL
, LENGTHOF(source
),
1031 dest
, LENGTHOF(dest
),
1032 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1034 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1035 log_err("failure in u_shapeArabic(source=NULL), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1038 errorCode
=U_ZERO_ERROR
;
1039 length
=u_shapeArabic(source
, -2,
1040 dest
, LENGTHOF(dest
),
1041 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1043 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1044 log_err("failure in u_shapeArabic(sourceLength=-2), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1047 errorCode
=U_ZERO_ERROR
;
1048 length
=u_shapeArabic(source
, LENGTHOF(source
),
1049 NULL
, LENGTHOF(dest
),
1050 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1052 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1053 log_err("failure in u_shapeArabic(dest=NULL), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1056 errorCode
=U_ZERO_ERROR
;
1057 length
=u_shapeArabic(source
, LENGTHOF(source
),
1059 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1061 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1062 log_err("failure in u_shapeArabic(destSize=-1), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1065 errorCode
=U_ZERO_ERROR
;
1066 length
=u_shapeArabic(source
, LENGTHOF(source
),
1067 dest
, LENGTHOF(dest
),
1068 U_SHAPE_DIGITS_RESERVED
|U_SHAPE_DIGIT_TYPE_AN
,
1070 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1071 log_err("failure in u_shapeArabic(U_SHAPE_DIGITS_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1074 errorCode
=U_ZERO_ERROR
;
1075 length
=u_shapeArabic(source
, LENGTHOF(source
),
1076 dest
, LENGTHOF(dest
),
1077 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_RESERVED
,
1079 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1080 log_err("failure in u_shapeArabic(U_SHAPE_DIGIT_TYPE_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1083 errorCode
=U_ZERO_ERROR
;
1084 length
=u_shapeArabic(source
, LENGTHOF(source
),
1085 (UChar
*)(source
+2), LENGTHOF(dest
), /* overlap source and destination */
1086 U_SHAPE_DIGITS_EN2AN
|U_SHAPE_DIGIT_TYPE_AN
,
1088 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
1089 log_err("failure in u_shapeArabic(U_SHAPE_DIGIT_TYPE_RESERVED), returned %s instead of U_ILLEGAL_ARGUMENT_ERROR\n", u_errorName(errorCode
));
1094 doLamAlefSpecialVLTRArabicShapingTest() {
1097 /*a*/ 0x20 ,0x646,0x622,0x644,0x627,0x20,
1098 /*b*/ 0x646,0x623,0x64E,0x644,0x627,0x20,
1099 /*c*/ 0x646,0x627,0x670,0x644,0x627,0x20,
1100 /*d*/ 0x646,0x622,0x653,0x644,0x627,0x20,
1101 /*e*/ 0x646,0x625,0x655,0x644,0x627,0x20,
1102 /*f*/ 0x646,0x622,0x654,0x644,0x627,0x20,
1105 0x20,0xfee5,0x20,0xfef5,0xfe8d,0x20,0xfee5,0x20,0xfe76,0xfef7,0xfe8d,0x20,
1106 0xfee5,0x20,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x20,0x653,0xfef5,0xfe8d,0x20,
1107 0xfee5,0x20,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x20,0x654,0xfef5,0xfe8d,0x20,
1110 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,0x670,
1111 0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,0xfe8d,
1112 0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb,0x20,0x20,0x20,0x20,0x20,0x20
1113 }, shape_at_begin
[]={
1114 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,
1115 0xfef7,0xfe8d,0x20,0xfee5,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,
1116 0x20,0xfee5,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1117 }, shape_grow_shrink
[]={
1118 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,
1119 0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,
1120 0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1121 }, shape_excepttashkeel_near
[]={
1122 0x20,0xfee5,0x20,0xfef5,0xfe8d,0x20,0xfee5,0x20,0xfe76,0xfef7,0xfe8d,0x20,
1123 0xfee5,0x20,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x20,0x653,0xfef5,0xfe8d,0x20,
1124 0xfee5,0x20,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x20,0x654,0xfef5,0xfe8d,0x20,
1126 }, shape_excepttashkeel_at_end
[]={
1127 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,
1128 0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,
1129 0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb,0x20,0x20,0x20,
1131 }, shape_excepttashkeel_at_begin
[]={
1132 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,
1133 0xfef7,0xfe8d,0x20,0xfee5,0x670,0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,
1134 0x20,0xfee5,0x655,0xfef9,0xfe8d,0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1135 }, shape_excepttashkeel_grow_shrink
[]={
1136 0x20,0xfee5,0xfef5,0xfe8d,0x20,0xfee5,0xfe76,0xfef7,0xfe8d,0x20,0xfee5,0x670,
1137 0xfefb,0xfe8d,0x20,0xfee5,0x653,0xfef5,0xfe8d,0x20,0xfee5,0x655,0xfef9,0xfe8d,
1138 0x20,0xfee5,0x654,0xfef5,0xfe8d,0x20,0xfefc,0xfecb
1142 UErrorCode errorCode
;
1145 errorCode
=U_ZERO_ERROR
;
1147 length
=u_shapeArabic(source
, LENGTHOF(source
),
1148 dest
, LENGTHOF(dest
),
1149 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1150 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1153 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_near
) || uprv_memcmp(dest
, shape_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1154 log_err("failure in u_shapeArabic(LAMALEF shape_near)\n");
1157 errorCode
=U_ZERO_ERROR
;
1159 length
=u_shapeArabic(source
, LENGTHOF(source
),
1160 dest
, LENGTHOF(dest
),
1161 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_END
|
1162 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1165 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_at_end
) || uprv_memcmp(dest
, shape_at_end
, length
*U_SIZEOF_UCHAR
)!=0) {
1166 log_err("failure in u_shapeArabic(LAMALEF shape_at_end)\n");
1169 errorCode
=U_ZERO_ERROR
;
1171 length
=u_shapeArabic(source
, LENGTHOF(source
),
1172 dest
, LENGTHOF(dest
),
1173 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING
|
1174 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1177 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_at_begin
) || uprv_memcmp(dest
, shape_at_begin
, length
*U_SIZEOF_UCHAR
)!=0) {
1178 log_err("failure in u_shapeArabic(LAMALEF shape_at_begin)\n");
1181 errorCode
=U_ZERO_ERROR
;
1183 length
=u_shapeArabic(source
, LENGTHOF(source
),
1184 dest
, LENGTHOF(dest
),
1185 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_GROW_SHRINK
|
1186 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1189 if(U_FAILURE(errorCode
) || uprv_memcmp(dest
, shape_grow_shrink
, length
*U_SIZEOF_UCHAR
)!=0) {
1190 log_err("failure in u_shapeArabic(LAMALEF shape_grow_shrink)\n");
1193 /* ==================== U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED ==================== */
1195 errorCode
=U_ZERO_ERROR
;
1197 length
=u_shapeArabic(source
, LENGTHOF(source
),
1198 dest
, LENGTHOF(dest
),
1199 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1200 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1203 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_near
) || uprv_memcmp(dest
, shape_excepttashkeel_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1204 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_near)\n");
1207 errorCode
=U_ZERO_ERROR
;
1209 length
=u_shapeArabic(source
, LENGTHOF(source
),
1210 dest
, LENGTHOF(dest
),
1211 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_AT_END
|
1212 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1215 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_at_end
) || uprv_memcmp(dest
,shape_excepttashkeel_at_end
, length
*U_SIZEOF_UCHAR
)!=0) {
1216 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_at_end)\n");
1219 errorCode
=U_ZERO_ERROR
;
1221 length
=u_shapeArabic(source
, LENGTHOF(source
),
1222 dest
, LENGTHOF(dest
),
1223 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING
|
1224 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1227 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_at_begin
) || uprv_memcmp(dest
, shape_excepttashkeel_at_begin
, length
*U_SIZEOF_UCHAR
)!=0) {
1228 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_at_begin)\n");
1231 errorCode
=U_ZERO_ERROR
;
1233 length
=u_shapeArabic(source
, LENGTHOF(source
),
1234 dest
, LENGTHOF(dest
),
1235 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_GROW_SHRINK
|
1236 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1239 if(U_FAILURE(errorCode
) || uprv_memcmp(dest
, shape_excepttashkeel_grow_shrink
, length
*U_SIZEOF_UCHAR
)!=0) {
1240 log_err("failure in u_shapeArabic(LAMALEF shape_excepttashkeel_grow_shrink)\n");
1245 doTashkeelSpecialVLTRArabicShapingTest() {
1248 0x64A,0x628,0x631,0x639,0x20,
1249 0x64A,0x628,0x651,0x631,0x64E,0x639,0x20,
1250 0x64C,0x64A,0x628,0x631,0x64F,0x639,0x20,
1251 0x628,0x670,0x631,0x670,0x639,0x20,
1252 0x628,0x653,0x631,0x653,0x639,0x20,
1253 0x628,0x654,0x631,0x654,0x639,0x20,
1254 0x628,0x655,0x631,0x655,0x639,0x20,
1256 0xfef2,0xfe91,0xfeae,0xfecb,0x20,0xfef2,0xfe91,0xfe7c,0xfeae,0xfe77,0xfecb,
1257 0x20,0xfe72,0xfef2,0xfe91,0xfeae,0xfe79,0xfecb,0x20,0xfe8f,0x670,0xfeae,0x670,
1258 0xfecb,0x20,0xfe8f,0x653,0xfeae,0x653,0xfecb,0x20,0xfe8f,0x654,0xfeae,0x654,
1259 0xfecb,0x20,0xfe8f,0x655,0xfeae,0x655,0xfecb,0x20
1260 }, shape_excepttashkeel_near
[]={
1261 0xfef2,0xfe91,0xfeae,0xfecb,0x20,0xfef2,0xfe91,0xfe7c,0xfeae,0xfe76,0xfecb,0x20,
1262 0xfe72,0xfef2,0xfe91,0xfeae,0xfe78,0xfecb,0x20,0xfe8f,0x670,0xfeae,0x670,0xfecb,
1263 0x20,0xfe8f,0x653,0xfeae,0x653,0xfecb,0x20,0xfe8f,0x654,0xfeae,0x654,0xfecb,0x20,
1264 0xfe8f,0x655,0xfeae,0x655,0xfecb,0x20
1268 UErrorCode errorCode
;
1271 errorCode
=U_ZERO_ERROR
;
1273 length
=u_shapeArabic(source
, LENGTHOF(source
),
1274 dest
, LENGTHOF(dest
),
1275 U_SHAPE_LETTERS_SHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1276 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1279 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_near
) || uprv_memcmp(dest
, shape_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1280 log_err("failure in u_shapeArabic(TASHKEEL shape_near)\n");
1283 errorCode
=U_ZERO_ERROR
;
1285 length
=u_shapeArabic(source
, LENGTHOF(source
),
1286 dest
, LENGTHOF(dest
),
1287 U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1288 U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
,
1291 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(shape_excepttashkeel_near
) || uprv_memcmp(dest
, shape_excepttashkeel_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1292 log_err("failure in u_shapeArabic(TASHKEEL shape_excepttashkeel_near)\n");
1297 doLOGICALArabicDeShapingTest() {
1300 0x0020,0x0020,0x0020,0xFE8D,0xFEF5,0x0020,0xFEE5,0x0020,0xFE8D,0xFEF7,0x0020,
1301 0xFED7,0xFEFC,0x0020,0xFEE1,0x0020,0xFE8D,0xFEDF,0xFECC,0xFEAE,0xFE91,0xFEF4,
1302 0xFE94,0x0020,0xFE8D,0xFEDF,0xFEA4,0xFEAE,0xFE93,0x0020,0x0020,0x0020,0x0020
1304 0x20,0x20,0x20,0x627,0x644,0x622,0x646,0x20,0x627,0x644,0x623,0x642,0x644,0x627,
1305 0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,0x644,0x62d,0x631,
1306 0x629,0x20,0x20,0x20,0x20
1307 }, unshape_at_end
[]={
1308 0x20,0x20,0x20,0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642,
1309 0x644,0x627,0x20,0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,
1310 0x644,0x62d,0x631,0x629,0x20
1311 }, unshape_at_begin
[]={
1312 0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642,0x644,0x627,0x20,
1313 0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,0x644,0x62d,0x631,
1314 0x629,0x20,0x20,0x20,0x20
1315 }, unshape_grow_shrink
[]={
1316 0x20,0x20,0x20,0x627,0x644,0x622,0x20,0x646,0x20,0x627,0x644,0x623,0x20,0x642,
1317 0x644,0x627,0x20,0x645,0x20,0x627,0x644,0x639,0x631,0x628,0x64a,0x629,0x20,0x627,
1318 0x644,0x62d,0x631,0x629,0x20,0x20,0x20,0x20
1322 UErrorCode errorCode
;
1325 errorCode
=U_ZERO_ERROR
;
1327 length
=u_shapeArabic(source
, LENGTHOF(source
),
1328 dest
, LENGTHOF(dest
),
1329 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_NEAR
|
1330 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1333 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(unshape_near
) || uprv_memcmp(dest
, unshape_near
, length
*U_SIZEOF_UCHAR
)!=0) {
1334 log_err("failure in u_shapeArabic(unshape_near)\n");
1337 errorCode
=U_ZERO_ERROR
;
1339 length
=u_shapeArabic(source
, LENGTHOF(source
),
1340 dest
, LENGTHOF(dest
),
1341 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_END
|
1342 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1345 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(unshape_at_end
) || uprv_memcmp(dest
, unshape_at_end
, length
*U_SIZEOF_UCHAR
)!=0) {
1346 log_err("failure in u_shapeArabic(unshape_at_end)\n");
1349 errorCode
=U_ZERO_ERROR
;
1351 length
=u_shapeArabic(source
, LENGTHOF(source
),
1352 dest
, LENGTHOF(dest
),
1353 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING
|
1354 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1357 if(U_FAILURE(errorCode
) || length
!=LENGTHOF(unshape_at_begin
) || uprv_memcmp(dest
, unshape_at_begin
, length
*U_SIZEOF_UCHAR
)!=0) {
1358 log_err("failure in u_shapeArabic(unshape_at_begin)\n");
1361 errorCode
=U_ZERO_ERROR
;
1363 length
=u_shapeArabic(source
, LENGTHOF(source
),
1364 dest
, LENGTHOF(dest
),
1365 U_SHAPE_LETTERS_UNSHAPE
|U_SHAPE_LENGTH_GROW_SHRINK
|
1366 U_SHAPE_TEXT_DIRECTION_LOGICAL
,
1369 if(U_FAILURE(errorCode
) || uprv_memcmp(dest
, unshape_grow_shrink
, length
*U_SIZEOF_UCHAR
)!=0) {
1370 log_err("failure in u_shapeArabic(unshape_grow_shrink)\n");
1375 /* helpers ------------------------------------------------------------------ */
1378 initCharFromDirProps() {
1379 static const UVersionInfo ucd401
={ 4, 0, 1, 0 };
1380 static UVersionInfo ucdVersion
={ 0, 0, 0, 0 };
1382 /* lazy initialization */
1383 if(ucdVersion
[0]>0) {
1387 u_getUnicodeVersion(ucdVersion
);
1388 if(memcmp(ucdVersion
, ucd401
, sizeof(UVersionInfo
))>=0) {
1389 /* Unicode 4.0.1 changes bidi classes for +-/ */
1390 charFromDirProp
[U_EUROPEAN_NUMBER_SEPARATOR
]=0x2b; /* change ES character from / to + */
1394 /* return a string with characters according to the desired directional properties */
1396 getStringFromDirProps(const uint8_t *dirProps
, int32_t length
) {
1397 static UChar s
[MAX_STRING_LENGTH
];
1400 initCharFromDirProps();
1402 /* this part would have to be modified for UTF-x */
1403 for(i
=0; i
<length
; ++i
) {
1404 s
[i
]=charFromDirProp
[dirProps
[i
]];
1411 printUnicode(const UChar
*s
, int32_t length
, const UBiDiLevel
*levels
) {
1415 for(i
=0; i
<length
; ++i
) {
1417 log_verbose("%4x.%u ", s
[i
], levels
[i
]);
1419 log_verbose("%4x ", s
[i
]);