From: Ozan Çağlayan Date: Tue, 19 Apr 2011 05:38:40 +0000 (+0300) Subject: Use locale-unaware methods for case conversion X-Git-Url: https://git.tokkee.org/?p=tig.git;a=commitdiff_plain;h=ab7ff83bde6294f620a49bef3a8f8b617ef435ab;hp=0cd8f8485547a641873db71319da97ddc123b197 Use locale-unaware methods for case conversion Problem: On a tr_TR.UTF-8 locale, adding a key binding to tigrc can not be correctly parsed if the keymap contains 'i' like main, generic, etc. as they are wrongly converted to upper case. In languages like Turkish, 'i' is not converted to 'I' as they're different characters. So one should never use locale-aware conversion methods which will break things in some locales. See: http://www.mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug Signed-off-by: Jonas Fonseca --- diff --git a/tig.h b/tig.h index ef298c7..7baf824 100644 --- a/tig.h +++ b/tig.h @@ -132,6 +132,22 @@ name(type **mem, size_t size, size_t increase) \ #define prefixcmp(str1, str2) \ strncmp(str1, str2, STRING_SIZE(str2)) +static inline int +ascii_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + c &= ~0x20; + return c; +} + +static inline int +ascii_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + c |= 0x20; + return c; +} + static inline int suffixcmp(const char *str, int slen, const char *suffix) { @@ -252,7 +268,7 @@ string_enum_compare(const char *str1, const char *str2, int len) /* Diff-Header == DIFF_HEADER */ for (i = 0; i < len; i++) { - if (toupper(str1[i]) == toupper(str2[i])) + if (ascii_toupper(str1[i]) == ascii_toupper(str2[i])) continue; if (string_enum_sep(str1[i]) && @@ -275,7 +291,7 @@ enum_map_name(const char *name, size_t namelen) int bufpos; for (bufpos = 0; bufpos <= namelen; bufpos++) { - buf[bufpos] = tolower(name[bufpos]); + buf[bufpos] = ascii_tolower(name[bufpos]); if (buf[bufpos] == '_') buf[bufpos] = '-'; }