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

libxkbcommon: Changes to 'upstream-unstable'



 Makefile.am                        |   72 
 README                             |   17 
 configure.ac                       |   45 
 doc/Doxyfile.in                    |  126 -
 src/context.c                      |   85 
 src/context.h                      |   28 
 src/darray.h                       |    6 
 src/keymap-dump.c                  |  688 ------
 src/keymap.c                       |  248 ++
 src/keymap.h                       |   55 
 src/keysym-utf.c                   |   39 
 src/keysym.c                       |    8 
 src/list.h                         |  489 ----
 src/state.c                        |  302 +-
 src/text.c                         |  238 +-
 src/text.h                         |    2 
 src/utils.c                        |  107 +
 src/utils.h                        |   20 
 src/xkbcomp/.gitignore             |    1 
 src/xkbcomp/action.c               |   34 
 src/xkbcomp/ast-build.c            |  242 +-
 src/xkbcomp/ast-build.h            |    8 
 src/xkbcomp/ast.h                  |    9 
 src/xkbcomp/compat.c               |  308 +-
 src/xkbcomp/include.c              |   48 
 src/xkbcomp/include.h              |    5 
 src/xkbcomp/keycodes.c             |  531 ++---
 src/xkbcomp/keycodes.h             |   37 
 src/xkbcomp/keymap-dump.c          |  669 ++++++
 src/xkbcomp/keymap.c               |   16 
 src/xkbcomp/keywords.c             |  349 +++
 src/xkbcomp/keywords.gperf         |   79 
 src/xkbcomp/parser-priv.h          |   14 
 src/xkbcomp/parser.y               |   34 
 src/xkbcomp/rules.c                |  138 -
 src/xkbcomp/scanner-utils.h        |  148 +
 src/xkbcomp/scanner.c              |  205 +
 src/xkbcomp/scanner.l              |  291 --
 src/xkbcomp/symbols.c              |  145 -
 src/xkbcomp/types.c                |  153 -
 src/xkbcomp/xkbcomp-priv.h         |   22 
 src/xkbcomp/xkbcomp.c              |  144 -
 test/.gitignore                    |    2 
 test/bench-key-proc.c              |   95 
 test/buffercomp.c                  |   90 
 test/common.c                      |  149 +
 test/context.c                     |    2 
 test/data/compat/default           |   12 
 test/data/compat/iso9995           |    4 
 test/data/keymaps/stringcomp.data  | 3817 ++++++++++++++++++-------------------
 test/data/keymaps/unbound-vmod.xkb | 1533 ++++++++++++++
 test/data/rules/base               |   75 
 test/data/rules/evdev              |   81 
 test/data/symbols/altwin           |   13 
 test/data/symbols/ca               |    5 
 test/data/symbols/de               |   36 
 test/data/symbols/il               |   80 
 test/data/symbols/in               |   75 
 test/data/symbols/inet             |    2 
 test/data/symbols/keypad           |   11 
 test/data/symbols/latin            |    2 
 test/data/symbols/level3           |   42 
 test/data/symbols/level5           |   26 
 test/data/symbols/pc               |    2 
 test/data/symbols/ru               |   13 
 test/data/symbols/rupeesign        |    5 
 test/data/symbols/us               |  163 +
 test/data/sync.sh                  |   63 
 test/data/types/level5             |    1 
 test/data/types/pc                 |    8 
 test/filecomp.c                    |   11 
 test/interactive.c                 |   24 
 test/keyseq.c                      |  196 -
 test/keysym.c                      |   21 
 test/log.c                         |    2 
 test/print-compiled-keymap.c       |    2 
 test/rmlvo-to-kccgst.c             |   15 
 test/rules-file.c                  |    2 
 test/rulescomp.c                   |  170 +
 test/state.c                       |   30 
 test/stringcomp.c                  |   12 
 test/test.h                        |   31 
 xkbcommon/xkbcommon.h              |  261 +-
 83 files changed, 8087 insertions(+), 5302 deletions(-)

