@@ -19,10 +19,17 @@ #include #include #include #include #include + +#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L) +# include +#endif +#ifdef HAVE_XLOCALE_H +# include +#endif #include #import "OFString.h" #import "OFString_UTF8.h" @@ -64,10 +71,14 @@ * However, the MinGW version __strtod seems to be ok. */ #ifdef __MINGW32__ # define strtod __strtod #endif + +#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L) +static locale_t cLocale; +#endif @interface OFString () - (size_t)OF_getCString: (char*)cString maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding @@ -499,12 +510,19 @@ @end @implementation OFString + (void)initialize { - if (self == [OFString class]) - placeholder.isa = [OFString_placeholder class]; + if (self != [OFString class]) + return; + + placeholder.isa = [OFString_placeholder class]; + +#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L) + if ((cLocale = newlocale(LC_ALL_MASK, "C", NULL)) == NULL) + @throw [OFInitializationFailedException exception]; +#endif } + alloc { if (self == [OFString class]) @@ -2334,22 +2352,34 @@ } - (float)floatValue { void *pool = objc_autoreleasePoolPush(); +#ifdef HAVE_STRTOF_L + const char *UTF8String = [self UTF8String]; +#else + /* + * If we have no strtof_l, we have no other choice but to replace "." + * with the locale's decimal point. + */ OFString *decimalPoint = [OFSystemInfo decimalPoint]; const char *UTF8String = [[self stringByReplacingOccurrencesOfString: @"." withString: decimalPoint] UTF8String]; +#endif char *endPointer = NULL; float value; while (*UTF8String == ' ' || *UTF8String == '\t' || *UTF8String == '\n' || *UTF8String == '\r' || *UTF8String == '\f') UTF8String++; +#ifdef HAVE_STRTOF_L + value = strtof_l(UTF8String, &endPointer, cLocale); +#else value = strtof(UTF8String, &endPointer); +#endif /* Check if there are any invalid chars left */ if (endPointer != NULL) for (; *endPointer != '\0'; endPointer++) if (*endPointer != ' ' && *endPointer != '\t' && @@ -2363,22 +2393,34 @@ } - (double)doubleValue { void *pool = objc_autoreleasePoolPush(); +#ifdef HAVE_STRTOD_L + const char *UTF8String = [self UTF8String]; +#else + /* + * If we have no strtod_l, we have no other choice but to replace "." + * with the locale's decimal point. + */ OFString *decimalPoint = [OFSystemInfo decimalPoint]; const char *UTF8String = [[self stringByReplacingOccurrencesOfString: @"." withString: decimalPoint] UTF8String]; +#endif char *endPointer = NULL; double value; while (*UTF8String == ' ' || *UTF8String == '\t' || *UTF8String == '\n' || *UTF8String == '\r' || *UTF8String == '\f') UTF8String++; +#ifdef HAVE_STRTOD_L + value = strtod_l(UTF8String, &endPointer, cLocale); +#else value = strtod(UTF8String, &endPointer); +#endif /* Check if there are any invalid chars left */ if (endPointer != NULL) for (; *endPointer != '\0'; endPointer++) if (*endPointer != ' ' && *endPointer != '\t' &&