diff --git a/headers/private/libroot/locale/ICUCtypeData.h b/headers/private/libroot/locale/ICUCtypeData.h index 38d91f2973..b560205a7a 100644 --- a/headers/private/libroot/locale/ICUCtypeData.h +++ b/headers/private/libroot/locale/ICUCtypeData.h @@ -32,9 +32,14 @@ public: const char* GetLanginfo(int index); private: - unsigned short fClassInfo[256]; - int fToLowerMap[256]; - int fToUpperMap[256]; + /* + * the following arrays have 257 elements where the first is a + * dummy element (containing the neutral/identity value) used when + * the array is accessed as in 'isblank(EOF)' (i.e. with index -1). + */ + unsigned short fClassInfo[257]; + int fToLowerMap[257]; + int fToUpperMap[257]; LocaleCtypeDataBridge* fDataBridge; }; diff --git a/headers/private/libroot/locale/PosixCtype.h b/headers/private/libroot/locale/PosixCtype.h index 9dfa51e83c..cf99c92672 100644 --- a/headers/private/libroot/locale/PosixCtype.h +++ b/headers/private/libroot/locale/PosixCtype.h @@ -9,9 +9,14 @@ namespace BPrivate { -extern const unsigned short gPosixClassInfo[256]; -extern const int gPosixToLowerMap[256]; -extern const int gPosixToUpperMap[256]; +/* + * the following arrays have 257 elements where the first is a + * dummy element (containing the neutral/identity value) used when + * the array is accessed as in 'isblank(EOF)' (i.e. with index -1). + */ +extern const unsigned short gPosixClassInfo[257]; +extern const int gPosixToLowerMap[257]; +extern const int gPosixToUpperMap[257]; } // namespace BPrivate diff --git a/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp b/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp index 432ef1e15a..f477ca9ee3 100644 --- a/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp +++ b/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp @@ -30,9 +30,9 @@ ICUCtypeData::~ICUCtypeData() void ICUCtypeData::Initialize(LocaleCtypeDataBridge* dataBridge) { - *dataBridge->addrOfClassInfoTable = fClassInfo; - *dataBridge->addrOfToLowerTable = fToLowerMap; - *dataBridge->addrOfToUpperTable = fToUpperMap; + *dataBridge->addrOfClassInfoTable = &fClassInfo[1]; + *dataBridge->addrOfToLowerTable = &fToLowerMap[1]; + *dataBridge->addrOfToUpperTable = &fToUpperMap[1]; fDataBridge = dataBridge; } @@ -97,9 +97,9 @@ ICUCtypeData::SetTo(const Locale& locale, const char* posixLocaleName) if (U_SUCCESS(icuStatus)) toUpper = (unsigned char)buffer[0]; } - fClassInfo[i] = classInfo; - fToLowerMap[i] = toLower; - fToUpperMap[i] = toUpper; + fClassInfo[i + 1] = classInfo; + fToLowerMap[i + 1] = toLower; + fToUpperMap[i + 1] = toUpper; } return B_OK; @@ -124,6 +124,9 @@ ICUCtypeData::SetToPosix() int ICUCtypeData::IsWCType(wint_t wc, wctype_t charClass) { + if (wc == WEOF) + return 0; + switch (charClass) { case _ISalnum: return u_hasBinaryProperty(wc, UCHAR_POSIX_ALNUM); diff --git a/src/system/libroot/posix/locale/LocaleData.cpp b/src/system/libroot/posix/locale/LocaleData.cpp index a17ff232ed..ae5de96ef1 100644 --- a/src/system/libroot/posix/locale/LocaleData.cpp +++ b/src/system/libroot/posix/locale/LocaleData.cpp @@ -27,7 +27,13 @@ namespace BPrivate { -const unsigned short gPosixClassInfo[256] = { +/* + * the following arrays have 257 elements where the first is a + * dummy element (containing the neutral/identity value) used when + * the array is accessed as in 'isblank(EOF)' (i.e. with index -1). + */ +const unsigned short gPosixClassInfo[257] = { + /* -1 */ 0, // neutral value /* 0 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, /* 8 */ _IScntrl, _ISblank|_IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl, _IScntrl, /* 16 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, @@ -62,7 +68,8 @@ const unsigned short gPosixClassInfo[256] = { /* 248 */ 0, 0, 0, 0, 0, 0, 0, 0 }; -const int gPosixToLowerMap[256] = { +const int gPosixToLowerMap[257] = { + /* -1 */ -1, // identity value /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, @@ -98,7 +105,8 @@ const int gPosixToLowerMap[256] = { }; -const int gPosixToUpperMap[256] = { +const int gPosixToUpperMap[257] = { + /* -1 */ -1, // identity value /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, @@ -267,6 +275,6 @@ const char* gPosixLanginfo[_NL_LANGINFO_LAST] = { } // namespace BPrivate -const unsigned short* __ctype_b = BPrivate::gPosixClassInfo; -const int* __ctype_tolower = BPrivate::gPosixToLowerMap; -const int* __ctype_toupper = BPrivate::gPosixToUpperMap; +const unsigned short* __ctype_b = &BPrivate::gPosixClassInfo[1]; +const int* __ctype_tolower = &BPrivate::gPosixToLowerMap[1]; +const int* __ctype_toupper = &BPrivate::gPosixToUpperMap[1]; diff --git a/src/tests/system/libroot/posix/locale_test.cpp b/src/tests/system/libroot/posix/locale_test.cpp index 63ce4a43e8..e2a62b6df4 100644 --- a/src/tests/system/libroot/posix/locale_test.cpp +++ b/src/tests/system/libroot/posix/locale_test.cpp @@ -691,24 +691,24 @@ test_ctype(const char* locale, const unsigned short int classInfos[], printf("ctype of %s locale\n", locale); int problemCount = 0; - for (int i = 0; i < 256; ++i) { + for (int i = -1; i < 256; ++i) { unsigned short classInfo = determineFullClassInfo(i); - if (classInfo != classInfos[i]) { - printf("\tPROBLEM: %d = %x (expected %x)\n", i, classInfo, - classInfos[i]); + if (classInfo != classInfos[i + 1]) { + printf("\tPROBLEM: ctype(%d) = %x (expected %x)\n", i, classInfo, + classInfos[i + 1]); problemCount++; } int lower = tolower(i); - if (lower != toLowerMap[i]) { + if (lower != toLowerMap[i + 1]) { printf("\tPROBLEM: tolower(%d) = %x (expected %x)\n", i, lower, - toLowerMap[i]); + toLowerMap[i + 1]); problemCount++; } int upper = toupper(i); - if (upper != toUpperMap[i]) { + if (upper != toUpperMap[i + 1]) { printf("\tPROBLEM: toupper(%d) = %x (expected %x)\n", i, upper, - toUpperMap[i]); + toUpperMap[i + 1]); problemCount++; } } @@ -722,7 +722,8 @@ test_ctype(const char* locale, const unsigned short int classInfos[], void test_ctype() { - const unsigned short int classInfos_posix[256] = { + const unsigned short int classInfos_posix[257] = { + /* -1 */ 0, // neutral value /* 0 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, /* 8 */ _IScntrl, _ISblank|_IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl, _IScntrl, /* 16 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, @@ -756,7 +757,8 @@ test_ctype() /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 248 */ 0, 0, 0, 0, 0, 0, 0, 0, }; - const int toLowerMap_posix[256] = { + const int toLowerMap_posix[257] = { + /* -1 */ -1, // identity value /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, @@ -790,7 +792,8 @@ test_ctype() /* 240 */ 240, 241, 242, 243, 244, 245, 246, 247, /* 248 */ 248, 249, 250, 251, 252, 253, 254, 255, }; - const int toUpperMap_posix[256] = { + const int toUpperMap_posix[257] = { + /* -1 */ -1, // identity value /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, @@ -826,7 +829,8 @@ test_ctype() }; test_ctype("POSIX", classInfos_posix, toLowerMap_posix, toUpperMap_posix); - const unsigned short int classInfos_de[256] = { + const unsigned short int classInfos_de[257] = { + /* -1 */ 0, // neutral value /* 0 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, /* 8 */ _IScntrl, _ISblank|_IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl, _IScntrl, /* 16 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, @@ -860,7 +864,8 @@ test_ctype() /* 240 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph, /* 248 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, }; - const int toLowerMap_de[256] = { + const int toLowerMap_de[257] = { + /* -1 */ -1, // identity value /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, @@ -894,7 +899,8 @@ test_ctype() /* 240 */ 240, 241, 242, 243, 244, 245, 246, 247, /* 248 */ 248, 249, 250, 251, 252, 253, 254, 255, }; - const int toUpperMap_de[256] = { + const int toUpperMap_de[257] = { + /* -1 */ -1, // identity value /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, @@ -930,7 +936,8 @@ test_ctype() }; test_ctype("de_DE.ISO8859-1", classInfos_de, toLowerMap_de, toUpperMap_de); - const unsigned short int classInfos_utf8[256] = { + const unsigned short int classInfos_utf8[257] = { + /* -1 */ 0, // neutral value /* 0 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, /* 8 */ _IScntrl, _ISblank|_IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl, _IScntrl, /* 16 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, @@ -1014,9 +1021,14 @@ test_wctype(const char* locale, const wchar_t* text, printf("wctype of %s locale\n", locale); int problemCount = 0; + unsigned short classInfo = determineWideFullClassInfo(WEOF); + if (classInfo != 0) { + printf("\tPROBLEM: classinfo for WEOF = %x (expected 0)\n", classInfo); + problemCount++; + } wint_t wc = *text; for (int i = 0; i < 48; wc = *++text, ++i) { - unsigned short classInfo = determineWideFullClassInfo(wc); + classInfo = determineWideFullClassInfo(wc); if (wc != wcs[i]) { printf("\tPROBLEM: wc for char #%d = %x (expected %x)\n", i, wc, wcs[i]);