keymap-dump: follow xkbcomp in printing affect=both in pointer actions
[platform/upstream/libxkbcommon.git] / src / xkbcomp / ast-build.c
index 79b579c..7ee13d0 100644 (file)
  *         Ran Benita <ran234@gmail.com>
  */
 
+#include "config.h"
+
 #include "xkbcomp-priv.h"
 #include "ast-build.h"
-#include "parser-priv.h"
 #include "include.h"
 
-ParseCommon *
-AppendStmt(ParseCommon *to, ParseCommon *append)
+static ExprDef *
+ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size)
 {
-    ParseCommon *iter;
+    ExprDef *expr = malloc(size);
+    if (!expr)
+        return NULL;
 
-    if (!to)
-        return append;
+    expr->common.type = STMT_EXPR;
+    expr->common.next = NULL;
+    expr->expr.op = op;
+    expr->expr.value_type = type;
 
-    for (iter = to; iter->next; iter = iter->next);
+    return expr;
+}
 
-    iter->next = append;
-    return to;
+ExprDef *
+ExprCreateString(xkb_atom_t str)
+{
+    ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING, sizeof(ExprString));
+    if (!expr)
+        return NULL;
+    expr->string.str = str;
+    return expr;
 }
 
 ExprDef *
-ExprCreate(enum expr_op_type op, enum expr_value_type type)
+ExprCreateInteger(int ival)
 {
-    ExprDef *expr = malloc(sizeof(*expr));
+    ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT, sizeof(ExprInteger));
     if (!expr)
         return NULL;
+    expr->integer.ival = ival;
+    return expr;
+}
 
-    expr->common.type = STMT_EXPR;
-    expr->common.next = NULL;
-    expr->op = op;
-    expr->value_type = type;
+ExprDef *
+ExprCreateFloat(void)
+{
+    ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_FLOAT, sizeof(ExprFloat));
+    if (!expr)
+        return NULL;
+    return expr;
+}
+
+ExprDef *
+ExprCreateBoolean(bool set)
+{
+    ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN, sizeof(ExprBoolean));
+    if (!expr)
+        return NULL;
+    expr->boolean.set = set;
+    return expr;
+}
+
+ExprDef *
+ExprCreateKeyName(xkb_atom_t key_name)
+{
+    ExprDef *expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME, sizeof(ExprKeyName));
+    if (!expr)
+        return NULL;
+    expr->key_name.key_name = key_name;
+    return expr;
+}
 
+ExprDef *
+ExprCreateIdent(xkb_atom_t ident)
+{
+    ExprDef *expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN, sizeof(ExprIdent));
+    if (!expr)
+        return NULL;
+    expr->ident.ident = ident;
     return expr;
 }
 
@@ -89,38 +135,129 @@ ExprDef *
 ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
                 ExprDef *child)
 {
-    ExprDef *expr = malloc(sizeof(*expr));
+    ExprDef *expr = ExprCreate(op, type, sizeof(ExprUnary));
+    if (!expr)
+        return NULL;
+    expr->unary.child = child;
+    return expr;
+}
+
+ExprDef *
+ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
+{
+    ExprDef *expr = ExprCreate(op, EXPR_TYPE_UNKNOWN, sizeof(ExprBinary));
     if (!expr)
         return NULL;
 
-    expr->common.type = STMT_EXPR;
-    expr->common.next = NULL;
-    expr->op = op;
-    expr->value_type = type;
-    expr->value.child = child;
+    if (op == EXPR_ASSIGN || left->expr.value_type == EXPR_TYPE_UNKNOWN)
+        expr->expr.value_type = right->expr.value_type;
+    else if (left->expr.value_type == right->expr.value_type ||
+             right->expr.value_type == EXPR_TYPE_UNKNOWN)
+        expr->expr.value_type = left->expr.value_type;
+    expr->binary.left = left;
+    expr->binary.right = right;
 
     return expr;
 }
 
 ExprDef *
-ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
+ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
 {
-    ExprDef *expr = malloc(sizeof(*expr));
+    ExprDef *expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprFieldRef));
     if (!expr)
         return NULL;
