summaryrefslogtreecommitdiff
path: root/src/keysym.c
diff options
context:
space:
mode:
authorRan Benita <ran234@gmail.com>2016-12-02 22:15:19 +0200
committerRan Benita <ran234@gmail.com>2016-12-02 23:46:56 +0200
commitb5586a6c4294b46eb23d1fc527ff63dcd27e23ac (patch)
treea567b29fe33c258006e6ec9b4d51a9acda4d0514 /src/keysym.c
parent327364d277609600aa19aabd6dc55f2fc7dfb8cf (diff)
downloadxorg-lib-libxkbcommon-b5586a6c4294b46eb23d1fc527ff63dcd27e23ac.tar.gz
keysym: fix locale dependence in xkb_keysym_from_name()
We currently use strcasecmp, which is locale-dependent. In particular, one well-known surprise even if restricted just ASCII input is found in the tr_TR (Turkish) locale, see e.g. https://msdn.microsoft.com/en-us/library/ms973919.aspx#stringsinnet20_topic5 We have known to avoid locale-dependent functions before, but in this case, we forgot. Fix it by implementing our own simple ASCII-only strcasecmp/strncasecmp. Might have been possible to use strcasecmp_l() with the C locale, but went the easy route. Side advantage is that even this non-optimized version is faster than the optimized libc one (__strcasecmp_l_sse42) since it doesn't need to do the locale stuff. xkb_keysym_from_name(), which uses strcasecmp heavily, becomes faster, and so for example Compose file parsing, which uses xkb_keysym_from_name() heavily, becomes ~20% faster. Resolves https://github.com/xkbcommon/libxkbcommon/issues/42 Signed-off-by: Ran Benita <ran234@gmail.com>
Diffstat (limited to 'src/keysym.c')
-rw-r--r--src/keysym.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/keysym.c b/src/keysym.c
index db0e973..9e7b4fb 100644
--- a/src/keysym.c
+++ b/src/keysym.c
@@ -76,7 +76,7 @@ compare_by_name(const void *a, const void *b)
{
const char *key = a;
const struct name_keysym *entry = b;
- return strcasecmp(key, get_name(entry));
+ return istrcmp(key, get_name(entry));
}
XKB_EXPORT int
@@ -109,7 +109,7 @@ xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
/*
* Find the correct keysym if one case-insensitive match is given.
*
- * The name_to_keysym table is sorted by strcasecmp(). So bsearch() may return
+ * The name_to_keysym table is sorted by istrcmp(). So bsearch() may return
* _any_ of all possible case-insensitive duplicates. This function searches the
* returned entry @entry, all previous and all next entries that match by
* case-insensitive comparison and returns the exact match to @name. If @icase
@@ -138,7 +138,7 @@ find_sym(const struct name_keysym *entry, const char *name, bool icase)
for (iter = entry - 1; iter >= name_to_keysym; --iter) {
if (!icase && strcmp(get_name(iter), name) == 0)
return iter;
- if (strcasecmp(get_name(iter), get_name(entry)) != 0)
+ if (istrcmp(get_name(iter), get_name(entry)) != 0)
break;
if (icase && xkb_keysym_is_lower(iter->keysym))
return iter;
@@ -148,7 +148,7 @@ find_sym(const struct name_keysym *entry, const char *name, bool icase)
for (iter = entry + 1; iter < last; ++iter) {
if (!icase && strcmp(get_name(iter), name) == 0)
return iter;
- if (strcasecmp(get_name(iter), get_name(entry)) != 0)
+ if (istrcmp(get_name(iter), get_name(entry)) != 0)
break;
if (icase && xkb_keysym_is_lower(iter->keysym))
return iter;