Resolve keysyms early in parser
authorRan Benita <ran234@gmail.com>
Wed, 27 Nov 2013 11:49:13 +0000 (13:49 +0200)
committerRan Benita <ran234@gmail.com>
Wed, 27 Nov 2013 11:52:54 +0000 (13:52 +0200)
Instead of having the parser passing strings to the AST, and
symbols/compat etc. resolving them themselves. This simplifies the code
a bit, and makes it possible to print where exactly in the file the bad
keysym originates from.

The previous lazy approach had an advantage of not needlessly resolving
keysyms from unrelated maps. However, I think reporting these errors in
*any* map is better, and the parser is also a bit smarter then old
xkbcomp and doesn't parse many useless maps. So there's no discernible
speed/memory difference with this change.

Signed-off-by: Ran Benita <ran234@gmail.com>
src/xkbcomp/ast-build.c
src/xkbcomp/ast-build.h
src/xkbcomp/ast.h
src/xkbcomp/compat.c
src/xkbcomp/parser.y
src/xkbcomp/symbols.c
src/xkbcomp/xkbcomp-priv.h

index 4a36802..25172ee 100644 (file)
@@ -201,7 +201,7 @@ BoolVarCreate(xkb_atom_t nameToken, unsigned set)
 }
 
 InterpDef *
-InterpCreate(char *sym, ExprDef *match)
+InterpCreate(xkb_keysym_t sym, ExprDef *match)
 {
     InterpDef *def = malloc(sizeof(*def));
     if (!def)
@@ -329,7 +329,7 @@ ActionCreate(xkb_atom_t name, ExprDef *args)
 }
 
 ExprDef *
-CreateKeysymList(char *sym)
+CreateKeysymList(xkb_keysym_t sym)
 {
     ExprDef *def;
 
@@ -360,7 +360,7 @@ CreateMultiKeysymList(ExprDef *list)
 }
 
 ExprDef *
-AppendKeysymList(ExprDef *list, char *sym)
+AppendKeysymList(ExprDef *list, xkb_keysym_t sym)
 {
     size_t nSyms = darray_size(list->value.list.syms);
 
@@ -549,8 +549,6 @@ err:
 static void
 FreeExpr(ExprDef *expr)
 {
-    char **sym;
-
     if (!expr)
         return;
 
@@ -581,8 +579,6 @@ FreeExpr(ExprDef *expr)
         break;
 
     case EXPR_KEYSYM_LIST:
-        darray_foreach(sym, expr->value.list.syms)
-            free(*sym);
         darray_free(expr->value.list.syms);
         darray_free(expr->value.list.symsMapIndex);
         darray_free(expr->value.list.symsNumEntries);
@@ -640,7 +636,6 @@ FreeStmt(ParseCommon *stmt)
             FreeStmt(&u.keyType->body->common);
             break;
         case STMT_INTERP:
-            free(u.interp->sym);
             FreeStmt(&u.interp->match->common);
             FreeStmt(&u.interp->def->common);
             break;
index 4340c8c..4413f88 100644 (file)
@@ -56,7 +56,7 @@ VarDef *
 BoolVarCreate(xkb_atom_t nameToken, unsigned set);
 
 InterpDef *
-InterpCreate(char *sym, ExprDef *match);
+InterpCreate(xkb_keysym_t sym, ExprDef *match);
 
 KeyTypeDef *
 KeyTypeCreate(xkb_atom_t name, VarDef *body);
@@ -83,13 +83,13 @@ ExprDef *
 CreateMultiKeysymList(ExprDef *list);
 
 ExprDef *
-CreateKeysymList(char *sym);
+CreateKeysymList(xkb_keysym_t sym);
 
 ExprDef *
 AppendMultiKeysymList(ExprDef *list, ExprDef *append);
 
 ExprDef *
-AppendKeysymList(ExprDef *list, char *sym);
+AppendKeysymList(ExprDef *list, xkb_keysym_t sym);
 
 IncludeStmt *
 IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
index c430a77..ed8831b 100644 (file)
@@ -181,7 +181,7 @@ typedef struct _Expr {
             struct _Expr *args;
         } action;
         struct {
-            darray(char *) syms;
+            darray(xkb_keysym_t) syms;
             darray(int) symsMapIndex;
             darray(unsigned int) symsNumEntries;
         } list;
@@ -252,7 +252,7 @@ typedef struct {
 typedef struct {
     ParseCommon common;
     enum merge_mode merge;
-    char *sym;
+    xkb_keysym_t sym;
     ExprDef *match;
     VarDef *def;
 } InterpDef;
index e58f61c..9e17cbb 100644 (file)
@@ -840,15 +840,7 @@ HandleInterpDef(CompatInfo *info, InterpDef *def, enum merge_mode merge)
 
     si = info->default_interp;
     si.merge = merge = (def->merge == MERGE_DEFAULT ? merge : def->merge);
-
-    if (!LookupKeysym(def->sym, &si.interp.sym)) {
-        log_err(info->keymap->ctx,
-                "Could not resolve keysym %s; "
-                "Symbol interpretation ignored\n",
-                def->sym);
-        return false;
-    }
-
+    si.interp.sym = def->sym;
     si.interp.match = pred;
     si.interp.mods = mods;
 
index 001ea67..01421fc 100644 (file)
@@ -43,11 +43,47 @@ struct parser_param {
 };
 
 static void
-_xkbcommon_error(struct parser_param *param, const char *msg)
+parser_error(struct parser_param *param, const char *msg)
 {
     scanner_error(param->scanner, msg);
 }
 
+static void
+parser_warn(struct parser_param *param, const char *msg)
+{
+    scanner_warn(param->scanner, msg);
+}
+
+static void
+_xkbcommon_error(struct parser_param *param, const char *msg)
+{
+    parser_error(param, msg);
+}
+
+static bool
+resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn)
+{
+    xkb_keysym_t sym;
+
+    if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
+        *sym_rtrn = XKB_KEY_NoSymbol;
+        return true;
+    }
+
+    if (istreq(str, "none") || istreq(str, "voidsymbol")) {
+        *sym_rtrn = XKB_KEY_VoidSymbol;
+        return true;
+    }
+
+    sym = xkb_keysym_from_name(str, XKB_KEYSYM_NO_FLAGS);
+    if (sym != XKB_KEY_NoSymbol) {
+        *sym_rtrn = sym;
+        return true;
+    }
+
+    return false;
+}
+
 #define scanner param->scanner
 %}
 