+    expr->field_ref.element = element;
+    expr->field_ref.field = field;
+    return expr;
+}
 
-    expr->common.type = STMT_EXPR;
-    expr->common.next = NULL;
-    expr->op = op;
-    if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN)
-        expr->value_type = right->value_type;
-    else if (left->value_type == right->value_type ||
-             right->value_type == EXPR_TYPE_UNKNOWN)
-        expr->value_type = left->value_type;
-    else
-        expr->value_type = EXPR_TYPE_UNKNOWN;
-    expr->value.binary.left = left;
-    expr->value.binary.right = right;
+ExprDef *
+ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry)
+{
+    ExprDef *expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN, sizeof(ExprArrayRef));
+    if (!expr)
+        return NULL;
+    expr->array_ref.element = element;
+    expr->array_ref.field = field;
+    expr->array_ref.entry = entry;
+    return expr;
+}
+
+ExprDef *
+ExprCreateAction(xkb_atom_t name, ExprDef *args)
+{
+    ExprDef *expr = ExprCreate(EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN, sizeof(ExprAction));
+    if (!expr)
+        return NULL;
+    expr->action.name = name;
+    expr->action.args = args;
+    return expr;
+}
+
+ExprDef *
+ExprCreateActionList(ExprDef *actions)
+{
+    ExprDef *expr = ExprCreate(EXPR_ACTION_LIST, EXPR_TYPE_ACTIONS, sizeof(ExprActionList));
+    if (!expr)
+        return NULL;
+    expr->actions.actions = actions;
+    return expr;
+}
+
+ExprDef *
+ExprCreateKeysymList(xkb_keysym_t sym)
+{
+    ExprDef *expr = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS, sizeof(ExprKeysymList));
+    if (!expr)
+        return NULL;
+
+    darray_init(expr->keysym_list.syms);
+    darray_init(expr->keysym_list.symsMapIndex);
+    darray_init(expr->keysym_list.symsNumEntries);
+
+    darray_append(expr->keysym_list.syms, sym);
+    darray_append(expr->keysym_list.symsMapIndex, 0);
+    darray_append(expr->keysym_list.symsNumEntries, 1);
+
+    return expr;
+}
+
+ExprDef *
+ExprCreateMultiKeysymList(ExprDef *expr)
+{
+    unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex);
+
+    darray_resize(expr->keysym_list.symsMapIndex, 1);
+    darray_resize(expr->keysym_list.symsNumEntries, 1);
+    darray_item(expr->keysym_list.symsMapIndex, 0) = 0;
+    darray_item(expr->keysym_list.symsNumEntries, 0) = nLevels;
+
+    return expr;
+}
+
+ExprDef *
+ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
+{
+    unsigned nSyms = darray_size(expr->keysym_list.syms);
+
+    darray_append(expr->keysym_list.symsMapIndex, nSyms);
+    darray_append(expr->keysym_list.symsNumEntries, 1);
+    darray_append(expr->keysym_list.syms, sym);
+
+    return expr;
+}
+
+ExprDef *
+ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append)
+{
+    unsigned nSyms = darray_size(expr->keysym_list.syms);
+    unsigned numEntries = darray_size(append->keysym_list.syms);
+
+    darray_append(expr->keysym_list.symsMapIndex, nSyms);
+    darray_append(expr->keysym_list.symsNumEntries, numEntries);
+    darray_concat(expr->keysym_list.syms, append->keysym_list.syms);
+
+    FreeStmt((ParseCommon *) append);
 
     return expr;
 }
@@ -186,22 +323,27 @@ VarCreate(ExprDef *name, ExprDef *value)
 }
 
 VarDef *
