X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/48b980fed3435926e0b3a8d72ecb58be703a1c7a..729e4ab9bc6618bc3d8a898e575df7f4019e29ca:/icuSources/test/intltest/bidiconf.cpp diff --git a/icuSources/test/intltest/bidiconf.cpp b/icuSources/test/intltest/bidiconf.cpp new file mode 100644 index 00000000..c30a76b2 --- /dev/null +++ b/icuSources/test/intltest/bidiconf.cpp @@ -0,0 +1,488 @@ +/* +******************************************************************************* +* +* Copyright (C) 2009-2010, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: bidiconf.cpp +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2009oct16 +* created by: Markus W. Scherer +* +* BiDi conformance test, using the Unicode BidiTest.txt file. +*/ + +#include +#include +#include +#include "unicode/utypes.h" +#include "unicode/ubidi.h" +#include "unicode/errorcode.h" +#include "unicode/localpointer.h" +#include "unicode/putil.h" +#include "unicode/unistr.h" +#include "intltest.h" +#include "uparse.h" + +class BiDiConformanceTest : public IntlTest { +public: + BiDiConformanceTest() : + directionBits(0), lineNumber(0), levelsCount(0), orderingCount(0), + errorCount(0) {} + + void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL); + + void TestBidiTest(); +private: + char *getUnidataPath(char path[]); + + UBool parseLevels(const char *start); + UBool parseOrdering(const char *start); + UBool parseInputStringFromBiDiClasses(const char *&start); + + UBool checkLevels(const UBiDiLevel actualLevels[], int32_t actualCount, + const char *paraLevelName); + UBool checkOrdering(UBiDi *ubidi, const char *paraLevelName); + + void printErrorLine(const char *paraLevelName); + + char line[10000]; + UBiDiLevel levels[1000]; + uint32_t directionBits; + int32_t ordering[1000]; + int32_t lineNumber; + int32_t levelsCount; + int32_t orderingCount; + int32_t errorCount; + UnicodeString inputString; +}; + +extern IntlTest *createBiDiConformanceTest() { + return new BiDiConformanceTest(); +} + +void BiDiConformanceTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { + if(exec) { + logln("TestSuite BiDiConformanceTest: "); + } + switch (index) { + TESTCASE(0, TestBidiTest); + default: + name=""; + break; // needed to end the loop + } +} + +// 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) { + directionBits=0; + levelsCount=0; + while(*start!=0 && *(start=u_skipWhitespace(start))!=0) { + if(*start=='x') { + levels[levelsCount++]=UBIDI_DEFAULT_LTR; + ++start; + } else { + char *end; + uint32_t value=(uint32_t)strtoul(start, &end, 10); + if(end<=start || (!U_IS_INV_WHITESPACE(*end) && *end!=0) || value>(UBIDI_MAX_EXPLICIT_LEVEL+1)) { + errln("@Levels: parse error at %s", start); + return FALSE; + } + levels[levelsCount++]=(UBiDiLevel)value; + directionBits|=(1<<(value&1)); + start=end; + } + } + return TRUE; +} + +UBool BiDiConformanceTest::parseOrdering(const char *start) { + orderingCount=0; + while(*start!=0 && *(start=u_skipWhitespace(start))!=0) { + char *end; + uint32_t value=(uint32_t)strtoul(start, &end, 10); + if(end<=start || (!U_IS_INV_WHITESPACE(*end) && *end!=0) || value>=1000) { + errln("@Reorder: parse error at %s", start); + return FALSE; + } + ordering[orderingCount++]=(int32_t)value; + start=end; + } + return TRUE; +} + +static const UChar charFromBiDiClass[U_CHAR_DIRECTION_COUNT]={ + 0x6c, // 'l' for L + 0x52, // 'R' for R + 0x33, // '3' for EN + 0x2d, // '-' for ES + 0x25, // '%' for ET + 0x39, // '9' for AN + 0x2c, // ',' for CS + 0x2f, // '/' for B + 0x5f, // '_' for S + 0x20, // ' ' for WS + 0x3d, // '=' for ON + 0x65, // 'e' for LRE + 0x6f, // 'o' for LRO + 0x41, // 'A' for AL + 0x45, // 'E' for RLE + 0x4f, // 'O' for RLO + 0x2a, // '*' for PDF + 0x60, // '`' for NSM + 0x7c // '|' for BN +}; + +U_CDECL_BEGIN + +static UCharDirection U_CALLCONV +biDiConfUBiDiClassCallback(const void * /*context*/, UChar32 c) { + for(int i=0; i=UBIDI_DEFAULT_LTR) { + continue; // BiDi control, omitted from expected ordering. + } + if(visualIndex