@@ -137,6 +173,7 @@ _xkbcommon_error(struct parser_param *param, const char *msg)
         xkb_atom_t      sval;
         enum merge_mode merge;
         enum xkb_map_flags mapFlags;
+        xkb_keysym_t    keysym;
         ParseCommon     *any;
         ExprDef         *expr;
         VarDef          *var;
@@ -163,8 +200,9 @@ _xkbcommon_error(struct parser_param *param, const char *msg)
 %type <file_type> XkbCompositeType FileType
 %type <uval>    DoodadType
 %type <mapFlags> Flag Flags OptFlags
-%type <str>     MapName OptMapName KeySym
+%type <str>     MapName OptMapName
 %type <sval>    FieldSpec Ident Element String
+%type <keysym>  KeySym
 %type <any>     DeclList Decl
 %type <expr>    OptExprList ExprList Expr Term Lhs Terminal ArrayInit KeySyms
 %type <expr>    OptKeySymList KeySymList Action ActionList Coord CoordList
@@ -707,18 +745,23 @@ KeySyms         :       OBRACE KeySymList CBRACE
                         { $$ = $2; }
                 ;
 
-KeySym          :       IDENT   { $$ = $1; }
-                |       SECTION { $$ = strdup("section"); }
+KeySym          :       IDENT
+                        {
+                            if (!resolve_keysym($1, &$$))
+                                parser_warn(param, "unrecognized keysym");
+                            free($1);
+                        }
+                |       SECTION { $$ = XKB_KEY_section; }
                 |       Integer
                         {
-                            if ($1 < 10) {      /* XK_0 .. XK_9 */
-                                $$ = malloc(2);
-                                $$[0] = $1 + '0';
-                                $$[1] = '\0';
+                            if ($1 < 10) {      /* XKB_KEY_0 .. XKB_KEY_9 */
+                                $$ = XKB_KEY_0 + $1;
                             }
                             else {
-                                $$ = malloc(17);
-                                snprintf($$, 17, "0x%x", $1);
+                                char buf[17];
+                                snprintf(buf, sizeof(buf), "0x%x", $1);
+                                if (!resolve_keysym(buf, &$$))
+                                    parser_warn(param, "unrecognized keysym");
                             }
                         }
                 ;
index fdc961b..e719da9 100644 (file)
@@ -626,30 +626,6 @@ GetGroupIndex(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
     return true;
 }
 
-bool
-LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
-{
-    xkb_keysym_t sym;
-
-    if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
-        *sym_rtrn = XKB_KEY_NoSymbol;
-        return true;
-    }
-
-    if (istreq(str, "none") || istreq(str, "voidsymbol")) {
-        *sym_rtrn = XKB_KEY_VoidSymbol;
-        return true;
-    }
-
-    sym = xkb_keysym_from_name(str, XKB_KEYSYM_NO_FLAGS);
-    if (sym != XKB_KEY_NoSymbol) {
-        *sym_rtrn = sym;
-        return true;
-    }
-
-    return false;
-}
-
 static bool
 AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
                 ExprDef *value)
@@ -703,28 +679,8 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
             leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms));
 
         for (j = 0; j < leveli->num_syms; j++) {
-            char *sym_name = darray_item(value->value.list.syms,
-                                         sym_index + j);
-            xkb_keysym_t keysym;
-
-            if (!LookupKeysym(sym_name, &keysym)) {
-                const char *group_name = "unnamed";
-
-                if (ndx < darray_size(info->group_names) &&
-                    darray_item(info->group_names, ndx))
-                    group_name = xkb_atom_text(info->keymap->ctx,
-                                               darray_item(info->group_names,
-                                                           ndx));
-
-                log_warn(info->keymap->ctx,
-                         "Could not resolve keysym %s for key %s, group %u (%s), level %u\n",
-                         sym_name, KeyInfoText(info, keyi), ndx + 1,
-                         group_name, i);
-
-                ClearLevelInfo(leveli);
-                leveli->num_syms = 0;
-                break;
-            }
+            xkb_keysym_t keysym = darray_item(value->value.list.syms,
+                                              sym_index + j);
 
             if (leveli->num_syms == 1) {
                 if (keysym == XKB_KEY_NoSymbol)
index a5d4a1e..7e21d53 100644 (file)
@@ -79,9 +79,6 @@ bool
 CompileKeymap(XkbFile *file, struct xkb_keymap *keymap,
               enum merge_mode merge);
 
-bool
-LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn);
-
 /***====================================================================***/
 
 static inline bool