-BoolVarCreate(xkb_atom_t nameToken, unsigned set)
+BoolVarCreate(xkb_atom_t ident, bool set)
 {
     ExprDef *name, *value;
     VarDef *def;
-
-    name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
-    name->value.str = nameToken;
-    value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
-    value->value.uval = set;
-    def = VarCreate(name, value);
-
+    if (!(name = ExprCreateIdent(ident))) {
+        return NULL;
+    }
+    if (!(value = ExprCreateBoolean(set))) {
+        FreeStmt((ParseCommon *) name);
+        return NULL;
+    }
+    if (!(def = VarCreate(name, value))) {
+        FreeStmt((ParseCommon *) name);
+        FreeStmt((ParseCommon *) value);
+        return NULL;
+    }
     return def;
 }
 
 InterpDef *
-InterpCreate(char *sym, ExprDef *match)
+InterpCreate(xkb_keysym_t sym, ExprDef *match)
 {
     InterpDef *def = malloc(sizeof(*def));
     if (!def)
@@ -211,6 +353,7 @@ InterpCreate(char *sym, ExprDef *match)
     def->common.next = NULL;
     def->sym = sym;
     def->match = match;
+    def->def = NULL;
 
     return def;
 }
@@ -232,7 +375,7 @@ KeyTypeCreate(xkb_atom_t name, VarDef *body)
 }
 
 SymbolsDef *
-SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols)
+SymbolsCreate(xkb_atom_t keyName, VarDef *symbols)
 {
     SymbolsDef *def = malloc(sizeof(*def));
     if (!def)
@@ -248,7 +391,7 @@ SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols)
 }
 
 GroupCompatDef *
-GroupCompatCreate(int group, ExprDef *val)
+GroupCompatCreate(unsigned group, ExprDef *val)
 {
     GroupCompatDef *def = malloc(sizeof(*def));
     if (!def)
@@ -264,7 +407,7 @@ GroupCompatCreate(int group, ExprDef *val)
 }
 
 ModMapDef *
-ModMapCreate(uint32_t modifier, ExprDef *keys)
+ModMapCreate(xkb_atom_t modifier, ExprDef *keys)
 {
     ModMapDef *def = malloc(sizeof(*def));
     if (!def)
@@ -296,7 +439,7 @@ LedMapCreate(xkb_atom_t name, VarDef *body)
 }
 
 LedNameDef *
-LedNameCreate(int ndx, ExprDef *name, bool virtual)
+LedNameCreate(unsigned ndx, ExprDef *name, bool virtual)
 {
     LedNameDef *def = malloc(sizeof(*def));
     if (!def)
@@ -312,83 +455,6 @@ LedNameCreate(int ndx, ExprDef *name, bool virtual)
     return def;
 }
 
-ExprDef *
-ActionCreate(xkb_atom_t name, ExprDef *args)
-{
-    ExprDef *act = malloc(sizeof(*act));
-    if (!act)
-        return NULL;
-
-    act->common.type = STMT_EXPR;
-    act->common.next = NULL;
-    act->op = EXPR_ACTION_DECL;
-    act->value.action.name = name;
-    act->value.action.args = args;
-
-    return act;
-}
-
-ExprDef *
-CreateKeysymList(char *sym)
-{
-    ExprDef *def;
-
-    def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
-
-    darray_init(def->value.list.syms);
-    darray_init(def->value.list.symsMapIndex);
-    darray_init(def->value.list.symsNumEntries);
-
-    darray_append(def->value.list.syms, sym);
-    darray_append(def->value.list.symsMapIndex, 0);
-    darray_append(def->value.list.symsNumEntries, 1);
-
-    return def;
-}
-
-ExprDef *
-CreateMultiKeysymList(ExprDef *list)
-{
-    size_t nLevels = darray_size(list->value.list.symsMapIndex);
-
-    darray_resize(list->value.list.symsMapIndex, 1);
-    darray_resize(list->value.list.symsNumEntries, 1);
-    darray_item(list->value.list.symsMapIndex, 0) = 0;
-    darray_item(list->value.list.symsNumEntries, 0) = nLevels;
-
-    return list;
-}
-
-ExprDef *
-AppendKeysymList(ExprDef *list, char *sym)
-{
-    size_t nSyms = darray_size(list->value.list.syms);
-
-    darray_append(list->value.list.symsMapIndex, nSyms);
-    darray_append(list->value.list.symsNumEntries, 1);
-    darray_append(list->value.list.syms, sym);
-
-    return list;
-}
-
-ExprDef *
-AppendMultiKeysymList(ExprDef *list, ExprDef *append)
-{
-    size_t nSyms = darray_size(list->value.list.syms);
-    size_t numEntries = darray_size(append->value.list.syms);
-
-    darray_append(list->value.list.symsMapIndex, nSyms);
-    darray_append(list->value.list.symsNumEntries, numEntries);
-    darray_append_items(list->value.list.syms,
-                        darray_mem(append->value.list.syms, 0),
-                        numEntries);
-
-    darray_resize(append->value.list.syms, 0);
-    FreeStmt(&append->common);
-
-    return list;
-}
-
 static void
 FreeInclude(IncludeStmt *incl);
 
