Author: zooey Date: 2010-07-22 18:53:16 +0200 (Thu, 22 Jul 2010) New Revision: 37699 Changeset: http://dev.haiku-os.org/changeset/37699 Added: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/Jamfile haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/Jamfile haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCategoryData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCollateData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleBackend.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleconvData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUMessagesData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUMonetaryData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUNumericData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUTimeData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/Jamfile Removed: haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUCategoryData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUCollateData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUCtypeData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleconvData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUMessagesData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUMonetaryData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUNumericData.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUTimeData.cpp Modified: haiku/branches/developer/zooey/posix-locale/build/jam/HaikuImage haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h haiku/branches/developer/zooey/posix-locale/src/system/libroot/Jamfile haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/Jamfile haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.cpp haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/setlocale.cpp Log: * renamed libroot-addon-locale.so to libroot-addon-icu.so and prepared the support for more than one backend living in there Modified: haiku/branches/developer/zooey/posix-locale/build/jam/HaikuImage =================================================================== --- haiku/branches/developer/zooey/posix-locale/build/jam/HaikuImage 2010-07-22 16:52:49 UTC (rev 37698) +++ haiku/branches/developer/zooey/posix-locale/build/jam/HaikuImage 2010-07-22 16:53:16 UTC (rev 37699) @@ -87,7 +87,7 @@ libmail.so libmedia.so libmidi.so libmidi2.so libnetwork.so libpng.so - <revisioned>libroot.so libroot-addon-locale.so + <revisioned>libroot.so libroot-addon-icu.so libscreensaver.so libtextencoding.so libtiff.so libtracker.so libtranslation.so libz.so Modified: haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h =================================================================== --- haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h 2010-07-22 16:52:49 UTC (rev 37698) +++ haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h 2010-07-22 16:53:16 UTC (rev 37699) @@ -98,7 +98,7 @@ virtual void Initialize(LocaleDataBridge* dataBridge) = 0; - static status_t LoadBackend(LocaleDataBridge* dataBridge); + static status_t LoadBackend(); }; Modified: haiku/branches/developer/zooey/posix-locale/src/system/libroot/Jamfile =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/Jamfile 2010-07-22 16:52:49 UTC (rev 37698) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/Jamfile 2010-07-22 16:53:16 UTC (rev 37699) @@ -91,5 +91,6 @@ } +SubInclude HAIKU_TOP src system libroot add-ons ; SubInclude HAIKU_TOP src system libroot os ; SubInclude HAIKU_TOP src system libroot posix ; Added: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/Jamfile =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/Jamfile (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/Jamfile 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,3 @@ +SubDir HAIKU_TOP src system libroot add-ons ; + +SubInclude HAIKU_TOP src system libroot add-ons icu ; Added: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/Jamfile =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/Jamfile (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/Jamfile 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,14 @@ +SubDir HAIKU_TOP src system libroot add-ons icu ; + +local addonIcuObjects = + addon_icu_locale.o +; + +SharedLibrary libroot-addon-icu.so + : + : + $(addonIcuObjects:G=nogrist) + $(TARGET_LIBSTDC++) $(HAIKU_ICU_LIBS) +; + +SubInclude HAIKU_TOP src system libroot add-ons icu locale ; Copied: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCategoryData.cpp (from rev 37598, haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUCategoryData.cpp) =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCategoryData.cpp (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCategoryData.cpp 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,133 @@ +/* + * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "ICUCategoryData.h" + +#include <string.h> + +#include <unicode/uchar.h> + + +namespace BPrivate { + + +ICUCategoryData::ICUCategoryData() + : + fConverter(NULL) +{ + *fPosixLocaleName = '\0'; + *fGivenCharset = '\0'; +} + + +ICUCategoryData::~ICUCategoryData() +{ + if (fConverter) + ucnv_close(fConverter); +} + + +status_t +ICUCategoryData::_SetupConverter() +{ + if (fConverter != NULL) { + ucnv_close(fConverter); + fConverter = NULL; + } + + UErrorCode icuStatus = U_ZERO_ERROR; + fConverter = ucnv_open(fGivenCharset, &icuStatus); + if (fConverter == NULL) + return B_NAME_NOT_FOUND; + + icuStatus = U_ZERO_ERROR; + ucnv_setToUCallBack(fConverter, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, + NULL, &icuStatus); + icuStatus = U_ZERO_ERROR; + ucnv_setFromUCallBack(fConverter, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, + NULL, &icuStatus); + if (!U_SUCCESS(icuStatus)) + return B_ERROR; + + return B_OK; +} + + +status_t +ICUCategoryData::SetTo(const Locale& locale, const char* posixLocaleName) +{ + if (!posixLocaleName) + return B_BAD_VALUE; + + fLocale = locale; + strlcpy(fPosixLocaleName, posixLocaleName, skMaxPosixLocaleNameLen); + *fGivenCharset = '\0'; + + // POSIX locales often contain an embedded charset, but ICU does not + // handle these within locales (that part of the name is simply + // ignored). + // We need to fetch the charset specification and lookup an appropriate + // ICU charset converter. This converter will later be used to get info + // about ctype properties. + const char* charsetStart = strchr(fPosixLocaleName, '.'); + if (charsetStart) { + ++charsetStart; + int l = 0; + while (charsetStart[l] != '\0' && charsetStart[l] != '@') + ++l; + snprintf(fGivenCharset, UCNV_MAX_CONVERTER_NAME_LENGTH, "%.*s", l, + charsetStart); + } + if (!strlen(fGivenCharset)) + strcpy(fGivenCharset, "utf-8"); + + return _SetupConverter(); +} + + +status_t +ICUCategoryData::SetToPosix() +{ + fLocale = Locale::createFromName("en_US_POSIX"); + strcpy(fPosixLocaleName, "POSIX"); + strcpy(fGivenCharset, "US-ASCII"); + + return _SetupConverter(); +} + + +status_t +ICUCategoryData::_ConvertUnicodeStringToLocaleconvEntry( + const UnicodeString& string, char* destination, int destinationSize, + const char* defaultValue) +{ + status_t result = B_OK; + UErrorCode icuStatus = U_ZERO_ERROR; + + ucnv_fromUChars(fConverter, destination, destinationSize, + string.getBuffer(), string.length(), &icuStatus); + if (!U_SUCCESS(icuStatus)) { + switch (icuStatus) { + case U_BUFFER_OVERFLOW_ERROR: + result = B_NAME_TOO_LONG; + break; + case U_INVALID_CHAR_FOUND: + case U_TRUNCATED_CHAR_FOUND: + case U_ILLEGAL_CHAR_FOUND: + result = B_BAD_DATA; + break; + default: + result = B_ERROR; + break; + } + strcpy(destination, defaultValue); + } + + return result; +} + + +} // namespace BPrivate Copied: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCollateData.cpp (from rev 37598, haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUCollateData.cpp) =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCollateData.cpp (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCollateData.cpp 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,176 @@ +/* + * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "ICUCollateData.h" + +#include <string.h> + +#include <unicode/unistr.h> + + +namespace BPrivate { + + +ICUCollateData::ICUCollateData() + : + fCollator(NULL) +{ +} + + +ICUCollateData::~ICUCollateData() +{ + delete fCollator; +} + + +status_t +ICUCollateData::SetTo(const Locale& locale, const char* posixLocaleName) +{ + status_t result = inherited::SetTo(locale, posixLocaleName); + + if (result == B_OK) { + UErrorCode icuStatus = U_ZERO_ERROR; + delete fCollator; + fCollator = Collator::createInstance(fLocale, icuStatus); + if (!U_SUCCESS(icuStatus)) + return B_NO_MEMORY; + } + + return result; +} + + +status_t +ICUCollateData::SetToPosix() +{ + status_t result = inherited::SetToPosix(); + + if (result == B_OK) { + delete fCollator; + fCollator = NULL; + } + + return result; +} + + +status_t +ICUCollateData::Strcoll(const char* a, const char* b, int& result) +{ + if (strcmp(fPosixLocaleName, "POSIX") == 0) { + // handle POSIX here as the collator ICU uses for that (english) is + // incompatible in too many ways + result = strcmp(a, b); + for (const char* aIter = a; *aIter != 0; ++aIter) { + if (*aIter < 0) + return B_BAD_VALUE; + } + for (const char* bIter = b; *bIter != 0; ++bIter) { + if (*bIter < 0) + return B_BAD_VALUE; + } + return B_OK; + } + + status_t status = B_OK; + UErrorCode icuStatus = U_ZERO_ERROR; + + if (strcasecmp(fGivenCharset, "utf-8") == 0) { + UCharIterator aIter, bIter; + uiter_setUTF8(&aIter, a, -1); + uiter_setUTF8(&bIter, b, -1); + + result = fCollator->compare(aIter, bIter, icuStatus); + } else { + UnicodeString unicodeA; + UnicodeString unicodeB; + + if (_ToUnicodeString(a, unicodeA) != B_OK + || _ToUnicodeString(b, unicodeB) != B_OK) { + status = B_BAD_VALUE; + } + + result = fCollator->compare(unicodeA, unicodeB, icuStatus); + } + + if (!U_SUCCESS(icuStatus)) + status = B_BAD_VALUE; + + return status; +} + + +status_t +ICUCollateData::Strxfrm(char* out, const char* in, size_t size, size_t& outSize) +{ + if (strcmp(fPosixLocaleName, "POSIX") == 0) { + // handle POSIX here as the collator ICU uses for that (english) is + // incompatible in too many ways + outSize = strlcpy(out, in, size); + for (const char* inIter = in; *inIter != 0; ++inIter) { + if (*inIter < 0) + return B_BAD_VALUE; + } + return B_OK; + } + + if (in == NULL) { + outSize = 0; + return B_OK; + } + + UErrorCode icuStatus = U_ZERO_ERROR; + + UnicodeString unicodeIn; + if (_ToUnicodeString(in, unicodeIn) != B_OK) + return B_BAD_VALUE; + + outSize = fCollator->getSortKey(unicodeIn, (uint8_t*)out, size); + if (!U_SUCCESS(icuStatus)) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +ICUCollateData::_ToUnicodeString(const char* in, UnicodeString& out) +{ + out.remove(); + + if (in == NULL) + return B_OK; + + size_t inLen = strlen(in); + if (inLen == 0) + return B_OK; + + UErrorCode icuStatus = U_ZERO_ERROR; + int32_t outLen = ucnv_toUChars(fConverter, NULL, 0, in, inLen, &icuStatus); + if (icuStatus != U_BUFFER_OVERFLOW_ERROR) + return B_BAD_VALUE; + if (outLen < 0) + return B_ERROR; + if (outLen == 0) + return B_OK; + + UChar* outBuf = out.getBuffer(outLen + 1); + icuStatus = U_ZERO_ERROR; + outLen + = ucnv_toUChars(fConverter, outBuf, outLen + 1, in, inLen, &icuStatus); + if (!U_SUCCESS(icuStatus)) { + out.releaseBuffer(0); + return B_BAD_VALUE; + } + + out.releaseBuffer(outLen); + + return B_OK; +} + + +} // namespace BPrivate Copied: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp (from rev 37667, haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUCtypeData.cpp) =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUCtypeData.cpp 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,186 @@ +/* + * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "ICUCtypeData.h" + +#include <langinfo.h> +#include <string.h> + +#include <unicode/uchar.h> + + +namespace BPrivate { + + +ICUCtypeData::ICUCtypeData() + : + fDataBridge(NULL) +{ +} + + +ICUCtypeData::~ICUCtypeData() +{ +} + + +void +ICUCtypeData::Initialize(LocaleCtypeDataBridge* dataBridge) +{ + *dataBridge->addrOfClassInfoTable = fClassInfo; + *dataBridge->addrOfToLowerTable = fToLowerMap; + *dataBridge->addrOfToUpperTable = fToUpperMap; + fDataBridge = dataBridge; +} + + +status_t +ICUCtypeData::SetTo(const Locale& locale, const char* posixLocaleName) +{ + status_t result = inherited::SetTo(locale, posixLocaleName); + if (result != B_OK) + return result; + + UErrorCode icuStatus = U_ZERO_ERROR; + + ucnv_reset(fConverter); + char buffer[] = { 0, 0 }; + for (int i = 0; i < 256; ++i) { + const char* source = buffer; + buffer[0] = (char)i; + buffer[1] = '\0'; + icuStatus = U_ZERO_ERROR; + UChar32 unicodeChar + = ucnv_getNextUChar(fConverter, &source, source + 1, &icuStatus); + + unsigned short classInfo = 0; + unsigned int toLower = i; + unsigned int toUpper = i; + if (U_SUCCESS(icuStatus)) { + if (u_isblank(unicodeChar)) + classInfo |= _ISblank; + if (u_charType(unicodeChar) == U_CONTROL_CHAR) + classInfo |= _IScntrl; + if (u_ispunct(unicodeChar)) + classInfo |= _ISpunct; + if (u_hasBinaryProperty(unicodeChar, UCHAR_POSIX_ALNUM)) + classInfo |= _ISalnum; + if (u_isUUppercase(unicodeChar)) + classInfo |= _ISupper; + if (u_isULowercase(unicodeChar)) + classInfo |= _ISlower; + if (u_isUAlphabetic(unicodeChar)) + classInfo |= _ISalpha; + if (u_isdigit(unicodeChar)) + classInfo |= _ISdigit; + if (u_isxdigit(unicodeChar)) + classInfo |= _ISxdigit; + if (u_isUWhiteSpace(unicodeChar)) + classInfo |= _ISspace; + if (u_hasBinaryProperty(unicodeChar, UCHAR_POSIX_PRINT)) + classInfo |= _ISprint; + if (u_hasBinaryProperty(unicodeChar, UCHAR_POSIX_GRAPH)) + classInfo |= _ISgraph; + + UChar lowerChar = u_tolower(unicodeChar); + icuStatus = U_ZERO_ERROR; + ucnv_fromUChars(fConverter, buffer, 1, &lowerChar, 1, &icuStatus); + if (U_SUCCESS(icuStatus)) + toLower = (unsigned char)buffer[0]; + + UChar upperChar = u_toupper(unicodeChar); + icuStatus = U_ZERO_ERROR; + ucnv_fromUChars(fConverter, buffer, 1, &upperChar, 1, &icuStatus); + if (U_SUCCESS(icuStatus)) + toUpper = (unsigned char)buffer[0]; + } + fClassInfo[i] = classInfo; + fToLowerMap[i] = toLower; + fToUpperMap[i] = toUpper; + } + + return B_OK; +} + + +status_t +ICUCtypeData::SetToPosix() +{ + status_t result = inherited::SetToPosix(); + + if (result == B_OK) { + memcpy(fClassInfo, fDataBridge->posixClassInfo, sizeof(fClassInfo)); + memcpy(fToLowerMap, fDataBridge->posixToLowerMap, sizeof(fToLowerMap)); + memcpy(fToUpperMap, fDataBridge->posixToUpperMap, sizeof(fToUpperMap)); + } + + return result; +} + + +int +ICUCtypeData::IsWCType(wint_t wc, wctype_t charClass) +{ + switch (charClass) { + case _ISalnum: + return u_hasBinaryProperty(wc, UCHAR_POSIX_ALNUM); + case _ISalpha: + return u_isUAlphabetic(wc); + case _ISblank: + return u_isblank(wc); + case _IScntrl: + return u_charType(wc) == U_CONTROL_CHAR; + case _ISdigit: + return u_isdigit(wc); + case _ISgraph: + return u_hasBinaryProperty(wc, UCHAR_POSIX_GRAPH); + case _ISlower: + return u_isULowercase(wc); + case _ISprint: + return u_hasBinaryProperty(wc, UCHAR_POSIX_PRINT); + case _ISpunct: + return u_ispunct(wc); + case _ISspace: + return u_isUWhiteSpace(wc); + case _ISupper: + return u_isUUppercase(wc); + case _ISxdigit: + return u_isxdigit(wc); + default: + return 0; + } +} + + +status_t +ICUCtypeData::ToWCTrans(wint_t wc, wctrans_t transition, wint_t& result) +{ + switch (transition) { + case _ISlower: + result = u_tolower(wc); + return B_OK; + case _ISupper: + result = u_toupper(wc); + return B_OK; + default: + return B_BAD_VALUE; + } +} + + +const char* +ICUCtypeData::GetLanginfo(int index) +{ + switch(index) { + case CODESET: + return fGivenCharset; + default: + return ""; + } +} + + +} // namespace BPrivate Copied: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleBackend.cpp (from rev 37667, haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp) =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleBackend.cpp (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleBackend.cpp 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,319 @@ +/* + * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "ICULocaleBackend.h" + +#include <new> + +#include <langinfo.h> +#include <locale.h> +#include <string.h> + + +namespace BPrivate { + + +extern "C" LocaleBackend* +CreateInstance() +{ + return new(std::nothrow) ICULocaleBackend(); +} + + +ICULocaleBackend::ICULocaleBackend() + : + fMonetaryData(fLocaleConv), + fNumericData(fLocaleConv), + fTimeData(fLCTimeInfo) +{ +} + + +ICULocaleBackend::~ICULocaleBackend() +{ +} + + +void +ICULocaleBackend::Initialize(LocaleDataBridge* dataBridge) +{ + fCtypeData.Initialize(&dataBridge->ctypeDataBridge); + fMessagesData.Initialize(&dataBridge->messagesDataBridge); + fMonetaryData.Initialize(&dataBridge->monetaryDataBridge); + fNumericData.Initialize(&dataBridge->numericDataBridge); + fTimeData.Initialize(&dataBridge->timeDataBridge); + + fPosixLanginfo = dataBridge->posixLanginfo; + + _SetPosixLocale(LC_ALL); +} + + +const char* +ICULocaleBackend::SetLocale(int category, const char* posixLocaleName) +{ + if (posixLocaleName == NULL) + return _QueryLocale(category); + + if (strcasecmp(posixLocaleName, "POSIX") == 0 + || strcasecmp(posixLocaleName, "C") == 0) + return _SetPosixLocale(category); + + Locale locale = Locale::createCanonical(posixLocaleName); + switch (category) { + case LC_ALL: + if (fCollateData.SetTo(locale, posixLocaleName) != B_OK + || fCtypeData.SetTo(locale, posixLocaleName) != B_OK + || fMessagesData.SetTo(locale, posixLocaleName) != B_OK + || fMonetaryData.SetTo(locale, posixLocaleName) != B_OK + || fNumericData.SetTo(locale, posixLocaleName) != B_OK + || fTimeData.SetTo(locale, posixLocaleName) != B_OK) + return NULL; + break; + case LC_COLLATE: + if (fCollateData.SetTo(locale, posixLocaleName) != B_OK) + return NULL; + break; + case LC_CTYPE: + if (fCtypeData.SetTo(locale, posixLocaleName) != B_OK) + return NULL; + break; + case LC_MESSAGES: + if (fMessagesData.SetTo(locale, posixLocaleName) != B_OK) + return NULL; + break; + case LC_MONETARY: + if (fMonetaryData.SetTo(locale, posixLocaleName) != B_OK) + return NULL; + break; + case LC_NUMERIC: + if (fNumericData.SetTo(locale, posixLocaleName) != B_OK) + return NULL; + break; + case LC_TIME: + if (fTimeData.SetTo(locale, posixLocaleName) != B_OK) + return NULL; + break; + default: + // unsupported category + return NULL; + } + + return posixLocaleName; +} + + +const struct lconv* +ICULocaleBackend::LocaleConv() +{ + return &fLocaleConv; +} + + +const struct lc_time_t* +ICULocaleBackend::LCTimeInfo() +{ + return &fLCTimeInfo; +} + + +int +ICULocaleBackend::IsWCType(wint_t wc, wctype_t charClass) +{ + return fCtypeData.IsWCType(wc, charClass); +} + + +status_t +ICULocaleBackend::ToWCTrans(wint_t wc, wctrans_t transition, wint_t& result) +{ + return fCtypeData.ToWCTrans(wc, transition, result); +} + + +const char* +ICULocaleBackend::GetLanginfo(int index) +{ + switch(index) { + case CODESET: + return fCtypeData.GetLanginfo(index); + + case D_T_FMT: + case D_FMT: + case T_FMT: + case T_FMT_AMPM: + case AM_STR: + case PM_STR: + case DAY_1: + case DAY_2: + case DAY_3: + case DAY_4: + case DAY_5: + case DAY_6: + case DAY_7: + case ABDAY_1: + case ABDAY_2: + case ABDAY_3: + case ABDAY_4: + case ABDAY_5: + case ABDAY_6: + case ABDAY_7: + case MON_1: + case MON_2: + case MON_3: + case MON_4: + case MON_5: + case MON_6: + case MON_7: + case MON_8: + case MON_9: + case MON_10: + case MON_11: + case MON_12: + case ABMON_1: + case ABMON_2: + case ABMON_3: + case ABMON_4: + case ABMON_5: + case ABMON_6: + case ABMON_7: + case ABMON_8: + case ABMON_9: + case ABMON_10: + case ABMON_11: + case ABMON_12: + return fTimeData.GetLanginfo(index); + + case ERA: + case ERA_D_FMT: + case ERA_D_T_FMT: + case ERA_T_FMT: + case ALT_DIGITS: + return fPosixLanginfo[index]; + + case RADIXCHAR: + case THOUSEP: + return fNumericData.GetLanginfo(index); + + case YESEXPR: + case NOEXPR: + return fMessagesData.GetLanginfo(index); + + case CRNCYSTR: + return fMonetaryData.GetLanginfo(index); + + default: + return ""; + } +} + + +status_t +ICULocaleBackend::Strcoll(const char* a, const char* b, int& result) +{ + return fCollateData.Strcoll(a, b, result); +} + + +status_t +ICULocaleBackend::Strxfrm(char* out, const char* in, size_t size, + size_t& outSize) +{ + return fCollateData.Strxfrm(out, in, size, outSize); +} + + +const char* +ICULocaleBackend::_QueryLocale(int category) +{ + switch (category) { + case LC_ALL: + { + // if all categories have the same locale, return that + const char* locale = fCollateData.PosixLocaleName(); + if (strcmp(locale, fCtypeData.PosixLocaleName()) == 0 + && strcmp(locale, fMessagesData.PosixLocaleName()) == 0 + && strcmp(locale, fMonetaryData.PosixLocaleName()) == 0 + && strcmp(locale, fNumericData.PosixLocaleName()) == 0 + && strcmp(locale, fTimeData.PosixLocaleName()) == 0) + return locale; + + // build a string with all info (at least glibc does it, too) + snprintf(fLocaleDescription, sizeof(fLocaleDescription), + "LC_COLLATE=%s;LC_CTYPE=%s;LC_MESSAGES=%s;LC_MONETARY=%s;" + "LC_NUMERIC=%s;LC_TIME=%s", + fCollateData.PosixLocaleName(), fCtypeData.PosixLocaleName(), + fMessagesData.PosixLocaleName(), + fMonetaryData.PosixLocaleName(), fNumericData.PosixLocaleName(), + fTimeData.PosixLocaleName()); + return fLocaleDescription; + } + case LC_COLLATE: + return fCollateData.PosixLocaleName(); + case LC_CTYPE: + return fCtypeData.PosixLocaleName(); + case LC_MESSAGES: + return fMessagesData.PosixLocaleName(); + case LC_MONETARY: + return fMonetaryData.PosixLocaleName(); + case LC_NUMERIC: + return fNumericData.PosixLocaleName(); + case LC_TIME: + return fTimeData.PosixLocaleName(); + default: + // unsupported category + return NULL; + } +} + + +const char* +ICULocaleBackend::_SetPosixLocale(int category) +{ + switch (category) { + case LC_ALL: + if (fCollateData.SetToPosix() != B_OK + || fCtypeData.SetToPosix() != B_OK + || fMessagesData.SetToPosix() != B_OK + || fMonetaryData.SetToPosix() != B_OK + || fNumericData.SetToPosix() != B_OK + || fTimeData.SetToPosix() != B_OK) + return NULL; + break; + case LC_COLLATE: + if (fCollateData.SetToPosix() != B_OK) + return NULL; + break; + case LC_CTYPE: + if (fCtypeData.SetToPosix() != B_OK) + return NULL; + break; + case LC_MESSAGES: + if (fMessagesData.SetToPosix() != B_OK) + return NULL; + break; + case LC_MONETARY: + if (fMonetaryData.SetToPosix() != B_OK) + return NULL; + break; + case LC_NUMERIC: + if (fNumericData.SetToPosix() != B_OK) + return NULL; + break; + case LC_TIME: + if (fTimeData.SetToPosix() != B_OK) + return NULL; + break; + default: + // unsupported category + return NULL; + } + + return "POSIX"; +} + + +} // namespace BPrivate Copied: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleconvData.cpp (from rev 37598, haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleconvData.cpp) =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleconvData.cpp (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICULocaleconvData.cpp 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,32 @@ +/* + * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "ICULocaleconvData.h" + +#include <string.h> + + +namespace BPrivate { + + +status_t +ICULocaleconvData::_SetLocaleconvEntry(const DecimalFormatSymbols* formatSymbols, + char* destination, FormatSymbol symbol, const char* defaultValue) +{ + status_t result = B_OK; + + UnicodeString symbolString = formatSymbols->getSymbol(symbol); + if (!symbolString.isEmpty()) { + result = _ConvertUnicodeStringToLocaleconvEntry(symbolString, + destination, skLCBufSize, defaultValue); + } else + destination[0] = '\0'; + + return result; +} + + +} // namespace BPrivate Copied: haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUMessagesData.cpp (from rev 37598, haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICUMessagesData.cpp) =================================================================== --- haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUMessagesData.cpp (rev 0) +++ haiku/branches/developer/zooey/posix-locale/src/system/libroot/add-ons/icu/locale/ICUMessagesData.cpp 2010-07-22 16:53:16 UTC (rev 37699) @@ -0,0 +1,60 @@ +/* + * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "ICUMessagesData.h" + +#include <langinfo.h> +#include <string.h> + + +namespace BPrivate { + + +void +ICUMessagesData::Initialize(LocaleMessagesDataBridge* dataBridge) +{ + fPosixLanginfo = dataBridge->posixLanginfo; +} + + +status_t +ICUMessagesData::SetTo(const Locale& locale, const char* posixLocaleName) +{ + status_t result = inherited::SetTo(locale, posixLocaleName); + + // TODO: open the "POSIX" catalog and fetch the translations from there! + + return result; +} + + +status_t +ICUMessagesData::SetToPosix() +{ + status_t result = inherited::SetToPosix(); + + strcpy(fYesExpression, fPosixLanginfo[YESEXPR]); + strcpy(fNoExpression, fPosixLanginfo[NOEXPR]); + + return result; +} + + +const char* +ICUMessagesData::GetLanginfo(int index) +{ + switch(index) { + case YESEXPR: [... truncated: 1015 lines follow ...]