Code

Use locale-unaware methods for case conversion
authorOzan Çağlayan <ozan@pardus.org.tr>
Tue, 19 Apr 2011 05:38:40 +0000 (08:38 +0300)
committerJonas Fonseca <fonseca@diku.dk>
Tue, 3 May 2011 01:38:44 +0000 (21:38 -0400)
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 <fonseca@diku.dk>
tig.h

diff --git a/tig.h b/tig.h
index ef298c736a1aea2a922e7f92c91499ad2a653826..7baf8241b53680eeb9ad61a7216b125a081ef95f 100644 (file)
--- 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] = '-';
        }