@@ -428,12 +494,8 @@ IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
             incl = incl->next_incl;
         }
 
-        if (!incl) {
-            log_wsgo(ctx,
-                     "Allocation failure in IncludeCreate; "
-                     "Using only part of the include\n");
+        if (!incl)
             break;
-        }
 
         incl->common.type = STMT_INCLUDE;
         incl->common.next = NULL;
@@ -464,33 +526,9 @@ err:
     return NULL;
 }
 
-static void
-EscapeMapName(char *name)
-{
-    /*
-     * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
-     * wildcards.
-     */
-    static const unsigned char legal[] = {
-        0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
-        0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
-    };
-
-    if (!name)
-        return;
-
-    while (*name) {
-        if (!(legal[*name / 8] & (1 << (*name % 8))))
-            *name = '_';
-        name++;
-    }
-}
-
 XkbFile *
-XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
-              ParseCommon *defs, enum xkb_map_flags flags)
+XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
+              enum xkb_map_flags flags)
 {
     XkbFile *file;
 
@@ -498,12 +536,10 @@ XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
     if (!file)
         return NULL;
 
-    EscapeMapName(name);
+    XkbEscapeMapName(name);
     file->file_type = type;
-    file->topName = strdup_safe(name);
-    file->name = name;
+    file->name = name ? name : strdup("(unnamed)");
     file->defs = defs;
-    file->id = xkb_context_take_file_id(ctx);
     file->flags = flags;
 
     return file;
@@ -520,23 +556,26 @@ XkbFileFromComponents(struct xkb_context *ctx,
     enum xkb_file_type type;
     IncludeStmt *include = NULL;
     XkbFile *file = NULL;
-    ParseCommon *defs = NULL;
+    ParseCommon *defs = NULL, *defsLast = NULL;
 
     for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) {
         include = IncludeCreate(ctx, components[type], MERGE_DEFAULT);
         if (!include)
             goto err;
 
-        file = XkbFileCreate(ctx, type, NULL, &include->common, 0);
+        file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0);
         if (!file) {
             FreeInclude(include);
             goto err;
         }
 
-        defs = AppendStmt(defs, &file->common);
+        if (!defs)
+            defsLast = defs = &file->common;
+        else
+            defsLast = defsLast->next = &file->common;
     }
 
-    file = XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL, defs, 0);
+    file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0);
     if (!file)
         goto err;
 
@@ -550,18 +589,15 @@ err:
 static void
 FreeExpr(ExprDef *expr)
 {
-    char **sym;
-
     if (!expr)
         return;
 
-    switch (expr->op) {
-    case EXPR_ACTION_LIST:
+    switch (expr->expr.op) {
     case EXPR_NEGATE:
     case EXPR_UNARY_PLUS:
     case EXPR_NOT:
     case EXPR_INVERT:
-        FreeStmt(&expr->value.child->common);
+        FreeStmt((ParseCommon *) expr->unary.child);
         break;
 
     case EXPR_DIVIDE:
@@ -569,24 +605,26 @@ FreeExpr(ExprDef *expr)
     case EXPR_SUBTRACT:
     case EXPR_MULTIPLY:
     case EXPR_ASSIGN:
-        FreeStmt(&expr->value.binary.left->common);
-        FreeStmt(&expr->value.binary.right->common);
+        FreeStmt((ParseCommon *) expr->binary.left);
+        FreeStmt((ParseCommon *) expr->binary.right);
         break;
 
     case EXPR_ACTION_DECL:
-        FreeStmt(&expr->value.action.args->common);
+        FreeStmt((ParseCommon *) expr->action.args);
+        break;
+
+    case EXPR_ACTION_LIST:
+        FreeStmt((ParseCommon *) expr->actions.actions);
         break;
 
     case EXPR_ARRAY_REF:
-        FreeStmt(&expr->value.array.entry->common);
+        FreeStmt((ParseCommon *) expr->array_ref.entry);
         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);
+        darray_free(expr->keysym_list.syms);
+        darray_free(expr->keysym_list.symsMapIndex);
+        darray_free(expr->keysym_list.symsNumEntries);
         break;
 
     default:
@@ -617,12 +655,10 @@ void
 FreeStmt(ParseCommon *stmt)
 {
     ParseCommon *next;
-    YYSTYPE u;
 
     while (stmt)
     {
         next = stmt->next;
-        u.any = stmt;
 
         switch (stmt->type) {
         case STMT_INCLUDE:
@@ -631,37 +667,36 @@ FreeStmt(ParseCommon *stmt)
             stmt = NULL;
             break;
         case STMT_EXPR:
-            FreeExpr(u.expr);
+            FreeExpr((ExprDef *) stmt);
             break;
         case STMT_VAR:
-            FreeStmt(&u.var->name->common);
-            FreeStmt(&u.var->value->common);
+            FreeStmt((ParseCommon *) ((VarDef *) stmt)->name);
+            FreeStmt((ParseCommon *) ((VarDef *) stmt)->value);
             break;
         case STMT_TYPE:
-            FreeStmt(&u.keyType->body->common);
+            FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body);
             break;
         case STMT_INTERP:
-            free(u.interp->sym);
-            FreeStmt(&u.interp->match->common);
-            FreeStmt(&u.interp->def->common);
+            FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match);
+            FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def);
             break;
         case STMT_VMOD:
-            FreeStmt(&u.vmod->value->common);
+            FreeStmt((ParseCommon *) ((VModDef *) stmt)->value);
             break;
         case STMT_SYMBOLS:
-            FreeStmt(&u.syms->symbols->common);
+            FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols);
             break;
         case STMT_MODMAP:
-            FreeStmt(&u.modMask->keys->common);
+            FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys);
             break;
         case STMT_GROUP_COMPAT:
-            FreeStmt(&u.groupCompat->def->common);
+            FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def);
             break;
         case STMT_LED_MAP:
-            FreeStmt(&u.ledMap->body->common);
+            FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body);
             break;
         case STMT_LED_NAME:
-            FreeStmt(&u.ledName->name->common);
+            FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name);
             break;
         default:
             break;
@@ -699,7 +734,6 @@ FreeXkbFile(XkbFile *file)
         }
 
         free(file->name);
-        free(file->topName);
         free(file);
         file = next;
     }
@@ -718,7 +752,7 @@ static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = {
 const char *
 xkb_file_type_to_string(enum xkb_file_type type)
 {
-    if (type > _FILE_TYPE_NUM_ENTRIES)
+    if (type >= _FILE_TYPE_NUM_ENTRIES)
         return "unknown";
     return xkb_file_type_strings[type];
 }
@@ -779,8 +813,10 @@ static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = {
     [EXPR_TYPE_UNKNOWN] = "unknown",
     [EXPR_TYPE_BOOLEAN] = "boolean",
     [EXPR_TYPE_INT] = "int",
+    [EXPR_TYPE_FLOAT] = "float",
     [EXPR_TYPE_STRING] = "string",
     [EXPR_TYPE_ACTION] = "action",
+    [EXPR_TYPE_ACTIONS] = "actions",
     [EXPR_TYPE_KEYNAME] = "keyname",
     [EXPR_TYPE_SYMBOLS] = "symbols",
 };