New commits:
commit 9f01bd1e7281bdc07dec1109384ab1030f72425e
Author: Daniel Stone <daniel@fooishbar.org>
Date:   Mon Jun 3 16:43:43 2013 +0100

    Bump version to 0.3.1
    
    Signed-off-by: Daniel Stone <daniel@fooishbar.org>

diff --git a/configure.ac b/configure.ac
index 2806a2c..bc3f1a0 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.3.0],
+AC_INIT([libxkbcommon], [0.3.1],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=libxkbcommon],
         [libxkbcommon], [http://xkbcommon.org])
 AC_CONFIG_SRCDIR([Makefile.am])

commit b06de3072b46a5108878b8e00f934f01fdb6a0ff
Author: Matthias Clasen <mclasen@redhat.com>
Date:   Thu May 9 15:31:21 2013 +0100

    Add keycode min/max and iteration API
    
    Add three new pieces of API:
      - xkb_keymap_min_keycode does what it says on the tin
      - xkb_keymap_max_keycode likewise
      - xkb_keymap_key_for_each calls the provided function once for every
        valid key in the keymap
    
    Signed-off-by: Daniel Stone <daniel@fooishbar.org>

diff --git a/src/keymap.c b/src/keymap.c
index 55000f4..8205bab 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -484,6 +484,28 @@ err:
     return 0;
 }
 
+XKB_EXPORT xkb_keycode_t
+xkb_keymap_min_keycode(struct xkb_keymap *keymap)
+{
+    return keymap->min_key_code;
+}
+
+XKB_EXPORT xkb_keycode_t
+xkb_keymap_max_keycode(struct xkb_keymap *keymap)
+{
+    return keymap->max_key_code;
+}
+
+XKB_EXPORT void
+xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
+                        void *data)
+{
+    struct xkb_key *key;
+
+    xkb_foreach_key(key, keymap)
+        iter(keymap, key->keycode, data);
+}
+
 /**
  * Simple boolean specifying whether or not the key should repeat.
  */
diff --git a/test/state.c b/test/state.c
index 34da201..3521d66 100644
--- a/test/state.c
+++ b/test/state.c
@@ -331,6 +331,28 @@ test_consume(struct xkb_keymap *keymap)
     xkb_state_unref(state);
 }
 
