[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

libxkbcommon: Changes to 'debian-unstable'



 NEWS                          |   14 +++++++++++
 configure.ac                  |    8 ------
 debian/changelog              |    7 +++++
 debian/rules                  |    2 -
 src/compose/parser.c          |   48 ++------------------------------------
 src/keysym.c                  |    8 +++---
 src/state.c                   |    2 -
 src/utils.c                   |   53 ++++++++++++++++++++++++++++++++++++++++++
 src/utils.h                   |   17 ++++++++++---
 test/keysym.c                 |   22 +++++++++++++++++
 xkbcommon/xkbcommon-compose.h |    6 +++-
 xkbcommon/xkbcommon.h         |    3 ++
 12 files changed, 127 insertions(+), 63 deletions(-)

New commits:
commit c95f02d38ac9aa458be655bcd997bc67826f972b
Author: Emilio Pozuelo Monfort <pochu@debian.org>
Date:   Wed Jan 18 20:05:35 2017 +0100

    Release to unstable

diff --git a/debian/changelog b/debian/changelog
index 1f1db34..23cb027 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,9 @@
-libxkbcommon (0.7.1-1) UNRELEASED; urgency=medium
+libxkbcommon (0.7.1-1) unstable; urgency=medium
 
   * New upstream release.
   * No need to explicitly enable --parallel, it's the default in compat 10.
 
- -- Emilio Pozuelo Monfort <pochu@debian.org>  Wed, 18 Jan 2017 20:00:40 +0100
+ -- Emilio Pozuelo Monfort <pochu@debian.org>  Wed, 18 Jan 2017 20:05:33 +0100
 
 libxkbcommon (0.7.0-1) unstable; urgency=medium
 

commit 2388b164e2fe38dc080ddb52de34afffa235236f
Author: Emilio Pozuelo Monfort <pochu@debian.org>
Date:   Wed Jan 18 20:04:09 2017 +0100

    No need to explicitly enable --parallel
    
    It's the default in compat 10.

diff --git a/debian/changelog b/debian/changelog
index 7cd5f5e..1f1db34 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 libxkbcommon (0.7.1-1) UNRELEASED; urgency=medium
 
   * New upstream release.
+  * No need to explicitly enable --parallel, it's the default in compat 10.
 
  -- Emilio Pozuelo Monfort <pochu@debian.org>  Wed, 18 Jan 2017 20:00:40 +0100
 
diff --git a/debian/rules b/debian/rules
index 9281c0b..483bdf0 100755
--- a/debian/rules
+++ b/debian/rules
@@ -14,7 +14,7 @@ override_dh_makeshlibs:
 	dh_makeshlibs -- -c4
 
 %:
-	dh $@ --parallel --with quilt
+	dh $@ --with quilt
 
 
 # For maintainer use only, generate a tarball

commit 90cdd38fddd0cef30d0d4c38f939ab2e4806b506
Author: Emilio Pozuelo Monfort <pochu@debian.org>
Date:   Wed Jan 18 20:02:04 2017 +0100

    New upstream release

diff --git a/debian/changelog b/debian/changelog
index 2009af1..7cd5f5e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libxkbcommon (0.7.1-1) UNRELEASED; urgency=medium
+
+  * New upstream release.
+
+ -- Emilio Pozuelo Monfort <pochu@debian.org>  Wed, 18 Jan 2017 20:00:40 +0100
+
 libxkbcommon (0.7.0-1) unstable; urgency=medium
 
   * New upstream release.

commit 877fe59ac362b4e9afb2979b6e0bc837950a1dad
Author: Ran Benita <ran234@gmail.com>
Date:   Wed Jan 18 20:17:46 2017 +0200

    Bump version to 0.7.1
    
    Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/configure.ac b/configure.ac
index 3484c8c..725915b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@ dnl Process this file with autoconf to create configure.
 
 # Initialize Autoconf
 AC_PREREQ([2.62])
-AC_INIT([libxkbcommon], [0.7.0],
+AC_INIT([libxkbcommon], [0.7.1],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=libxkbcommon],
         [libxkbcommon], [http://xkbcommon.org])
 AC_CONFIG_SRCDIR([Makefile.am])

commit 18d53732f291e96f3f66b2d96b8ff8622eac5975
Author: Ran Benita <ran234@gmail.com>
Date:   Wed Jan 18 20:16:15 2017 +0200

    Update NEWS
    
    Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/NEWS b/NEWS
index 27d5c29..7eaeb52 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,17 @@
+libxkbcommon 0.7.1 - 2017-01-18
+==================
+
+- Fixed various reported problems when the current locale is tr_TR.UTF-8.
+
+  The function xkb_keysym_from_name() used to perform case-insensitive
+  string comparisons in a locale-dependent way, but required it to to
+  work as in the C/ASCII locale (the so called "Turkish i problem").
+
+  The function is now no longer affected by the current locale.
+
+- Fixed compilation in NetBSD.
+
+
 libxkbcommon 0.7.0 - 2016-11-11
 ==================
 

commit 47d6e5a8d9a5260a57a51f2620f193b105281133
Author: Ran Benita <ran234@gmail.com>
Date:   Sun Jan 15 18:27:22 2017 +0200

    compose/doc: note that it is safe to pass the result of getenv() as locale
    
    See the NOTES section of getenv(3). Somewhat obscure but it doesn't hurt
    to reassure the readers who know about this.
    
    Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/xkbcommon/xkbcommon-compose.h b/xkbcommon/xkbcommon-compose.h
index 7414c37..81b0d3f 100644
--- a/xkbcommon/xkbcommon-compose.h
+++ b/xkbcommon/xkbcommon-compose.h
@@ -211,7 +211,11 @@ enum xkb_compose_format {
  * @param context
  *     The library context in which to create the compose table.
  * @param locale
- *     The current locale.  See @ref compose-locale.
+ *     The current locale.  See @ref compose-locale.\n
+ *
+ *     The value is copied, so it is safe to pass the result of getenv(3)
+ *     (or similar) without fear of it being invalidated by a subsequent
+ *     setenv(3) (or similar).
  * @param flags
  *     Optional flags for the compose table, or 0.
  *

commit 1ec14d0996c9a6679a5fc27aac4682727a71c4ed
Author: Ran Benita <ran234@gmail.com>
Date:   Fri Dec 2 22:46:53 2016 +0200

    compose: remove the keysym_from_name cache
    
    The hit rate is high, but either the cache is slow or the function is
    not fast enough -- the cache no longer holds its weight, leading only to
    very modest improvements. If it's the former, it can definitely be
    improved, the code is very dumb (though it worked just as well as any
    other I tried back then). But instead, let's just kill it.
    
    Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/compose/parser.c b/src/compose/parser.c
index 763d29e..fd2dca9 100644
--- a/src/compose/parser.c
+++ b/src/compose/parser.c
@@ -64,45 +64,6 @@ OR PERFORMANCE OF THIS SOFTWARE.
 #define MAX_LHS_LEN 10
 #define MAX_INCLUDE_DEPTH 5
 
-#define KEYSYM_FROM_NAME_CACHE_SIZE 8
-
-/*
- * xkb_keysym_from_name() is fairly slow, because for internal reasons
- * it must use strcasecmp().
- * A small cache reduces about 20% from the compilation time of
- * en_US.UTF-8/Compose.
- */
-struct keysym_from_name_cache {
-    struct {
-        char name[64];
-        unsigned len;
-        xkb_keysym_t keysym;
-    } cache[KEYSYM_FROM_NAME_CACHE_SIZE];
-    unsigned next;
-};
-
-static xkb_keysym_t
-cached_keysym_from_name(struct keysym_from_name_cache *cache,
-                        const char *name, size_t len)
-{
-    xkb_keysym_t keysym;
-
-    if (len >= sizeof(cache->cache[0].name))
-        return XKB_KEY_NoSymbol;
-
-    for (unsigned i = 0; i < KEYSYM_FROM_NAME_CACHE_SIZE; i++)
-        if (cache->cache[i].len == len &&
-            memcmp(cache->cache[i].name, name, len) == 0)
-            return cache->cache[i].keysym;
-
-    keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
-    strcpy(cache->cache[cache->next].name, name);
-    cache->cache[cache->next].len = len;
-    cache->cache[cache->next].keysym = keysym;
-    cache->next = (cache->next + 1) % KEYSYM_FROM_NAME_CACHE_SIZE;
-    return keysym;
-}
-
 /*
  * Grammar adapted from libX11/modules/im/ximcp/imLcPrs.c.
  * See also the XCompose(5) manpage.
@@ -536,7 +497,6 @@ parse(struct xkb_compose_table *table, struct scanner *s,
 {
     enum rules_token tok;
     union lvalue val;
-    struct keysym_from_name_cache *cache = s->priv;
     xkb_keysym_t keysym;
     struct production production;
     enum { MAX_ERRORS = 10 };
@@ -612,7 +572,7 @@ lhs_keysym:
 lhs_keysym_tok:
     switch (tok) {
     case TOK_LHS_KEYSYM:
-        keysym = cached_keysym_from_name(cache, val.string.str, val.string.len);
+        keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS);
         if (keysym == XKB_KEY_NoSymbol) {
             scanner_err(s, "unrecognized keysym \"%s\" on left-hand side",
                         val.string.str);
@@ -683,7 +643,7 @@ rhs:
         production.has_string = true;
         goto rhs;
     case TOK_IDENT:
-        keysym = cached_keysym_from_name(cache, val.string.str, val.string.len);
+        keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS);
         if (keysym == XKB_KEY_NoSymbol) {
             scanner_err(s, "unrecognized keysym \"%s\" on right-hand side",
                         val.string.str);
@@ -735,9 +695,7 @@ parse_string(struct xkb_compose_table *table, const char *string, size_t len,
              const char *file_name)
 {
     struct scanner s;
-    struct keysym_from_name_cache cache;
-    memset(&cache, 0, sizeof(cache));
-    scanner_init(&s, table->ctx, string, len, file_name, &cache);
+    scanner_init(&s, table->ctx, string, len, file_name, NULL);
     if (!parse(table, &s, 0))
         return false;
     /* Maybe the allocator can use the excess space. */

commit 7984a30bbc3c659724243b7e4656dcc68fe17abe
Author: Ran Benita <ran234@gmail.com>
Date:   Fri Dec 2 23:55:19 2016 +0200

    doc: note that XKB_KEYSYM_CASE_INSENSITIVE does C folding only
    
    and not locale-dependent.
    
    Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/xkbcommon/xkbcommon.h b/xkbcommon/xkbcommon.h
index 4902dc4..8b05835 100644
--- a/xkbcommon/xkbcommon.h
+++ b/xkbcommon/xkbcommon.h
@@ -449,6 +449,9 @@ enum xkb_keysym_flags {
  * fails, only then to try with this flag, while possibly warning the user
  * he had misspelled the name, and might get wrong results.
  *
+ * Case folding is done according to the C locale; the current locale is not
+ * consulted.
+ *
  * @returns The keysym. If the name is invalid, returns XKB_KEY_NoSymbol.
  *
  * @sa xkb_keysym_t

commit b5586a6c4294b46eb23d1fc527ff63dcd27e23ac
Author: Ran Benita <ran234@gmail.com>
Date:   Fri Dec 2 22:15:19 2016 +0200

    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>

diff --git a/configure.ac b/configure.ac
index fdab4ab..3484c8c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,12 +68,6 @@ AS_IF([test ! -f "src/xkbcomp/parser.c" -a "x$YACC_INST" = x], [
 ])
 
 # Checks for library functions.
-AC_CHECK_FUNCS([strcasecmp strncasecmp])
-AS_IF([test "x$ac_cv_func_strcasecmp" = xno -o \
-            "x$ac_cv_func_strncasecmp" = xno], [
-    AC_MSG_ERROR([C library does not support strcasecmp/strncasecmp])
-])
-
 AC_CHECK_FUNCS([eaccess euidaccess mmap])
 
 AC_CHECK_FUNCS([secure_getenv __secure_getenv])
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;
diff --git a/src/utils.c b/src/utils.c
index d725bbd..a71b570 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -108,3 +108,56 @@ unmap_file(char *str, size_t size)
 }
 
 #endif
+
+// ASCII lower-case map.
+static const unsigned char lower_map[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+    40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+    59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+    108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+    91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+    108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+    123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
+    138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
+    153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
+    168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
+    183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
+    198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
+    213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
+    228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+    243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+// ASCII tolower (to avoid locale issues).
+char
+to_lower(char c)
+{
+    return (char) lower_map[(unsigned char) c];
+}
+
+// ASCII strcasecmp (to avoid locale issues).
+int
+istrcmp(const char *a, const char *b)
+{
+    for (size_t i = 0; ; i++) {
+        if (to_lower(a[i]) != to_lower(b[i]))
+            return (int) to_lower(a[i]) - (int) to_lower(b[i]);
+        if (!a[i])
+            break;
+    }
+    return 0;
+}
+
+// ASCII strncasecmp (to avoid locale issues).
+int
+istrncmp(const char *a, const char *b, size_t n)
+{
+    for (size_t i = 0; i < n; i++) {
+        if (to_lower(a[i]) != to_lower(b[i]))
+            return (int) to_lower(a[i]) - (int) to_lower(b[i]);
+        if (!a[i])
+            break;
+    }
+    return 0;
+}
diff --git a/src/utils.h b/src/utils.h
index d63d23a..cb98e8e 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -29,7 +29,6 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
-#include <strings.h>
 
 #include "darray.h"
 
@@ -44,6 +43,15 @@
     switch (0) { case 0: case (expr): ; } \
 } while (0)
 
+char
+to_lower(char c);
+
+int
+istrcmp(const char *a, const char *b);
+
+int
+istrncmp(const char *a, const char *b, size_t n);
+
 static inline bool
 streq(const char *s1, const char *s2)
 {
@@ -61,13 +69,13 @@ streq_not_null(const char *s1, const char *s2)
 static inline bool
 istreq(const char *s1, const char *s2)
 {
-    return strcasecmp(s1, s2) == 0;
+    return istrcmp(s1, s2) == 0;
 }
 
 static inline bool
 istreq_prefix(const char *s1, const char *s2)
 {
-    return strncasecmp(s1, s2, strlen(s1)) == 0;
+    return istrncmp(s1, s2, strlen(s1)) == 0;
 }
 
 static inline char *
diff --git a/test/keysym.c b/test/keysym.c
index 439622c..4414523 100644
--- a/test/keysym.c
+++ b/test/keysym.c
@@ -20,6 +20,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+#include <locale.h>
 
 #include "test.h"
 #include "keysym.h" /* For unexported is_lower/upper/keypad() */
@@ -81,6 +82,25 @@ test_utf8(xkb_keysym_t keysym, const char *expected)
     return streq(s, expected);
 }
 
+static void
+test_github_issue_42(void)
+{
+    // Verify we are not dependent on locale, Turkish-i problem in particular.
+    if (setlocale(LC_CTYPE, "tr_TR.UTF-8") == NULL) {
+        // The locale is not available, probably; skip.
+        return;
+    }
+
+    assert(test_string("i", XKB_KEY_i));
+    assert(test_string("I", XKB_KEY_I));
+    assert(test_casestring("i", XKB_KEY_i));
+    assert(test_casestring("I", XKB_KEY_i));
+    assert(xkb_keysym_to_upper(XKB_KEY_i) == XKB_KEY_I);
+    assert(xkb_keysym_to_lower(XKB_KEY_I) == XKB_KEY_i);
+
+    setlocale(LC_CTYPE, "C");
+}
+
 int
 main(void)
 {
@@ -196,5 +216,7 @@ main(void)
     assert(xkb_keysym_to_upper(XKB_KEY_eacute) == XKB_KEY_Eacute);
     assert(xkb_keysym_to_lower(XKB_KEY_Eacute) == XKB_KEY_eacute);
 
+    test_github_issue_42();
+
     return 0;
 }

commit 327364d277609600aa19aabd6dc55f2fc7dfb8cf
Author: Ran Benita <ran234@gmail.com>
Date:   Mon Nov 14 17:37:35 2016 +0200

    utils: rename popcount to avoid conflict in NetBSD
    
    Resolves https://github.com/xkbcommon/libxkbcommon/issues/41
    Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/state.c b/src/state.c
index 039115a..00495f7 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1359,7 +1359,7 @@ key_get_consumed(struct xkb_state *state, const struct xkb_key *key,
             if (XkbLevelsSameSyms(level, no_mods_level))
                 continue;
 
-            if (entry == matching_entry || popcount(entry->mods.mask) == 1)
+            if (entry == matching_entry || my_popcount(entry->mods.mask) == 1)
                 consumed |= entry->mods.mask & ~entry->preserve.mask;
         }
         break;
diff --git a/src/utils.h b/src/utils.h
index 11ef735..d63d23a 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -178,8 +178,9 @@ msb_pos(uint32_t mask)
     return pos;
 }
 
+// Avoid conflict with other popcount()s.
 static inline int
-popcount(uint32_t x)
+my_popcount(uint32_t x)
 {
     int count;
 #if defined(HAVE___BUILTIN_POPCOUNT)


Reply to: