Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -880,11 +880,11 @@ OBJCFLAGS="$old_OBJCFLAGS" ]) AC_CHECK_FUNCS([sysconf gmtime_r localtime_r nanosleep fcntl]) -AC_CHECK_HEADERS(langinfo.h xlocale.h) +AC_CHECK_HEADERS(xlocale.h) AC_CHECK_FUNCS([strtod_l strtof_l vasprintf_l]) AC_CHECK_FUNC(pipe, [ AC_DEFINE(OF_HAVE_PIPE, 1, [Whether we have pipe()]) ]) Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -70,12 +70,11 @@ #endif - (void)OF_run; @end static OFApplication *app = nil; -extern of_string_encoding_t of_system_info_native_8bit_encoding; -extern OFString *of_system_info_decimal_point; +extern void of_system_info_parse_locale(char*); static void atexitHandler(void) { id delegate = [app delegate]; @@ -107,52 +106,12 @@ id delegate; #ifdef OF_WINDOWS wchar_t **wargv, **wenvp; int wargc, si = 0; #endif -#ifdef HAVE_LANGINFO_H - char *codeset, *lowerCodeset; - size_t codesetLen; -#endif - - setlocale(LC_ALL, ""); - -#ifdef HAVE_LANGINFO_H - codeset = nl_langinfo(CODESET); - codesetLen = strlen(codeset); - - if (SIZE_MAX - codesetLen < 1) - @throw [OFOutOfRangeException exception]; - - if ((lowerCodeset = malloc(codesetLen + 1)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: codesetLen + 1]; - - for (size_t i = 0; i < codesetLen; i++) - lowerCodeset[i] = of_ascii_tolower(codeset[i]); - - if (strcmp(lowerCodeset, "utf8") == 0 || - strcmp(lowerCodeset, "utf-8") == 0) - of_system_info_native_8bit_encoding = OF_STRING_ENCODING_UTF_8; - else if (strcmp(lowerCodeset, "ascii") == 0 || - strcmp(lowerCodeset, "us-ascii") == 0) - of_system_info_native_8bit_encoding = OF_STRING_ENCODING_ASCII; - else if (strcmp(lowerCodeset, "iso8859-1") == 0 || - strcmp(lowerCodeset, "iso-8859-1") == 0) - of_system_info_native_8bit_encoding = - OF_STRING_ENCODING_ISO_8859_1; - else if (strcmp(lowerCodeset, "iso8859-15") == 0 || - strcmp(lowerCodeset, "iso-8859-15") == 0) - of_system_info_native_8bit_encoding = - OF_STRING_ENCODING_ISO_8859_15; - - free(lowerCodeset); -#endif - - of_system_info_decimal_point = [[OFString alloc] - initWithCString: localeconv()->decimal_point - encoding: of_system_info_native_8bit_encoding]; + + of_system_info_parse_locale(setlocale(LC_ALL, "")); if ([cls isSubclassOfClass: [OFApplication class]]) { fprintf(stderr, "FATAL ERROR:\n Class %s is a subclass of " "class OFApplication, but class\n %s was specified as " "application delegate!\n Most likely, you wanted to " Index: src/OFSystemInfo.h ================================================================== --- src/OFSystemInfo.h +++ src/OFSystemInfo.h @@ -44,15 +44,35 @@ /*! * @brief Returns the native 8-bit string encoding of the operating system. * * This is useful to encode strings correctly for passing them to operating * system calls. + * + * If the native 8-bit encoding is unknown, UTF-8 is assumed. * * @return The native 8-bit string encoding of the operating system */ + (of_string_encoding_t)native8BitEncoding; +/*! + * @brief Returns the language of the locale. + * + * If the language is unknown, nil is returned. + * + * @return The language of the locale. + */ ++ (OFString*)language; + +/*! + * @brief Returns the territory of the locale. + * + * If the territory is unknown, nil is returned. + * + * @return The territory of the locale. + */ ++ (OFString*)territory; + /*! * @brief Returns the decimal point in the system's locale. * * @return The decimal point in the system's locale */ Index: src/OFSystemInfo.m ================================================================== --- src/OFSystemInfo.m +++ src/OFSystemInfo.m @@ -22,10 +22,11 @@ #include /* include any libc header to get the libc defines */ #ifdef __GLIBC__ # undef __USE_XOPEN #endif +#include #include #include "platform.h" #ifdef OF_MAC_OS_X @@ -63,14 +64,75 @@ }; #endif static size_t pageSize; static size_t numberOfCPUs; +static of_string_encoding_t native8BitEncoding = OF_STRING_ENCODING_UTF_8; +static OFString *language = nil; +static OFString *territory = nil; +static OFString *decimalPoint = @"."; + +void +of_system_info_parse_locale(char *locale) +{ + if (locale == NULL) + return; + + locale = of_strdup(locale); + + @try { + char *tmp; + + /* We don't care for extras behind the @ */ + if ((tmp = strrchr(locale, '@')) != NULL) + *tmp = '\0'; + + /* Encoding */ + if ((tmp = strrchr(locale, '.')) != NULL) { + size_t tmpLen; + + *tmp++ = '\0'; + + tmpLen = strlen(tmp); + for (size_t i = 0; i < tmpLen; i++) + tmp[i] = of_ascii_tolower(tmp[i]); + + if (strcmp(tmp, "utf8") == 0 || + strcmp(tmp, "utf-8") == 0) + native8BitEncoding = OF_STRING_ENCODING_UTF_8; + else if (strcmp(tmp, "ascii") == 0 || + strcmp(tmp, "us-ascii") == 0) + native8BitEncoding = OF_STRING_ENCODING_ASCII; + else if (strcmp(tmp, "iso8859-1") == 0 || + strcmp(tmp, "iso-8859-1") == 0) + native8BitEncoding = + OF_STRING_ENCODING_ISO_8859_1; + else if (strcmp(tmp, "iso8859-15") == 0 || + strcmp(tmp, "iso-8859-15") == 0) + native8BitEncoding = + OF_STRING_ENCODING_ISO_8859_15; + } + + /* Territory */ + if ((tmp = strrchr(locale, '_')) != NULL) { + *tmp++ = '\0'; + territory = [[OFString alloc] + initWithCString: tmp + encoding: OF_STRING_ENCODING_ASCII]; + } + + language = [[OFString alloc] + initWithCString: locale + encoding: OF_STRING_ENCODING_ASCII]; + } @finally { + free(locale); + } -of_string_encoding_t of_system_info_native_8bit_encoding = - OF_STRING_ENCODING_UTF_8; -OFString *of_system_info_decimal_point = @"."; + decimalPoint = [[OFString alloc] + initWithCString: localeconv()->decimal_point + encoding: native8BitEncoding]; +} #if defined(OF_X86_64) || defined(OF_X86) static OF_INLINE struct x86_regs OF_CONST_FUNC x86_cpuid(uint32_t eax, uint32_t ecx) { @@ -147,16 +209,26 @@ return numberOfCPUs; } + (of_string_encoding_t)native8BitEncoding { - return of_system_info_native_8bit_encoding; + return native8BitEncoding; +} + ++ (OFString*)language +{ + return language; +} + ++ (OFString*)territory +{ + return territory; } + (OFString*)decimalPoint { - return of_system_info_decimal_point; + return decimalPoint; } + (OFString*)userDataPath { #if defined(OF_MAC_OS_X) || defined(OF_IOS)