+static void
+key_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
+{
+    int *counter = (int *) data;
+
+    assert(*counter == key);
+    (*counter)++;
+}
+
+static void
+test_range(struct xkb_keymap *keymap)
+{
+    int counter;
+
+    assert(xkb_keymap_min_keycode(keymap) == 9);
+    assert(xkb_keymap_max_keycode(keymap) == 253);
+
+    counter = xkb_keymap_min_keycode(keymap);
+    xkb_keymap_key_for_each(keymap, key_iter, &counter);
+    assert(counter == xkb_keymap_max_keycode(keymap) + 1);
+}
+
 int
 main(void)
 {
@@ -351,6 +373,7 @@ main(void)
     test_serialisation(keymap);
     test_repeat(keymap);
     test_consume(keymap);
+    test_range(keymap);
 
     xkb_keymap_unref(keymap);
     xkb_context_unref(context);
diff --git a/xkbcommon/xkbcommon.h b/xkbcommon/xkbcommon.h
index a2aecfb..ff2ce68 100644
--- a/xkbcommon/xkbcommon.h
+++ b/xkbcommon/xkbcommon.h
@@ -812,6 +812,46 @@ xkb_keymap_get_as_string(struct xkb_keymap *keymap,
  */
 
 /**
+ * Get the minimum keycode in the keymap.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ */
+xkb_keycode_t
+xkb_keymap_min_keycode(struct xkb_keymap *keymap);
+
+/**
+ * Get the maximum keycode in the keymap.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ */
+xkb_keycode_t
+xkb_keymap_max_keycode(struct xkb_keymap *keymap);
+
+/**
+ * The iterator used by xkb_keymap_key_for_each().
+ *
+ * @sa xkb_keymap_key_for_each
+ * @memberof xkb_keymap
+ */
+typedef void
+(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key,
+                         void *data);
+
+/**
+ * Run a specified function for every valid keycode in the keymap.  If a
+ * keymap is sparse, this function may be called fewer than
+ * (max_keycode - min_keycode + 1) times.
+ *
+ * @sa xkb_keymap_min_keycode() xkb_keymap_max_keycode() xkb_keycode_t
+ * @memberof xkb_keymap
+ */
+void
+xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
+                        void *data);
+
+/**
  * Get the number of modifiers in the keymap.
  *
  * @sa xkb_mod_index_t

commit 17a956d80781846903c90b7bd4beaf8ac7aac40c
Author: Daniel Stone <daniel@fooishbar.org>
Date:   Thu May 9 14:47:09 2013 +0100

    Widen keycode range to 8/255 if possible (bug #63390)
    
    If the keycode range is smaller than 8 → 255, artifically widen it when
    dumping the keymap as not to displease X.
    
    Signed-off-by: Daniel Stone <daniel@fooishbar.org>

diff --git a/src/utils.h b/src/utils.h
index 160bc42..eca6368 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -93,6 +93,18 @@ memdup(const void *mem, size_t nmemb, size_t size)
     return p;
 }
 
+static inline int
+min(int misc, int other)
+{
+    return (misc < other) ? misc : other;
+}
+
+static inline int
+max(int misc, int other)
+{
+    return (misc > other) ? misc : other;
+}
+
 bool
 map_file(FILE *file, const char **string_out, size_t *size_out);
 
diff --git a/src/xkbcomp/keymap-dump.c b/src/xkbcomp/keymap-dump.c
index 034a8c1..0933873 100644
--- a/src/xkbcomp/keymap-dump.c
+++ b/src/xkbcomp/keymap-dump.c
@@ -157,6 +157,13 @@ write_keycodes(struct xkb_keymap *keymap, struct buf *buf)
     else
         write_buf(buf, "xkb_keycodes {\n");
 
+    /* xkbcomp and X11 really want to see keymaps with a minimum of 8, and
+     * a maximum of at least 255, else XWayland really starts hating life.
+     * If this is a problem and people really need strictly bounded keymaps,
+     * we should probably control this with a flag. */
+    write_buf(buf, "\tminimum = %d;\n", min(keymap->min_key_code, 8));
+    write_buf(buf, "\tmaximum = %d;\n", max(keymap->max_key_code, 255));
+
     xkb_foreach_key(key, keymap) {
         if (key->name == XKB_ATOM_NONE)
             continue;
diff --git a/test/data/keymaps/stringcomp.data b/test/data/keymaps/stringcomp.data
index 7d21eb5..8f80fcc 100644
--- a/test/data/keymaps/stringcomp.data
+++ b/test/data/keymaps/stringcomp.data
@@ -1,5 +1,7 @@
 xkb_keymap {
 xkb_keycodes "evdev_aliases(qwerty)" {
+	minimum = 8;
+	maximum = 255;
 	<ESC>                = 9;
 	<AE01>               = 10;
 	<AE02>               = 11;

commit a392d2682bfbf5ce6c3ee153c6a08bb456da0660
Author: Ran Benita <ran234@gmail.com>
Date:   Sun Aug 12 11:40:02 2012 +0300

    Replace flex scanner with a hand-written one
    
    The scanner is very similar in structure to the one in xkbcomp/rules.c.
    It avoids copying and has nicer error reporting.
    
    It uses gperf to generate a hashtable for the keywords, which gives a
    nice speed boost (compared to the naive strcasecmp method at least). But
    since there's hardly a reason to regenerate it every time and require
    people to install gperf, the output (keywords.c) is added here as well.
    
    Here are some stats from test/rulescomp:
    
    Before:
    compiled 1000 keymaps in 4.052939625s
    ==22063==   total heap usage: 101,101 allocs, 101,101 frees, 11,840,834 bytes allocated
    
    After:
    compiled 1000 keymaps in 3.519665434s
    ==26505==   total heap usage: 99,945 allocs, 99,945 frees, 7,033,608 bytes allocated
    
    Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/Makefile.am b/Makefile.am
index 0d43f39..98cabc1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,11 +38,12 @@ libxkbcommon_la_SOURCES = \
 	src/xkbcomp/keycodes.c \
 	src/xkbcomp/keymap.c \
 	src/xkbcomp/keymap-dump.c \
+	src/xkbcomp/keywords.c \
 	src/xkbcomp/parser.y \
 	src/xkbcomp/parser-priv.h \
 	src/xkbcomp/rules.c \
 	src/xkbcomp/rules.h \
-	src/xkbcomp/scanner.l \
+	src/xkbcomp/scanner.c \
 	src/xkbcomp/scanner-utils.h \
 	src/xkbcomp/symbols.c \
 	src/xkbcomp/types.c \
@@ -70,13 +71,11 @@ libxkbcommon_la_SOURCES = \
 
 BUILT_SOURCES = \
 	src/xkbcomp/parser.c \
-	src/xkbcomp/parser.h \
-	src/xkbcomp/scanner.c
+	src/xkbcomp/parser.h
 CLEANFILES = $(BUILT_SOURCES)
 
 src/xkbcomp/parser.c: $(top_builddir)/src/$(am__dirstamp) $(top_builddir)/src/xkbcomp/$(am__dirstamp)
 src/xkbcomp/parser.h: $(top_builddir)/src/$(am__dirstamp) $(top_builddir)/src/xkbcomp/$(am__dirstamp)
-src/xkbcomp/scanner.c: $(top_builddir)/src/$(am__dirstamp) $(top_builddir)/src/xkbcomp/$(am__dirstamp)
 
 # Documentation
 
@@ -171,7 +170,6 @@ EXTRA_DIST = \
 # removes #define _OSF_Keysyms and such.  The XK_Ydiaeresis case is to
 # handle a duplicate definition in HPkeysyms.h which kicks in if it's
 # not already defined.
-
 X11_INCLUDEDIR = /usr/include/X11
 KEYSYMDEFS = \
 	 $(X11_INCLUDEDIR)/keysymdef.h \
@@ -191,6 +189,11 @@ update-keysyms:
 	echo -en '/* This file is autogenerated from Makefile.am; please do not commit directly. */\n\n' > $(top_srcdir)/src/ks_tables.h
 	LC_CTYPE=C python $(top_srcdir)/makekeys.py $(top_srcdir)/xkbcommon/xkbcommon-keysyms.h >> $(top_srcdir)/src/ks_tables.h
 
+# Run this if you add/remove a new keyword to the xkbcomp scanner,
+# or just want to regenerate the gperf file.
+update-keywords:
+	$(AM_V_GEN)gperf < $(top_srcdir)/src/xkbcomp/keywords.gperf > $(top_srcdir)/src/xkbcomp/keywords.c
+
 # Android stuff
 
 Android_build.mk: Makefile $(BUILT_SOURCES)
diff --git a/configure.ac b/configure.ac
index ec829cd..2806a2c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,7 +54,7 @@ AC_C_INLINE
 # Check for programs
 AC_PROG_MKDIR_P
 PKG_PROG_PKG_CONFIG
-AC_PROG_LEX
+
 AC_PROG_YACC
 AC_PATH_PROG([YACC_INST], $YACC)
 if test ! -f "src/xkbcomp/parser.c"; then
diff --git a/src/keymap.c b/src/keymap.c
index 3df183a..55000f4 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -190,35 +190,7 @@ xkb_keymap_new_from_string(struct xkb_context *ctx,
                            enum xkb_keymap_format format,
                            enum xkb_keymap_compile_flags flags)
 {
-    struct xkb_keymap *keymap;
-    const struct xkb_keymap_format_ops *ops;
-
-    ops = get_keymap_format_ops(format);
-    if (!ops || !ops->keymap_new_from_string) {
-        log_err_func(ctx, "unsupported keymap format: %d\n", format);
-        return NULL;
-    }
-
-    if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
-        log_err_func(ctx, "unrecognized flags: %#x\n", flags);
-        return NULL;
-    }
-
-    if (!string) {
-        log_err_func1(ctx, "no string specified\n");
-        return NULL;
-    }
-
-    keymap = xkb_keymap_new(ctx, format, flags);
-    if (!keymap)
-        return NULL;
-
-    if (!ops->keymap_new_from_string(keymap, string)) {
-        xkb_keymap_unref(keymap);
-        return NULL;
-    }
-
-    return keymap;
+    return xkb_keymap_new_from_buffer(ctx, string, SIZE_MAX, format, flags);
 }
 
 XKB_EXPORT struct xkb_keymap *
@@ -250,7 +222,7 @@ xkb_keymap_new_from_buffer(struct xkb_context *ctx,
     if (!keymap)
         return NULL;
 
-    if (!ops->keymap_new_from_buffer(keymap, buffer, length)) {
+    if (!ops->keymap_new_from_string(keymap, buffer, length)) {
         xkb_keymap_unref(keymap);
         return NULL;
     }
diff --git a/src/keymap.h b/src/keymap.h
index c6b884d..7d51184 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -439,9 +439,7 @@ struct xkb_keymap_format_ops {
     bool (*keymap_new_from_names)(struct xkb_keymap *keymap,
                                   const struct xkb_rule_names *names);
     bool (*keymap_new_from_string)(struct xkb_keymap *keymap,
-                                   const char *string);
-    bool (*keymap_new_from_buffer)(struct xkb_keymap *keymap,
-                                   const char *buffer, size_t length);
+                                   const char *string, size_t length);
     bool (*keymap_new_from_file)(struct xkb_keymap *keymap, FILE *file);
     char *(*keymap_get_as_string)(struct xkb_keymap *keymap);
 };
diff --git a/src/xkbcomp/.gitignore b/src/xkbcomp/.gitignore
index 2081535..d7814e4 100644
--- a/src/xkbcomp/.gitignore
+++ b/src/xkbcomp/.gitignore
@@ -1,3 +1,2 @@
 parser.c
 parser.h
-scanner.c
diff --git a/src/xkbcomp/keywords.c b/src/xkbcomp/keywords.c
new file mode 100644
index 0000000..dba7086
--- /dev/null
+++ b/src/xkbcomp/keywords.c
@@ -0,0 +1,349 @@
+/* ANSI-C code produced by gperf version 3.0.4 */
+/* Command-line: gperf  */
+/* Computed positions: -k'1-2,5' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+
+#include "xkbcomp-priv.h"
+#include "parser-priv.h"
+
+static unsigned int
+keyword_gperf_hash(const char *str, unsigned int len);
+
+static const struct keyword_tok *
+keyword_gperf_lookup(const char *str, unsigned int len);
+struct keyword_tok { int name; enum yytokentype tok; };
+#include <string.h>
+/* maximum key range = 70, duplicates = 0 */
+
+#ifndef GPERF_DOWNCASE
+#define GPERF_DOWNCASE 1
+static unsigned char gperf_downcase[256] =
+  {
+      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
+  };
+#endif
+
+#ifndef GPERF_CASE_STRCMP
+#define GPERF_CASE_STRCMP 1
+static int
+gperf_case_strcmp (register const char *s1, register const char *s2)
+{
+  for (;;)
+    {
+      unsigned char c1 = gperf_downcase[(unsigned char)*s1++];
+      unsigned char c2 = gperf_downcase[(unsigned char)*s2++];
+      if (c1 != 0 && c1 == c2)
+        continue;
+      return (int)c1 - (int)c2;
+    }
+}
+#endif
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+keyword_gperf_hash (register const char *str, register unsigned int len)
+{
+  static const unsigned char asso_values[] =
+    {
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73,  0, 73,  5, 36,  0,
+      10,  1, 15, 15, 73,  0, 10, 20, 35, 20,
+      50, 73, 10, 10,  5,  0, 15, 73,  0, 15,
+      73, 73, 73, 73, 73, 73, 73,  0, 73,  5,
+      36,  0, 10,  1, 15, 15, 73,  0, 10, 20,
+      35, 20, 50, 73, 10, 10,  5,  0, 15, 73,
+       0, 15, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+      73, 73, 73, 73, 73, 73
+    };
+  register int hval = len;
+
+  switch (hval)
+    {
+      default:
+        hval += asso_values[(unsigned char)str[4]];
+      /*FALLTHROUGH*/
+      case 4:
+      case 3:
+      case 2:
+        hval += asso_values[(unsigned char)str[1]];
+      /*FALLTHROUGH*/
+      case 1:
+        hval += asso_values[(unsigned char)str[0]];
+        break;
+    }
+  return hval;
+}
+
+struct stringpool_t
+  {
+    char stringpool_str3[sizeof("key")];
+    char stringpool_str4[sizeof("keys")];
+    char stringpool_str7[sizeof("augment")];
+    char stringpool_str9[sizeof("text")];
+    char stringpool_str10[sizeof("xkb_keymap")];
+    char stringpool_str11[sizeof("keypad_keys")];
+    char stringpool_str12[sizeof("xkb_keycodes")];
+    char stringpool_str13[sizeof("xkb_geometry")];
+    char stringpool_str14[sizeof("xkb_types")];
+    char stringpool_str15[sizeof("xkb_compat")];
+    char stringpool_str17[sizeof("replace")];
+    char stringpool_str19[sizeof("xkb_compat_map")];
+    char stringpool_str20[sizeof("xkb_layout")];
+    char stringpool_str21[sizeof("xkb_symbols")];
+    char stringpool_str22[sizeof("xkb_compatibility")];
+    char stringpool_str23[sizeof("xkb_semantics")];
+    char stringpool_str24[sizeof("type")];
+    char stringpool_str25[sizeof("alias")];
+    char stringpool_str26[sizeof("xkb_compatibility_map")];
+    char stringpool_str27[sizeof("alphanumeric_keys")];
+    char stringpool_str28[sizeof("function_keys")];
+    char stringpool_str29[sizeof("alternate")];
+    char stringpool_str30[sizeof("shape")];
+    char stringpool_str31[sizeof("action")];
+    char stringpool_str32[sizeof("section")];
+    char stringpool_str33[sizeof("row")];
+    char stringpool_str34[sizeof("logo")];
+    char stringpool_str35[sizeof("alternate_group")];
+    char stringpool_str36[sizeof("hidden")];
+    char stringpool_str37[sizeof("virtual")];
+    char stringpool_str42[sizeof("outline")];
+    char stringpool_str43[sizeof("default")];
+    char stringpool_str46[sizeof("modmap")];
+    char stringpool_str47[sizeof("virtual_modifiers")];
+    char stringpool_str52[sizeof("overlay")];
+    char stringpool_str53[sizeof("override")];
+    char stringpool_str57[sizeof("include")];
+    char stringpool_str62[sizeof("modifier_map")];
+    char stringpool_str63[sizeof("modifier_keys")];
+    char stringpool_str64[sizeof("indicator")];
+    char stringpool_str66[sizeof("group")];
+    char stringpool_str67[sizeof("mod_map")];
+    char stringpool_str69[sizeof("interpret")];
+    char stringpool_str71[sizeof("solid")];
+    char stringpool_str72[sizeof("partial")];
+  };
+static const struct stringpool_t stringpool_contents =
+  {
+    "key",
+    "keys",
+    "augment",
+    "text",
+    "xkb_keymap",
+    "keypad_keys",
+    "xkb_keycodes",
+    "xkb_geometry",
+    "xkb_types",
+    "xkb_compat",
+    "replace",
+    "xkb_compat_map",
+    "xkb_layout",
+    "xkb_symbols",
+    "xkb_compatibility",
+    "xkb_semantics",
+    "type",
+    "alias",
+    "xkb_compatibility_map",
+    "alphanumeric_keys",
+    "function_keys",
+    "alternate",
+    "shape",
+    "action",
+    "section",
+    "row",
+    "logo",
+    "alternate_group",
+    "hidden",
+    "virtual",
+    "outline",
+    "default",
+    "modmap",
+    "virtual_modifiers",
+    "overlay",
+    "override",
+    "include",
+    "modifier_map",
+    "modifier_keys",
+    "indicator",
+    "group",
+    "mod_map",
+    "interpret",
+    "solid",
+    "partial"
+  };
+#define stringpool ((const char *) &stringpool_contents)
+#ifdef __GNUC__
+__inline
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+const struct keyword_tok *
+keyword_gperf_lookup (register const char *str, register unsigned int len)
+{
+  enum
+    {
+      TOTAL_KEYWORDS = 45,
+      MIN_WORD_LENGTH = 3,
+      MAX_WORD_LENGTH = 21,
+      MIN_HASH_VALUE = 3,
+      MAX_HASH_VALUE = 72
+    };
+
+  static const struct keyword_tok wordlist[] =
+    {
+      {-1}, {-1}, {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3,                    KEY},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4,                   KEYS},
+      {-1}, {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str7,                AUGMENT},
+      {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str9,                   TEXT},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str10,             XKB_KEYMAP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str11,            KEYPAD_KEYS},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str12,           XKB_KEYCODES},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str13,           XKB_GEOMETRY},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str14,              XKB_TYPES},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str15,             XKB_COMPATMAP},
+      {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str17,                REPLACE},
+      {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str19,         XKB_COMPATMAP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str20,             XKB_LAYOUT},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str21,            XKB_SYMBOLS},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str22,      XKB_COMPATMAP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str23,          XKB_SEMANTICS},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str24,                   TYPE},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str25,                  ALIAS},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str26,  XKB_COMPATMAP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str27,      ALPHANUMERIC_KEYS},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str28,          FUNCTION_KEYS},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str29,              ALTERNATE},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str30,                  SHAPE},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str31,                 ACTION_TOK},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str32,                SECTION},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str33,                    ROW},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str34,                   LOGO},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str35,        ALTERNATE_GROUP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str36,                 HIDDEN},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str37,                VIRTUAL},
+      {-1}, {-1}, {-1}, {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str42,                OUTLINE},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str43,                DEFAULT},
+      {-1}, {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str46,                 MODIFIER_MAP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str47,      VIRTUAL_MODS},
+      {-1}, {-1}, {-1}, {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str52,                OVERLAY},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str53,               OVERRIDE},
+      {-1}, {-1}, {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str57,                INCLUDE},
+      {-1}, {-1}, {-1}, {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str62,           MODIFIER_MAP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str63,          MODIFIER_KEYS},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str64,              INDICATOR},
+      {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str66,                  GROUP},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str67,                MODIFIER_MAP},
+      {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str69,              INTERPRET},
+      {-1},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str71,                  SOLID},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str72,                PARTIAL}
+    };
+
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register int key = keyword_gperf_hash (str, len);
+
+      if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+          register int o = wordlist[key].name;
+          if (o >= 0)
+            {
+              register const char *s = o + stringpool;
+
+              if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strcmp (str, s))
+                return &wordlist[key];
+            }
+        }
+    }
+  return 0;
+}
+
+
+int
+keyword_to_token(const char *string)
+{
+    const struct keyword_tok *kt;
+    kt = keyword_gperf_lookup(string, strlen(string));
+    if (!kt)
+        return -1;
+    return kt->tok;
+}
diff --git a/src/xkbcomp/keywords.gperf b/src/xkbcomp/keywords.gperf
new file mode 100644
index 0000000..cfbfe8f
--- /dev/null
+++ b/src/xkbcomp/keywords.gperf
@@ -0,0 +1,79 @@
+%{
+#include "xkbcomp-priv.h"
+#include "parser-priv.h"
+
+static unsigned int
+keyword_gperf_hash(const char *str, unsigned int len);
+
+static const struct keyword_tok *
+keyword_gperf_lookup(const char *str, unsigned int len);
+%}
+
+struct keyword_tok { int name; enum yytokentype tok; };
+%language=ANSI-C
+%define hash-function-name keyword_gperf_hash
+%define lookup-function-name keyword_gperf_lookup
+%readonly-tables
+%enum
+%includes
+%struct-type
+%pic
+%ignore-case
+
+%%
+action,                 ACTION_TOK
+alias,                  ALIAS
+alphanumeric_keys,      ALPHANUMERIC_KEYS
+alternate_group,        ALTERNATE_GROUP
+alternate,              ALTERNATE
+augment,                AUGMENT
+default,                DEFAULT
+function_keys,          FUNCTION_KEYS
+group,                  GROUP
+hidden,                 HIDDEN
+include,                INCLUDE
+indicator,              INDICATOR
+interpret,              INTERPRET
+keypad_keys,            KEYPAD_KEYS
+key,                    KEY
+keys,                   KEYS
+logo,                   LOGO
+modifier_keys,          MODIFIER_KEYS
+modifier_map,           MODIFIER_MAP
+mod_map,                MODIFIER_MAP
+modmap,                 MODIFIER_MAP
+outline,                OUTLINE
+overlay,                OVERLAY
+override,               OVERRIDE
+partial,                PARTIAL
+replace,                REPLACE
+row,                    ROW
+section,                SECTION
+shape,                  SHAPE
+solid,                  SOLID
+text,                   TEXT
+type,                   TYPE
+virtual_modifiers,      VIRTUAL_MODS
+virtual,                VIRTUAL
+xkb_compatibility_map,  XKB_COMPATMAP
+xkb_compatibility,      XKB_COMPATMAP
+xkb_compat_map,         XKB_COMPATMAP
+xkb_compat,             XKB_COMPATMAP
+xkb_geometry,           XKB_GEOMETRY
+xkb_keycodes,           XKB_KEYCODES
+xkb_keymap,             XKB_KEYMAP
+xkb_layout,             XKB_LAYOUT
+xkb_semantics,          XKB_SEMANTICS
+xkb_symbols,            XKB_SYMBOLS
+xkb_types,              XKB_TYPES
+%%
+
+int
+keyword_to_token(const char *string)
+{
+    const struct keyword_tok *kt;
+    kt = keyword_gperf_lookup(string, strlen(string));
+    if (!kt)
+        return -1;
+    return kt->tok;
+}
diff --git a/src/xkbcomp/parser-priv.h b/src/xkbcomp/parser-priv.h
index 2e02db6..465b19d 100644
--- a/src/xkbcomp/parser-priv.h
+++ b/src/xkbcomp/parser-priv.h
@@ -27,21 +27,21 @@
 #ifndef XKBCOMP_PARSER_PRIV_H
 #define XKBCOMP_PARSER_PRIV_H
 
-struct scanner_extra;
+struct scanner;
 struct parser_param;
 
-#pragma GCC diagnostic ignored "-Wredundant-decls"
-#pragma GCC diagnostic push
 #include "parser.h"
-#pragma GCC diagnostic pop
 
-void
-scanner_error(YYLTYPE *loc, void *scanner, const char *msg);
+int
+scanner_error(YYLTYPE *yylloc, struct scanner *scanner, const char *msg);
 
 int
-_xkbcommon_lex(YYSTYPE *val, YYLTYPE *loc, void *scanner);
+_xkbcommon_lex(YYSTYPE *yylval, YYLTYPE *yylloc, struct scanner *scanner);
 
 XkbFile *
 parse(struct xkb_context *ctx, void *scanner, const char *map);
 
+int
+keyword_to_token(const char *string);
+
 #endif
diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y
index 90ac75e..aaf87db 100644
--- a/src/xkbcomp/parser.y
+++ b/src/xkbcomp/parser.y
@@ -48,7 +48,7 @@ _xkbcommon_error(struct YYLTYPE *loc, struct parser_param *param, const char *ms
 %name-prefix    "_xkbcommon_"
 %define         api.pure
 %locations
-%lex-param      { void *scanner }
+%lex-param      { struct scanner *scanner }
 %parse-param    { struct parser_param *param }
 
 %token
diff --git a/src/xkbcomp/scanner.c b/src/xkbcomp/scanner.c
new file mode 100644
index 0000000..4be2c40
--- /dev/null
+++ b/src/xkbcomp/scanner.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "xkbcomp-priv.h"
+#include "parser-priv.h"
+#include "scanner-utils.h"
+
+int
+scanner_error(YYLTYPE *yylloc, struct scanner *s, const char *msg)
+{


Reply to: