Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -47,17 +47,19 @@ { unsigned char *str = (unsigned char*)str_; bool firstLetter = true; while (*str != '\0') { - if (!isalnum(*str)) { + if (!of_ascii_isalpha(*str)) { firstLetter = true; str++; continue; } - *str = (firstLetter ? toupper(*str) : tolower(*str)); + *str = (firstLetter + ? of_ascii_toupper(*str) + : of_ascii_tolower(*str)); firstLetter = false; str++; } } Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -152,17 +152,19 @@ if (cString == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: strlen([key UTF8String])]; while (*tmp != '\0') { - if (!isalnum(*tmp)) { + if (!of_ascii_isalpha(*tmp)) { firstLetter = true; tmp++; continue; } - *tmp = (firstLetter ? toupper(*tmp) : tolower(*tmp)); + *tmp = (firstLetter + ? of_ascii_toupper(*tmp) + : of_ascii_tolower(*tmp)); firstLetter = false; tmp++; } Index: src/OFIntrospection.m ================================================================== --- src/OFIntrospection.m +++ src/OFIntrospection.m @@ -274,15 +274,12 @@ if ((_attributes & OF_PROPERTY_READWRITE) && _setter == nil) { of_unichar_t first = [_name characterAtIndex: 0]; OFMutableString *tmp = [_name mutableCopy]; _setter = tmp; - if (first < 0x80) { - [tmp setCharacter: toupper((unsigned char)first) - atIndex: 0]; - } - + [tmp setCharacter: of_ascii_toupper(first) + atIndex: 0]; [tmp prependString: @"set"]; [tmp makeImmutable]; } } @catch (id e) { Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -35,25 +35,10 @@ static struct { Class isa; } placeholder; -#ifndef OF_HAVE_UNICODE_TABLES -/* Wrap these, as they can be macros. */ -static int -toupperWrapper(int c) -{ - return toupper(c); -} - -static int -tolowerWrapper(int c) -{ - return tolower(c); -} -#endif - @interface OFMutableString_placeholder: OFMutableString @end @implementation OFMutableString_placeholder - init @@ -295,20 +280,20 @@ } objc_autoreleasePoolPop(pool); } #else -- (void)OF_convertWithWordStartFunction: (int (*)(int))startFunction - wordMiddleFunction: (int (*)(int))middleFunction +- (void)OF_convertWithWordStartFunction: (char (*)(char))startFunction + wordMiddleFunction: (char (*)(char))middleFunction { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = [self characters]; size_t length = [self length]; bool isStart = true; for (size_t i = 0; i < length; i++) { - int (*function)(int) = + char (*function)(char) = (isStart ? startFunction : middleFunction);; of_unichar_t c = characters[i]; if (c <= 0x7F) [self setCharacter: (int)function(c) @@ -482,24 +467,24 @@ wordMiddleTableSize: OF_UNICODE_LOWERCASE_TABLE_SIZE]; } #else - (void)uppercase { - [self OF_convertWithWordStartFunction: toupperWrapper - wordMiddleFunction: toupperWrapper]; + [self OF_convertWithWordStartFunction: of_ascii_toupper + wordMiddleFunction: of_ascii_toupper]; } - (void)lowercase { - [self OF_convertWithWordStartFunction: tolowerWrapper - wordMiddleFunction: tolowerWrapper]; + [self OF_convertWithWordStartFunction: of_ascii_tolower + wordMiddleFunction: of_ascii_tolower]; } - (void)capitalize { - [self OF_convertWithWordStartFunction: toupperWrapper - wordMiddleFunction: tolowerWrapper]; + [self OF_convertWithWordStartFunction: of_ascii_toupper + wordMiddleFunction: of_ascii_tolower]; } #endif - (void)insertString: (OFString*)string atIndex: (size_t)index Index: src/OFObject+KeyValueCoding.m ================================================================== --- src/OFObject+KeyValueCoding.m +++ src/OFObject+KeyValueCoding.m @@ -62,11 +62,11 @@ @try { memcpy(name, "is", 2); memcpy(name + 2, [key UTF8String], keyLength); name[keyLength + 2] = '\0'; - name[2] = toupper((unsigned char)name[2]); + name[2] = of_ascii_toupper(name[2]); selector = sel_registerName(name); } @finally { free(name); } @@ -144,11 +144,11 @@ @try { memcpy(name, "set", 3); memcpy(name + 3, [key UTF8String], keyLength); memcpy(name + keyLength + 3, ":", 2); - name[3] = toupper((unsigned char)name[3]); + name[3] = of_ascii_toupper(name[3]); selector = sel_registerName(name); } @finally { free(name); } Index: src/OFString+URLEncoding.m ================================================================== --- src/OFString+URLEncoding.m +++ src/OFString+URLEncoding.m @@ -57,11 +57,11 @@ /* * '+' is also listed in RFC 1738, however, '+' is sometimes * interpreted as space in HTTP. Therefore always escape it to * make sure it's always interpreted correctly. */ - if (!(c & 0x80) && (isalnum(c) || strchr(allowed, c) != NULL)) + if (of_ascii_isalnum(c) || strchr(allowed, c) != NULL) retCString[i++] = c; else { unsigned char high, low; high = c >> 4; Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -1371,14 +1371,12 @@ if (tc) oc = tc; } #else - if (c <= 0x7F) - c = toupper(c); - if (oc <= 0x7F) - oc = toupper(oc); + c = of_ascii_toupper(c); + oc = of_ascii_toupper(oc); #endif if (c > oc) { objc_autoreleasePoolPop(pool); return OF_ORDERED_DESCENDING; Index: src/OFString_UTF8.m ================================================================== --- src/OFString_UTF8.m +++ src/OFString_UTF8.m @@ -47,14 +47,12 @@ { for (size_t i = 0; i < length; i++) { unsigned char f = first[i]; unsigned char s = second[i]; - if (f <= 0x7F) - f = toupper(f); - if (s <= 0x7F) - s = toupper(s); + f = of_ascii_toupper(f); + s = of_ascii_toupper(s); if (f > s) return OF_ORDERED_DESCENDING; if (f < s) return OF_ORDERED_ASCENDING; @@ -779,11 +777,14 @@ } - (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString { const char *otherCString; - size_t i, j, otherCStringLength, minimumCStringLength; + size_t otherCStringLength, minimumCStringLength; +#ifdef OF_HAVE_UNICODE_TABLES + size_t i, j; +#endif int compare; if (otherString == self) return OF_ORDERED_SAME; @@ -851,16 +852,16 @@ return OF_ORDERED_ASCENDING; i += l1; j += l2; } -#endif if (_s->cStringLength - i > otherCStringLength - j) return OF_ORDERED_DESCENDING; else if (_s->cStringLength - i < otherCStringLength - j) return OF_ORDERED_ASCENDING; +#endif return OF_ORDERED_SAME; } - (uint32_t)hash Index: src/OFURL.m ================================================================== --- src/OFURL.m +++ src/OFURL.m @@ -83,11 +83,11 @@ if ((tmp = strstr(UTF8String, "://")) == NULL) @throw [OFInvalidFormatException exception]; for (tmp2 = UTF8String; tmp2 < tmp; tmp2++) - *tmp2 = tolower((unsigned char)*tmp2); + *tmp2 = of_ascii_tolower(*tmp2); _scheme = [[OFString alloc] initWithUTF8String: UTF8String length: tmp - UTF8String]; Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -607,5 +607,29 @@ volatile unsigned char *buffer = buffer_; while (buffer < (unsigned char*)buffer_ + length) *buffer++ = character; } + +static OF_INLINE bool +of_ascii_isalpha(char c) +{ + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); +} + +static OF_INLINE bool +of_ascii_isalnum(char c) +{ + return (of_ascii_isalpha(c) || (c >= '0' && c <= '9')); +} + +static OF_INLINE char +of_ascii_toupper(char c) +{ + return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c); +} + +static OF_INLINE char +of_ascii_tolower(char c) +{ + return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c); +}