1
/********************************************************************
3
* Copyright (c) 1997-2001, International Business Machines Corporation and
4
* others. All Rights Reserved.
5
********************************************************************/
6
/* file name: cbididat.c
8
* tab size: 8 (not used)
11
* created on: 1999sep22
12
* created by: Markus W. Scherer
18
static const char levelString[]="...............................................................";
20
static const char *dirPropNames[dirPropCount]={
21
"L", "R", "EN", "ES", "ET", "AN", "CS", "B", "S", "WS", "ON",
22
"LRE", "LRO", "AL", "RLE", "RLO", "PDF", "NSM", "BN"
26
charFromDirProp[dirPropCount]={
27
/* L R EN ES ET AN CS B S WS ON */
28
0x61, 0x5d0, 0x30, 0x2f, 0x25, 0x660, 0x2c, 0xa, 0x9, 0x20, 0x26,
29
/* LRE LRO AL RLE RLO PDF NSM BN */
30
0x202a, 0x202d, 0x627, 0x202b, 0x202e, 0x202c, 0x308, 0x200c
35
L, L, WS, L, WS, EN, L, B
38
static const UBiDiLevel
40
0, 0, 0, 0, 0, 0, 0, 0
45
0, 1, 2, 3, 4, 5, 6, 7
50
R, AL, WS, R, AL, WS, R
53
static const UBiDiLevel
65
L, L, WS, EN, CS, WS, EN, CS, EN, WS, L, L
68
static const UBiDiLevel
70
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
75
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
80
L, AL, AL, AL, L, AL, AL, L, WS, EN, CS, WS, EN, CS, EN, WS, L, L
83
static const UBiDiLevel
85
0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
90
0, 3, 2, 1, 4, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
95
AL, R, AL, WS, EN, CS, WS, EN, CS, EN, WS, R, R, WS, L, L
98
static const UBiDiLevel
100
1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2
105
15, 14, 13, 12, 11, 10, 9, 6, 7, 8, 5, 4, 3, 2, 0, 1
113
static const UBiDiLevel
129
static const UBiDiLevel
141
RLE, WS, R, R, R, WS, PDF, WS, B
144
static const UBiDiLevel
146
1, 1, 1, 1, 1, 1, 1, 1, 1
151
8, 7, 6, 5, 4, 3, 2, 1, 0
156
LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE,
157
LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE,
158
AN, RLO, NSM, LRE, PDF, RLE, ES, EN, ON
161
static const UBiDiLevel
163
62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 61, 61, 61, 61, 61, 61, 61
168
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 7, 6, 5, 4, 3, 2, 1, 0
173
LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE,
174
LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE, LRE,
175
LRE, BN, CS, RLO, S, PDF, EN, LRO, AN, ES
178
static const UBiDiLevel
180
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0, 62, 62, 62, 62, 60
185
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
190
S, WS, NSM, RLE, WS, L, L, L, WS, LRO, WS, R, R, R, WS, RLO, WS, L, L,
191
L, WS, LRE, WS, R, R, R, WS, PDF, WS, L, L, L, WS, PDF, WS,
192
AL, AL, AL, WS, PDF, WS, L, L, L, WS, PDF, WS, L, L, L, WS, PDF,
193
ON, PDF, BN, BN, ON, PDF
196
static const UBiDiLevel
198
0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
203
0, 1, 2, 44, 43, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 31, 30, 29, 28, 27, 26, 20, 21, 24, 23, 22, 25, 19, 18, 17, 16, 15, 14, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 3, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57
208
NSM, WS, L, L, L, L, L, L, L, WS, L, L, L, L, WS,
209
R, R, R, R, R, WS, L, L, L, L, L, L, L, WS, WS, AL,
210
AL, AL, AL, WS, EN, EN, ES, EN, EN, CS, S, EN, EN, CS, WS,
211
EN, EN, WS, AL, AL, AL, AL, AL, B, L, L, L, L, L, L,
212
L, L, WS, AN, AN, CS, AN, AN, WS
215
static const UBiDiLevel
217
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 0, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0
222
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 40, 39, 38, 37, 36, 34, 35, 33, 31, 32, 30, 41, 52, 53, 51, 50, 48, 49, 47, 46, 45, 44, 43, 42, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
225
static const UBiDiLevel
227
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 0, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0
232
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 40, 39, 38, 37, 36, 34, 35, 33, 31, 32, 30, 41, 52, 53, 51, 50, 48, 49, 47, 46, 45, 44, 43, 42, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
235
static const UBiDiLevel
237
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 3, 2, 4, 4, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2
242
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 40, 39, 38, 37, 36, 34, 35, 33, 31, 32, 30, 41, 52, 53, 51, 50, 48, 49, 47, 46, 45, 44, 43, 42, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
245
static const UBiDiLevel
247
5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 6, 5, 5, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5
252
69, 68, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 55, 54, 53, 52, 51, 50, 49, 42, 43, 44, 45, 46, 47, 48, 41, 40, 39, 38, 37, 36, 35, 33, 34, 32, 30, 31, 29, 28, 26, 27, 25, 24, 22, 23, 21, 20, 19, 18, 17, 16, 15, 7, 8, 9, 10, 11, 12, 13, 14, 6, 1, 2, 3, 4, 5, 0
255
static const UBiDiLevel
257
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 0, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0
262
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 40, 39, 38, 37, 36, 34, 35, 33, 31, 32, 30, 41, 52, 53, 51, 50, 48, 49, 47, 46, 45, 44, 43, 42, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
267
ON, L, RLO, CS, R, WS, AN, AN, PDF, LRE, R, L, LRO, WS, BN, ON, S, LRE, LRO, B
270
static const UBiDiLevel
272
0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 2, 4, 4, 4, 4, 0, 0, 0, 0
277
0, 1, 15, 14, 13, 12, 11, 10, 4, 3, 2, 5, 6, 7, 8, 9, 16, 17, 18, 19
280
static const UBiDiLevel
292
RLO, RLO, AL, AL, WS, EN, ES, ON, WS, S, S, PDF, LRO, WS, AL, ET, RLE, ON, EN, B
295
static const UBiDiLevel
310
static const UBiDiLevel
317
{testText1, ARRAY_LENGTH(testText1), UBIDI_DEFAULT_LTR, -1, -1,
319
testLevels1, testVisualMap1},
320
{testText2, ARRAY_LENGTH(testText2), UBIDI_DEFAULT_LTR, -1, -1,
322
testLevels2, testVisualMap2},
323
{testText3, ARRAY_LENGTH(testText3), UBIDI_DEFAULT_LTR, -1, -1,
325
testLevels3, testVisualMap3},
326
{testText4, ARRAY_LENGTH(testText4), UBIDI_DEFAULT_LTR, -1, -1,
328
testLevels4, testVisualMap4},
329
{testText5, ARRAY_LENGTH(testText5), UBIDI_DEFAULT_LTR, -1, -1,
331
testLevels5, testVisualMap5},
332
{testText6, ARRAY_LENGTH(testText6), UBIDI_DEFAULT_LTR, -1, -1,
334
testLevels6, testVisualMap6},
335
{NULL, 0, UBIDI_DEFAULT_LTR, -1, -1,
338
{testText8, ARRAY_LENGTH(testText8), UBIDI_DEFAULT_LTR, -1, -1,
340
testLevels8, testVisualMap8},
341
{testText9, ARRAY_LENGTH(testText9), UBIDI_DEFAULT_LTR, -1, -1,
343
testLevels9, testVisualMap9},
344
{testText10, ARRAY_LENGTH(testText10), UBIDI_DEFAULT_LTR, -1, -1,
346
testLevels10, testVisualMap10},
347
{testText11, ARRAY_LENGTH(testText11), UBIDI_DEFAULT_LTR, -1, -1,
349
testLevels11, testVisualMap11},
350
{testText12, ARRAY_LENGTH(testText12), UBIDI_DEFAULT_LTR, -1, -1,
352
testLevels12, testVisualMap12},
353
{testText12, ARRAY_LENGTH(testText12), UBIDI_DEFAULT_RTL, -1, -1,
355
testLevels13, testVisualMap13},
356
{testText12, ARRAY_LENGTH(testText12), 2, -1, -1,
358
testLevels14, testVisualMap14},
359
{testText12, ARRAY_LENGTH(testText12), 5, -1, -1,
361
testLevels15, testVisualMap15},
362
{testText12, ARRAY_LENGTH(testText12), UBIDI_DEFAULT_LTR, -1, -1,
364
testLevels16, testVisualMap16},
365
{testText13, ARRAY_LENGTH(testText13), UBIDI_DEFAULT_LTR, -1, -1,
367
testLevels17, testVisualMap17},
368
{testText13, ARRAY_LENGTH(testText13), UBIDI_DEFAULT_LTR, 0, 6,
370
testLevels18, testVisualMap18},
371
{testText14, ARRAY_LENGTH(testText14), UBIDI_DEFAULT_LTR, 13, 14,
373
testLevels19, testVisualMap19},
374
{testText15, ARRAY_LENGTH(testText15), UBIDI_DEFAULT_LTR, 2, 3,
376
testLevels20, testVisualMap19}
379
int bidiTestCount=ARRAY_LENGTH(tests);
381
void BiDiTest::TestBiDi() {
382
UErrorCode errorCode=U_ZERO_ERROR;
384
logln("*** bidi regression test ***\n");
386
BiDi bidi(MAX_STRING_LENGTH, 0, errorCode);
389
if(U_SUCCESS(errorCode)) {
390
TestBiDi(bidi, line);
393
errln("BiDi constructor with 3 arguments returned NULL, errorCode %s\n", u_errorName(errorCode));
396
logln("*** bidi regression test finished ***\n");
399
void BiDiTest::TestBiDi(BiDi& bidi, BiDi& line) {
402
UErrorCode errorCode;
404
UBiDiLevel paraLevel;
406
for(i=0; i<bidiTestCount; i++) {
407
errorCode=U_ZERO_ERROR;
408
s=getStringFromDirProps(tests[i].text, tests[i].length);
409
paraLevel=tests[i].paraLevel;
410
bidi.setPara(s, -1, paraLevel, NULL, errorCode);
411
if(U_SUCCESS(errorCode)) {
412
logln("setPara(tests[%d], paraLevel %d) ok, direction %d paraLevel=%d\n",
413
i, paraLevel, bidi.getDirection(), bidi.getParaLevel());
414
lineStart=tests[i].lineStart;
416
TestBiDi(bidi, i, tests+i, 0);
418
/*ubidi_setLine(pBiDi, lineStart, tests[i].lineLimit, pLine, &errorCode);*/
419
line.setLine(bidi,lineStart,tests[i].lineLimit,errorCode);
420
if(U_SUCCESS(errorCode)) {
421
logln("setLine(%d, %d) ok, direction %d paraLevel=%d\n",
422
lineStart, tests[i].lineLimit, line.getDirection(), line.getParaLevel());
423
TestBiDi(line, i, tests+i, lineStart);
425
errln("setLine(tests[%d], %d, %d) failed with errorCode %s\n",
426
i, lineStart, tests[i].lineLimit, u_errorName(errorCode));
430
errln("setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
431
i, paraLevel, u_errorName(errorCode));
435
void BiDiTest::TestBiDi(BiDi& bidi, 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=bidi.getLength(), logicalIndex, runCount;
440
UErrorCode errorCode=U_ZERO_ERROR;
441
UBiDiLevel level, level2;
443
TestReordering(bidi, testNumber);
445
for(i=0; i<len; ++i) {
446
logln("%3d %3d %.*s%-3s @%d\n",
447
i, bidi.getLevelAt(i), bidi.getLevelAt(i), levelString,
448
dirPropNames[dirProps[i]],
449
bidi.getVisualIndex(i, errorCode));
452
logln("\n-----levels:");
453
for(i=0; i<len; ++i) {
457
logln(" %d", bidi.getLevelAt(i));
460
logln("\n--reordered:");
461
for(i=0; i<len; ++i) {
465
logln(" %d", bidi.getVisualIndex( i, errorCode));
469
if(test->direction!=bidi.getDirection()) {
470
errln("getDirection(tests[%d]): wrong direction %d\n", testNumber, bidi.getDirection());
473
if(test->resultLevel!=bidi.getParaLevel()) {
474
errln("getParaLevel(tests[%d]): wrong paragraph level %d\n", testNumber, bidi.getParaLevel());
477
for(i=0; i<len; ++i) {
478
if(levels[i]!=bidi.getLevelAt(i)) {
479
errln("getLevelAt(tests[%d], %d): wrong level %d\n", testNumber, i, bidi.getLevelAt(i));
484
for(i=0; i<len; ++i) {
485
logicalIndex=bidi.getVisualIndex(i,errorCode);
486
if(U_FAILURE(errorCode)) {
487
errln("getVisualIndex(tests[%d], %d): error %s\n", testNumber, i, u_errorName(errorCode));
490
if(visualMap[i]!=logicalIndex) {
491
errln("getVisualIndex(tests[%d], %d): wrong index %d\n", testNumber, i, logicalIndex);
496
runCount=bidi.countRuns(errorCode);
497
if(U_FAILURE(errorCode)) {
498
errln("countRuns(tests[%d]): error %s\n", testNumber, u_errorName(errorCode));
502
for(logicalIndex=0; logicalIndex<len;) {
503
level=bidi.getLevelAt(logicalIndex);
504
bidi.getLogicalRun(logicalIndex, logicalIndex, level2);
506
errln("getLogicalRun(tests[%d], run ending at index %d): wrong level %d\n", testNumber, logicalIndex, level2);
509
errln("\ngetLogicalRun(tests[%d]): wrong number of runs compared to %d=getRunCount()\n", testNumber, bidi.countRuns(errorCode));
514
errln("\ngetLogicalRun(tests[%d]): wrong number of runs compared to %d=getRunCount()\n", testNumber, bidi.countRuns(errorCode));
521
void BiDiTest::TestReordering(BiDi& bidi, int testNumber) {
523
logicalMap1[200], logicalMap2[200], logicalMap3[200],
524
visualMap1[200], visualMap2[200], visualMap3[200], visualMap4[200];
525
UErrorCode errorCode=U_ZERO_ERROR;
526
UBiDiLevel levels[200];
527
int32_t i, length=bidi.getLength();
528
int32_t runCount, visualIndex, logicalStart, runLength;
535
/* get the logical and visual maps from the object */
536
bidi.getLogicalMap(logicalMap1, errorCode);
537
if(U_FAILURE(errorCode)) {
538
errln("getLogicalMap(tests[%d]): error %s\n", testNumber, u_errorName(errorCode));
542
bidi.getVisualMap(visualMap1, errorCode);
544
if(U_FAILURE(errorCode)) {
545
errln("getVisualMap(tests[%d]): error %s\n", testNumber, u_errorName(errorCode));
549
/* invert them both */
550
bidi.invertMap(logicalMap1, visualMap2, length);
551
bidi.invertMap(visualMap1, logicalMap2, length);
553
/* get them from the levels array, too */
554
uprv_memcpy(levels, bidi.getLevels(errorCode), length);
556
if(U_FAILURE(errorCode)) {
557
errln("getLevels(tests[%d]): error %s\n", testNumber, u_errorName(errorCode));
561
bidi.reorderLogical(levels, length, logicalMap3);
562
bidi.reorderVisual(levels, length, visualMap3);
564
/* get the visual map from the runs, too */
565
runCount=bidi.countRuns(errorCode);
566
if(U_FAILURE(errorCode)) {
567
errln("countRuns(tests[%d]): error %s\n", testNumber, u_errorName(errorCode));
571
logln("\n----%2d runs:", runCount);
572
for(i=0; i<runCount; ++i) {
573
odd=(UBool)(bidi.getVisualRun(i, logicalStart, runLength));
574
logln(" (%c @%d[%d])", odd ? 'R' : 'L', logicalStart, runLength);
579
for(i=0; i<runCount; ++i) {
580
if(UBIDI_LTR==bidi.getVisualRun( i, logicalStart, runLength)) {
582
visualMap4[visualIndex++]=logicalStart++;
583
} while(--runLength>0);
585
logicalStart+=runLength; /* logicalLimit */
587
visualMap4[visualIndex++]=--logicalStart;
588
} while(--runLength>0);
592
/* print all the maps */
593
logln("logical maps:\n");
594
for(i=0; i<length; ++i) {
595
logln("%4d", logicalMap1[i]);
598
for(i=0; i<length; ++i) {
599
logln("%4d", logicalMap2[i]);
602
for(i=0; i<length; ++i) {
603
logln("%4d", logicalMap3[i]);
606
logln("\nvisual maps:\n");
607
for(i=0; i<length; ++i) {
608
logln("%4d", visualMap1[i]);
611
for(i=0; i<length; ++i) {
612
logln("%4d", visualMap2[i]);
615
for(i=0; i<length; ++i) {
616
logln("%4d", visualMap3[i]);
619
for(i=0; i<length; ++i) {
620
logln("%4d", visualMap4[i]);
624
/* check that the indexes are the same between these and getLogical/VisualIndex() */
625
for(i=0; i<length; ++i) {
626
if(logicalMap1[i]!=logicalMap2[i]) {
627
logln("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap2[i] at i=%d\n", testNumber, i);
630
if(logicalMap1[i]!=logicalMap3[i]) {
631
logln("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap3[i] at i=%d\n", testNumber, i);
635
if(visualMap1[i]!=visualMap2[i]) {
636
logln("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap2[i] at i=%d\n", testNumber, i);
639
if(visualMap1[i]!=visualMap3[i]) {
640
logln("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap3[i] at i=%d\n", testNumber, i);
643
if(visualMap1[i]!=visualMap4[i]) {
644
logln("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap4[i] at i=%d\n", testNumber, i);
648
if(logicalMap1[i]!=bidi.getVisualIndex( i, errorCode)) {
649
logln("bidi reordering error in tests[%d]: logicalMap1[i]!=getVisualIndex(i) at i=%d\n", testNumber, i);
652
if(U_FAILURE(errorCode)) {
653
logln("getVisualIndex(tests[%d], %d): error %s\n", testNumber, i, u_errorName(errorCode));
656
if(visualMap1[i]!=bidi.getLogicalIndex(i, errorCode)) {
657
logln("bidi reordering error in tests[%d]: visualMap1[i]!=getLogicalIndex(i) at i=%d\n", testNumber, i);
660
if(U_FAILURE(errorCode)) {
661
logln("getLogicalIndex(tests[%d], %d): error %s\n", testNumber, i, u_errorName(errorCode));
667
#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
668
/* inverse BiDi ------------------------------------------------------------- */
671
string0[]={ 0x6c, 0x61, 0x28, 0x74, 0x69, 0x6e, 0x20, 0x5d0, 0x5d1, 0x29, 0x5d2, 0x5d3 },
672
string1[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x31, 0x32, 0x33 },
673
string2[]={ 0x6c, 0x61, 0x74, 0x20, 0x5d0, 0x28, 0x5d1, 0x5d2, 0x20, 0x31, 0x29, 0x32, 0x33 },
674
string3[]={ 0x31, 0x32, 0x33, 0x20, 0x5d0, 0x5d1, 0x5d2, 0x20, 0x34, 0x35, 0x36 },
675
string4[]={ 0x61, 0x62, 0x20, 0x61, 0x62, 0x20, 0x661, 0x662 };
677
#define STRING_TEST_CASE(s) { (s), LENGTHOF(s) }
679
static const struct {
683
STRING_TEST_CASE(string0),
684
STRING_TEST_CASE(string1),
685
STRING_TEST_CASE(string2),
686
STRING_TEST_CASE(string3)
689
static int countRoundtrips=0, countNonRoundtrips=0;
691
void BiDiTest::TestInverseBiDi() {
693
UErrorCode errorCode;
696
logln("inverse BiDi: testInverseBiDi(L) with %u test cases ---\n", LENGTHOF(testCases));
697
for(i=0; i<LENGTHOF(testCases); ++i) {
698
errorCode=U_ZERO_ERROR;
699
TestInverseBiDi(bidi, testCases[i].s,testCases[i].length, 0, errorCode);
702
logln("inverse BiDi: testInverseBiDi(R) with %u test cases ---\n", LENGTHOF(testCases));
703
for(i=0; i<LENGTHOF(testCases); ++i) {
704
errorCode=U_ZERO_ERROR;
705
TestInverseBiDi(bidi, testCases[i].s,testCases[i].length, 1, errorCode);
708
TestInverseBiDi(bidi, 0);
709
TestInverseBiDi(bidi, 1);
712
logln("inverse BiDi: rountrips: %5u\nnon-roundtrips: %5u\n", countRoundtrips, countNonRoundtrips);
717
#define COUNT_REPEAT_SEGMENTS 6
719
static const UChar repeatSegments[COUNT_REPEAT_SEGMENTS][2]={
720
{ 0x61, 0x62 }, /* L */
721
{ 0x5d0, 0x5d1 }, /* R */
722
{ 0x627, 0x628 }, /* AL */
723
{ 0x31, 0x32 }, /* EN */
724
{ 0x661, 0x662 }, /* AN */
725
{ 0x20, 0x20 } /* WS (N) */
728
void BiDiTest::TestInverseBiDi(BiDi& bidi, UBiDiLevel direction) {
729
static UChar text[8]={ 0, 0, 0x20, 0, 0, 0x20, 0, 0 };
731
UErrorCode errorCode;
733
logln("inverse BiDi: testManyInverseBiDi(%c) - test permutations of text snippets ---\n", direction==0 ? 'L' : 'R');
734
for(i=0; i<COUNT_REPEAT_SEGMENTS; ++i) {
735
text[0]=repeatSegments[i][0];
736
text[1]=repeatSegments[i][1];
737
for(j=0; j<COUNT_REPEAT_SEGMENTS; ++j) {
738
text[3]=repeatSegments[j][0];
739
text[4]=repeatSegments[j][1];
740
for(k=0; k<COUNT_REPEAT_SEGMENTS; ++k) {
741
text[6]=repeatSegments[k][0];
742
text[7]=repeatSegments[k][1];
744
errorCode=U_ZERO_ERROR;
745
logln("inverse BiDi: testManyInverseBiDi()[%u %u %u]\n", i, j, k);
746
TestInverseBiDi(bidi,text,8,direction, errorCode);
752
void BiDiTest::TestInverseBiDi(BiDi& bidi, const UChar *src, int32_t srcLength, UBiDiLevel direction, UErrorCode& errorCode) {
753
static UChar visualLTR[200], logicalDest[200], visualDest[200];
754
int32_t ltrLength, logicalLength, visualLength;
757
logln("inverse BiDi: testInverseBiDi(L)\n");
759
/* convert visual to logical */
760
bidi.setInverse(TRUE);
761
bidi.setPara(src, srcLength, 0, NULL, errorCode);
762
logicalLength=bidi.writeReordered(logicalDest, LENGTHOF(logicalDest),
763
UBIDI_DO_MIRRORING|UBIDI_INSERT_LRM_FOR_NUMERIC, errorCode);
765
printUnicode(src, srcLength, bidi.getLevels(errorCode));
768
/* convert back to visual LTR */
769
bidi.setInverse(FALSE);
770
bidi.setPara(logicalDest, logicalLength, 0, NULL, errorCode);
771
visualLength=bidi.writeReordered(visualDest, LENGTHOF(visualDest),
772
UBIDI_DO_MIRRORING|UBIDI_REMOVE_BIDI_CONTROLS, errorCode);
774
logln("inverse BiDi: testInverseBiDi(R)\n");
776
/* reverse visual from RTL to LTR */
777
ltrLength=bidi.writeReverse(src, srcLength, visualLTR, LENGTHOF(visualLTR), 0, errorCode);
779
printUnicode(src, srcLength, NULL);
782
/* convert visual RTL to logical */
783
bidi.setInverse(TRUE);
784
bidi.setPara(visualLTR, ltrLength, 0, NULL, errorCode);
785
logicalLength=bidi.writeReordered(logicalDest, LENGTHOF(logicalDest),
786
UBIDI_DO_MIRRORING|UBIDI_INSERT_LRM_FOR_NUMERIC, errorCode);
788
printUnicode(visualLTR, ltrLength, bidi.getLevels(errorCode));
791
/* convert back to visual RTL */
792
bidi.setInverse(FALSE);
793
bidi.setPara(logicalDest, logicalLength, 0, NULL, errorCode);
794
visualLength=bidi.writeReordered(visualDest, LENGTHOF(visualDest),
795
UBIDI_DO_MIRRORING|UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_OUTPUT_REVERSE, errorCode);
798
printUnicode(logicalDest, logicalLength, bidi.getLevels(errorCode));
801
printUnicode(visualDest, visualLength, NULL);
804
/* check and print results */
805
if(U_FAILURE(errorCode)) {
806
errln("inverse BiDi: *** error %s\n"
807
" turn on verbose mode to see details\n", u_errorName(errorCode));
808
} else if(srcLength==visualLength && uprv_memcmp(src, visualDest, srcLength*U_SIZEOF_UCHAR)==0) {
810
logln(" + roundtripped\n");
812
++countNonRoundtrips;
813
logln(" * did not roundtrip\n");
814
errln("inverse BiDi: transformation visual->logical->visual did not roundtrip the text;\n"
815
" turn on verbose mode to see details\n");
819
void BiDiTest::TestWriteReverse() {
820
/* U+064e and U+0650 are combining marks (Mn) */
821
static const UChar forward[]={
822
0x200f, 0x627, 0x64e, 0x650, 0x20, 0x28, 0x31, 0x29
823
}, reverseKeepCombining[]={
824
0x29, 0x31, 0x28, 0x20, 0x627, 0x64e, 0x650, 0x200f
825
}, reverseRemoveControlsKeepCombiningDoMirror[]={
826
0x28, 0x31, 0x29, 0x20, 0x627, 0x64e, 0x650
828
static UChar reverse[10];
829
UErrorCode errorCode;
832
/* test writeReverse() with "interesting" options */
833
errorCode=U_ZERO_ERROR;
834
length=BiDi::writeReverse(forward, LENGTHOF(forward),
835
reverse, LENGTHOF(reverse),
836
UBIDI_KEEP_BASE_COMBINING,
838
if(U_FAILURE(errorCode) || length!=LENGTHOF(reverseKeepCombining) || uprv_memcmp(reverse, reverseKeepCombining, length*U_SIZEOF_UCHAR)!=0) {
839
errln("failure in writeReverse(UBIDI_KEEP_BASE_COMBINING): length=%d (should be %d), error code %s\n",
840
length, LENGTHOF(reverseKeepCombining), u_errorName(errorCode));
843
uprv_memset(reverse, 0xa5, LENGTHOF(reverse)*U_SIZEOF_UCHAR);
844
errorCode=U_ZERO_ERROR;
845
length=BiDi::writeReverse(forward, LENGTHOF(forward),
846
reverse, LENGTHOF(reverse),
847
UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING,
849
if(U_FAILURE(errorCode) || length!=LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror) || uprv_memcmp(reverse, reverseRemoveControlsKeepCombiningDoMirror, length*U_SIZEOF_UCHAR)!=0) {
850
errln("failure in writeReverse(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING):\n"
851
" length=%d (should be %d), error code %s\n",
852
length, LENGTHOF(reverseRemoveControlsKeepCombiningDoMirror), u_errorName(errorCode));
856
/* helpers ------------------------------------------------------------------ */
858
/* return a string with characters according to the desired directional properties */
859
UChar * BiDiTest::getStringFromDirProps(const uint8_t *dirProps, int32_t length) {
860
static UChar s[MAX_STRING_LENGTH];
863
/* this part would have to be modified for UTF-x */
864
for(i=0; i<length; ++i) {
865
s[i]=charFromDirProp[dirProps[i]];
871
void BiDiTest::printUnicode(const UChar *s, int32_t length, const UBiDiLevel *levels) {
875
for(i=0; i<length; ++i) {
877
logln("%4x.%u ", s[i], levels[i]);
885
void BiDiTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) {
887
logln("TestSuite Character and String Test: ");
897
name="TestInverseBiDi";
903
name="TestWriteReverse";