home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / test / cintltst / cbiditst.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  12.4 KB  |  370 lines

  1. /*  
  2. *******************************************************************************
  3. *                                                                             *
  4. * COPYRIGHT:                                                                  *
  5. *   (C) Copyright International Business Machines Corporation, 1999           *
  6. *   Licensed Material - Program-Property of IBM - All Rights Reserved.        *
  7. *   US Government Users Restricted Rights - Use, duplication, or disclosure   *
  8. *   restricted by GSA ADP Schedule Contract with IBM Corp.                    *
  9. *                                                                             *
  10. *******************************************************************************
  11. *   file name:  cbiditst.cpp
  12. *   encoding:   US-ASCII
  13. *   tab size:   8 (not used)
  14. *   indentation:4
  15. *
  16. *   created on: 1999sep27
  17. *   created by: Markus W. Scherer
  18. */
  19.  
  20. #include "cintltst.h"
  21. #include "utypes.h"
  22. #include "cmemory.h"
  23. #include "uchar.h"
  24. #include "ubidi.h"
  25. #include "cbiditst.h"
  26.  
  27. /* prototypes ---------------------------------------------------------------*/
  28.  
  29. extern void
  30. doBiDiTest();
  31.  
  32. static void
  33. doTests(UBiDi *pBiDi, UBiDi *pLine);
  34.  
  35. static void
  36. doTest(UBiDi *pBiDi, int testNumber, BiDiTestData *test, UTextOffset lineStart);
  37.  
  38. static void
  39. testReordering(UBiDi *pBiDi, int testNumber);
  40.  
  41. static char *levelString;
  42.  
  43. static UChar *
  44. getStringFromDirProps(const uint8_t *dirProps, UTextOffset length);
  45.  
  46. /* regression tests ---------------------------------------------------------*/
  47.  
  48. extern void
  49. addComplexTest(TestNode** root) {
  50.     addTest(root, doBiDiTest, "complex/bidi/regression");
  51. }
  52.  
  53. extern void
  54. doBiDiTest() {
  55.     UBiDi *pBiDi, *pLine=NULL;
  56.     UErrorCode errorCode=U_ZERO_ERROR;
  57.  
  58.     log_verbose("*** bidi regression test ***\n");
  59.  
  60.     pBiDi=ubidi_openSized(MAX_STRING_LENGTH, 0, &errorCode);
  61.     if(pBiDi!=NULL) {
  62.         pLine=ubidi_open();
  63.         if(pLine!=NULL) {
  64.             doTests(pBiDi, pLine);
  65.         } else {
  66.             log_err("ubidi_open() returned NULL, out of memory\n");
  67.         }
  68.     } else {
  69.         log_err("ubidi_openSized() returned NULL, errorCode %s\n", myErrorName(errorCode));
  70.     }
  71.  
  72.     if(pLine!=NULL) {
  73.         ubidi_close(pLine);
  74.     }
  75.     if(pBiDi!=NULL) {
  76.         ubidi_close(pBiDi);
  77.     }
  78.  
  79.     log_verbose("*** bidi regression test finished ***\n");
  80. }
  81.  
  82. static void
  83. doTests(UBiDi *pBiDi, UBiDi *pLine) {
  84.     int i;
  85.     UChar *s;
  86.     UErrorCode errorCode;
  87.     UTextOffset lineStart;
  88.     UBiDiLevel paraLevel;
  89.  
  90.     for(i=0; i<bidiTestCount; ++i) {
  91.         errorCode=U_ZERO_ERROR;
  92.         s=getStringFromDirProps(tests[i].text, tests[i].length);
  93.         paraLevel=tests[i].paraLevel;
  94.         ubidi_setPara(pBiDi, s, -1, paraLevel, NULL, &errorCode);
  95.         if(U_SUCCESS(errorCode)) {
  96.             log_verbose("ubidi_setPara(tests[%d], paraLevel %d) ok, direction %d paraLevel=%d\n",
  97.                     i, paraLevel, ubidi_getDirection(pBiDi), ubidi_getParaLevel(pBiDi));
  98.             lineStart=tests[i].lineStart;
  99.             if(lineStart==-1) {
  100.                 doTest(pBiDi, i, tests+i, 0);
  101.             } else {
  102.                 ubidi_setLine(pBiDi, lineStart, tests[i].lineLimit, pLine, &errorCode);
  103.                 if(U_SUCCESS(errorCode)) {
  104.                     log_verbose("ubidi_setLine(%d, %d) ok, direction %d paraLevel=%d\n",
  105.                             lineStart, tests[i].lineLimit, ubidi_getDirection(pLine), ubidi_getParaLevel(pLine));
  106.                     doTest(pLine, i, tests+i, lineStart);
  107.                 } else {
  108.                     log_err("ubidi_setLine(tests[%d], %d, %d) failed with errorCode %s\n",
  109.                             i, lineStart, tests[i].lineLimit, myErrorName(errorCode));
  110.                 }
  111.             }
  112.         } else {
  113.             log_err("ubidi_setPara(tests[%d], paraLevel %d) failed with errorCode %s\n",
  114.                     i, paraLevel, myErrorName(errorCode));
  115.         }
  116.     }
  117. }
  118.  
  119. static void
  120. doTest(UBiDi *pBiDi, int testNumber, BiDiTestData *test, UTextOffset lineStart) {
  121.     const uint8_t *dirProps=test->text+lineStart;
  122.     const UBiDiLevel *levels=test->levels;
  123.     const uint8_t *visualMap=test->visualMap;
  124.     UTextOffset i, len=ubidi_getLength(pBiDi), logicalIndex, runCount;
  125.     UErrorCode errorCode=U_ZERO_ERROR;
  126.     UBiDiLevel level, level2;
  127.  
  128.     testReordering(pBiDi, testNumber);
  129.  
  130.     for(i=0; i<len; ++i) {
  131.         log_verbose("%3d %3d %.*s%-3s @%d\n",
  132.                 i, ubidi_getLevelAt(pBiDi, i), ubidi_getLevelAt(pBiDi, i), levelString,
  133.                 dirPropNames[dirProps[i]],
  134.                 ubidi_getVisualIndex(pBiDi, i, &errorCode));
  135.     }
  136.  
  137.     log_verbose("\n-----levels:");
  138.     for(i=0; i<len; ++i) {
  139.         if(i>0) {
  140.             log_verbose(",");
  141.         }
  142.         log_verbose(" %d", ubidi_getLevelAt(pBiDi, i));
  143.     }
  144.  
  145.     log_verbose("\n--reordered:");
  146.     for(i=0; i<len; ++i) {
  147.         if(i>0) {
  148.             log_verbose(",");
  149.         }
  150.         log_verbose(" %d", ubidi_getVisualIndex(pBiDi, i, &errorCode));
  151.     }
  152.     log_verbose("\n");
  153.  
  154.     if(test->direction!=ubidi_getDirection(pBiDi)) {
  155.         log_err("ubidi_getDirection(tests[%d]): wrong direction %d\n", testNumber, ubidi_getDirection(pBiDi));
  156.     }
  157.  
  158.     if(test->resultLevel!=ubidi_getParaLevel(pBiDi)) {
  159.         log_err("ubidi_getParaLevel(tests[%d]): wrong paragraph level %d\n", testNumber, ubidi_getParaLevel(pBiDi));
  160.     }
  161.  
  162.     for(i=0; i<len; ++i) {
  163.         if(levels[i]!=ubidi_getLevelAt(pBiDi, i)) {
  164.             log_err("ubidi_getLevelAt(tests[%d], %d): wrong level %d\n", testNumber, i, ubidi_getLevelAt(pBiDi, i));
  165.             return;
  166.         }
  167.     }
  168.  
  169.     for(i=0; i<len; ++i) {
  170.         logicalIndex=ubidi_getVisualIndex(pBiDi, i, &errorCode);
  171.         if(U_FAILURE(errorCode)) {
  172.             log_err("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber, i, myErrorName(errorCode));
  173.             return;
  174.         }
  175.         if(visualMap[i]!=logicalIndex) {
  176.             log_err("ubidi_getVisualIndex(tests[%d], %d): wrong index %d\n", testNumber, i, logicalIndex);
  177.             return;
  178.         }
  179.     }
  180.  
  181.     runCount=ubidi_countRuns(pBiDi, &errorCode);
  182.     if(U_FAILURE(errorCode)) {
  183.         log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber, myErrorName(errorCode));
  184.         return;
  185.     }
  186.  
  187.     for(logicalIndex=0; logicalIndex<len;) {
  188.         level=ubidi_getLevelAt(pBiDi, logicalIndex);
  189.         ubidi_getLogicalRun(pBiDi, logicalIndex, &logicalIndex, &level2);
  190.         if(level!=level2) {
  191.             log_err("ubidi_getLogicalRun(tests[%d], run ending at index %d): wrong level %d\n", testNumber, logicalIndex, level2);
  192.         }
  193.         if(--runCount<0) {
  194.             log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs compared to %d=ubidi_getRunCount()\n", testNumber, ubidi_countRuns(pBiDi, &errorCode));
  195.             return;
  196.         }
  197.     }
  198.     if(runCount!=0) {
  199.         log_err("\nubidi_getLogicalRun(tests[%d]): wrong number of runs compared to %d=ubidi_getRunCount()\n", testNumber, ubidi_countRuns(pBiDi, &errorCode));
  200.         return;
  201.     }
  202.  
  203.     log_verbose("\n\n");
  204. }
  205.  
  206. static void
  207. testReordering(UBiDi *pBiDi, int testNumber) {
  208.     UTextOffset
  209.         logicalMap1[200], logicalMap2[200], logicalMap3[200],
  210.         visualMap1[200], visualMap2[200], visualMap3[200], visualMap4[200];
  211.     UErrorCode errorCode=U_ZERO_ERROR;
  212.     UBiDiLevel levels[200];
  213.     UTextOffset i, length=ubidi_getLength(pBiDi);
  214.     UTextOffset runCount, visualIndex, logicalStart, runLength;
  215.     int result=0;
  216.     bool_t odd;
  217.  
  218.     if(length<=0) {
  219.         return;
  220.     }
  221.  
  222.     /* get the logical and visual maps from the object */
  223.     ubidi_getLogicalMap(pBiDi, logicalMap1, &errorCode);
  224.     if(U_FAILURE(errorCode)) {
  225.         log_err("ubidi_getLogicalMap(tests[%d]): error %s\n", testNumber, myErrorName(errorCode));
  226.         return;
  227.     }
  228.  
  229.     ubidi_getVisualMap(pBiDi, visualMap1, &errorCode);
  230.  
  231.     if(U_FAILURE(errorCode)) {
  232.         log_err("ubidi_getVisualMap(tests[%d]): error %s\n", testNumber, myErrorName(errorCode));
  233.         return;
  234.     }
  235.  
  236.     /* invert them both */
  237.     ubidi_invertMap(logicalMap1, visualMap2, length);
  238.     ubidi_invertMap(visualMap1, logicalMap2, length);
  239.  
  240.     /* get them from the levels array, too */
  241.     icu_memcpy(levels, ubidi_getLevels(pBiDi, &errorCode), length);
  242.     if(U_FAILURE(errorCode)) {
  243.         log_err("ubidi_getLevels(tests[%d]): error %s\n", testNumber, myErrorName(errorCode));
  244.         return;
  245.     }
  246.  
  247.     ubidi_reorderLogical(levels, length, logicalMap3);
  248.     ubidi_reorderVisual(levels, length, visualMap3);
  249.  
  250.     /* get the visual map from the runs, too */
  251.     runCount=ubidi_countRuns(pBiDi, &errorCode);
  252.     if(U_FAILURE(errorCode)) {
  253.         log_err("ubidi_countRuns(tests[%d]): error %s\n", testNumber, myErrorName(errorCode));
  254.         return;
  255.     }
  256.  
  257.     log_verbose("\n----%2d runs:", runCount);
  258.     for(i=0; i<runCount; ++i) {
  259.         odd=ubidi_getVisualRun(pBiDi, i, &logicalStart, &runLength);
  260.         log_verbose(" (%c @%d[%d])", odd ? 'R' : 'L', logicalStart, runLength);
  261.     }
  262.     log_verbose("\n");
  263.  
  264.     visualIndex=0;
  265.     for(i=0; i<runCount; ++i) {
  266.         if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, i, &logicalStart, &runLength)) {
  267.             do { /* LTR */
  268.                 visualMap4[visualIndex++]=logicalStart++;
  269.             } while(--runLength>0);
  270.         } else {
  271.             logicalStart+=runLength;   /* logicalLimit */
  272.             do { /* RTL */
  273.                 visualMap4[visualIndex++]=--logicalStart;
  274.             } while(--runLength>0);
  275.         }
  276.     }
  277.  
  278.     /* print all the maps */
  279.     log_verbose("logical maps:\n");
  280.     for(i=0; i<length; ++i) {
  281.         log_verbose("%4d", logicalMap1[i]);
  282.     }
  283.     log_verbose("\n");
  284.     for(i=0; i<length; ++i) {
  285.         log_verbose("%4d", logicalMap2[i]);
  286.     }
  287.     log_verbose("\n");
  288.     for(i=0; i<length; ++i) {
  289.         log_verbose("%4d", logicalMap3[i]);
  290.     }
  291.  
  292.     log_verbose("\nvisual maps:\n");
  293.     for(i=0; i<length; ++i) {
  294.         log_verbose("%4d", visualMap1[i]);
  295.     }
  296.     log_verbose("\n");
  297.     for(i=0; i<length; ++i) {
  298.         log_verbose("%4d", visualMap2[i]);
  299.     }
  300.     log_verbose("\n");
  301.     for(i=0; i<length; ++i) {
  302.         log_verbose("%4d", visualMap3[i]);
  303.     }
  304.     log_verbose("\n");
  305.     for(i=0; i<length; ++i) {
  306.         log_verbose("%4d", visualMap4[i]);
  307.     }
  308.     log_verbose("\n");
  309.  
  310.     /* check that the indexes are the same between these and ubidi_getLogical/VisualIndex() */
  311.     for(i=0; i<length; ++i) {
  312.         if(logicalMap1[i]!=logicalMap2[i]) {
  313.             log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap2[i] at i=%d\n", testNumber, i);
  314.             break;
  315.         }
  316.         if(logicalMap1[i]!=logicalMap3[i]) {
  317.             log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=logicalMap3[i] at i=%d\n", testNumber, i);
  318.             break;
  319.         }
  320.  
  321.         if(visualMap1[i]!=visualMap2[i]) {
  322.             log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap2[i] at i=%d\n", testNumber, i);
  323.             break;
  324.         }
  325.         if(visualMap1[i]!=visualMap3[i]) {
  326.             log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap3[i] at i=%d\n", testNumber, i);
  327.             break;
  328.         }
  329.         if(visualMap1[i]!=visualMap4[i]) {
  330.             log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=visualMap4[i] at i=%d\n", testNumber, i);
  331.             break;
  332.         }
  333.  
  334.         if(logicalMap1[i]!=ubidi_getVisualIndex(pBiDi, i, &errorCode)) {
  335.             log_verbose("bidi reordering error in tests[%d]: logicalMap1[i]!=ubidi_getVisualIndex(i) at i=%d\n", testNumber, i);
  336.             break;
  337.         }
  338.         if(U_FAILURE(errorCode)) {
  339.             log_verbose("ubidi_getVisualIndex(tests[%d], %d): error %s\n", testNumber, i, myErrorName(errorCode));
  340.             break;
  341.         }
  342.         if(visualMap1[i]!=ubidi_getLogicalIndex(pBiDi, i, &errorCode)) {
  343.             log_verbose("bidi reordering error in tests[%d]: visualMap1[i]!=ubidi_getLogicalIndex(i) at i=%d\n", testNumber, i);
  344.             break;
  345.         }
  346.         if(U_FAILURE(errorCode)) {
  347.             log_verbose("ubidi_getLogicalIndex(tests[%d], %d): error %s\n", testNumber, i, myErrorName(errorCode));
  348.             break;
  349.         }
  350.     }
  351. }
  352.  
  353. /* helpers ------------------------------------------------------------------*/
  354.  
  355. static char *levelString="...............................................................";
  356.  
  357. /* return a string with characters according to the desired directional properties */
  358. static UChar *
  359. getStringFromDirProps(const uint8_t *dirProps, UTextOffset length) {
  360.     static UChar s[MAX_STRING_LENGTH];
  361.     UTextOffset i;
  362.  
  363.     /* this part would have to be modified for UTF-x */
  364.     for(i=0; i<length; ++i) {
  365.         s[i]=charFromDirProp[dirProps[i]];
  366.     }
  367.     s[i]=0;
  368.     return s;
  369. }
  370.