]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/bidiconf.cpp
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / bidiconf.cpp
index c1ee4286c94245f33f8284f9c1e3815f7f311f15..1c22253d48ee8b283b3ffd6cbcfb795debce37d0 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2009-2013, International Business Machines
+*   Copyright (C) 2009-2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -39,8 +39,6 @@ public:
     void TestBidiTest();
     void TestBidiCharacterTest();
 private:
-    char *getUnidataPath(char path[]);
-
     UBool parseLevels(const char *&start);
     UBool parseOrdering(const char *start);
     UBool parseInputStringFromBiDiClasses(const char *&start);
@@ -77,42 +75,6 @@ void BiDiConformanceTest::runIndexedTest(int32_t index, UBool exec, const char *
     TESTCASE_AUTO_END;
 }
 
-// TODO: Move to a common place (IntlTest?) to avoid duplication with UnicodeTest (ucdtest.cpp).
-char *BiDiConformanceTest::getUnidataPath(char path[]) {
-    IcuTestErrorCode errorCode(*this, "getUnidataPath");
-    const int kUnicodeDataTxtLength=15;  // strlen("UnicodeData.txt")
-
-    // Look inside ICU_DATA first.
-    strcpy(path, pathToDataDirectory());
-    strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
-    FILE *f=fopen(path, "r");
-    if(f!=NULL) {
-        fclose(f);
-        *(strchr(path, 0)-kUnicodeDataTxtLength)=0;  // Remove the basename.
-        return path;
-    }
-
-    // As a fallback, try to guess where the source data was located
-    // at the time ICU was built, and look there.
-#   ifdef U_TOPSRCDIR
-        strcpy(path, U_TOPSRCDIR  U_FILE_SEP_STRING "data");
-#   else
-        strcpy(path, loadTestData(errorCode));
-        strcat(path, U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
-                     U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
-                     U_FILE_SEP_STRING "data");
-#   endif
-    strcat(path, U_FILE_SEP_STRING);
-    strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
-    f=fopen(path, "r");
-    if(f!=NULL) {
-        fclose(f);
-        *(strchr(path, 0)-kUnicodeDataTxtLength)=0;  // Remove the basename.
-        return path;
-    }
-    return NULL;
-}
-
 U_DEFINE_LOCAL_OPEN_POINTER(LocalStdioFilePointer, FILE, fclose);
 
 UBool BiDiConformanceTest::parseLevels(const char *&start) {
@@ -318,6 +280,8 @@ void BiDiConformanceTest::TestBidiTest() {
     levelsCount=0;
     orderingCount=0;
     errorCount=0;
+    // paraLevelName must be initialized in case the first non-comment line is in error
+    paraLevelName="N/A";
     while(errorCount<10 && fgets(line, (int)sizeof(line), bidiTestFile.getAlias())!=NULL) {
         ++lineNumber;
         // Remove trailing comments and whitespace.
@@ -460,6 +424,8 @@ L L R R R B R R L L L B ON ON ; 3 ; 0 ; 0 0 1 1 1 0 1 1 2 2 2 1 1 1
 *
 *******************************************************************************
 */
+enum { kMaxUtxt = 32, kMaxUctl = 16 };
+
 void BiDiConformanceTest::TestBidiCharacterTest() {
     IcuTestErrorCode errorCode(*this, "TestBidiCharacterTest");
     const char *sourceTestDataPath=getSourceTestData(errorCode);
@@ -593,6 +559,81 @@ void BiDiConformanceTest::TestBidiCharacterTest() {
         if(orderingCount>=0 && !checkOrdering(ubidi.getAlias())) {
             continue;
         }
+        
+        // tests for ubidi_setParaWithControls
+        // skip 2 tests known not to work (out of 91678 cases, though
+        // only 86 of those tests use controls so 2.3% of those failing),
+        // still investigating these
+        if (lineNumber==210 || lineNumber==211) {
+            continue;
+        }
+        
+        const UChar* ubufPtr = inputString.getBuffer();
+        int32_t ubufIdx;
+        UChar utxt[kMaxUtxt];
+        UBiDiLevel ulev[kMaxUtxt];
+        int32_t offsets[kMaxUctl];
+        UChar* uctlPtrs[kMaxUctl];
+        UChar uctl[kMaxUctl][5];
+        UChar *uctlPtr;
+        int32_t utxtLen = 0, offsetsLen = 0, ctlLen = 0;
+        UBool fail = FALSE;
+        for (ubufIdx = 0; ubufIdx < inputString.length(); ubufIdx++) {
+            UChar uc = ubufPtr[ubufIdx];
+            if ( (uc >=0x202A && uc<=0x202E) || (uc >=0x2066 && uc<=0x2069) ) {
+                // have a bidi control
+                if (ctlLen >= 4) {
+                    fail = TRUE; break;
+                }
+                if (ctlLen == 0) {
+                    // starting a new control sequence
+                    if (offsetsLen >= kMaxUctl) {
+                        fail = TRUE; break;
+                    }
+                    offsets[offsetsLen] = utxtLen;
+                    uctlPtr = &uctl[offsetsLen][0];
+                    uctlPtrs[offsetsLen] = uctlPtr;
+                    offsetsLen++;
+                }
+                uctlPtr[ctlLen++] = uc;
+                uctlPtr[ctlLen] = 0;
+            } else {
+                if (utxtLen >= kMaxUtxt) {
+                    fail = TRUE; break;
+                }
+                ctlLen = 0;
+                utxt[utxtLen] = uc;
+                levels[utxtLen] = levels[ubufIdx]; // will always have ubufIdx >= utxtLen so this is OK
+                utxtLen++;
+            }
+        }
+        levelsCount = utxtLen;
+        if (fail) {
+            logln("Skipping BidiCharacterTest unsuitable for ubidi_setParaWithControls: %d: %s", (int)lineNumber, line);
+            continue; // can't use this test
+        }
+        if (offsetsLen > 0 && offsets[offsetsLen-1] >= utxtLen) {
+            --offsetsLen;
+            ubidi_setContext(ubidi.getAlias(), NULL, 0, uctlPtrs[offsetsLen], -1, errorCode);
+        } else {
+            ubidi_setContext(ubidi.getAlias(), NULL, 0, NULL, 0, errorCode);
+        }
+        ubidi_setParaWithControls(ubidi.getAlias(), utxt, utxtLen, paraLevel,
+                                  offsets, offsetsLen, NULL, uctlPtrs, errorCode);
+        actualLevels=ubidi_getLevels(ubidi.getAlias(), errorCode);
+        if(errorCode.logIfFailureAndReset("ubidi_setContext()/ubidi_setParaWithControls()/ubidi_getLevels()")) {
+            errln("Input line %d: %s", (int)lineNumber, line);
+            continue;
+        }
+        if((actualLevel=ubidi_getParaLevel(ubidi.getAlias()))!=resolvedParaLevel) {
+            printErrorLine();
+            errln("\nError on line %d: Wrong resolved paragraph level from ubidi_setParaWithControls; expected %d actual %d",
+                   (int)lineNumber, resolvedParaLevel, actualLevel);
+            continue;
+        }
+        if(!checkLevels(actualLevels, ubidi_getProcessedLength(ubidi.getAlias()))) {
+            continue;
+        }
     }
 }