Organize xkbcomp/ header files
authorRan Benita <ran234@gmail.com>
Mon, 13 Aug 2012 08:00:43 +0000 (11:00 +0300)
committerRan Benita <ran234@gmail.com>
Sat, 1 Sep 2012 07:58:10 +0000 (10:58 +0300)
Various non-functional changes:
- Re-add keycodes.h and move some stuff there.
- Add parser-priv.h for internal bison/flex stuff.
- Don't include headers from other headers, such that file dependencies
  are immediate in each file.
- Rename xkbcomp.h -> ast.h, parseutils.{c,h} -> ast-build.{c,h}
- Rename path.{c,h} -> include.{c,h}
- Rename keytypes.c -> types.c
- Make the naming of XkbFile-related functions more consistent.
- Move xkb_map_{new,ref,unref} to map.c.
- Remove most extern keyword from function declarations, it's just
  noise (XKB_EXPORT is what's important here).
- Append XKBCOMP_ to include guards.
- Shuffle some code around to make all of this work.

Splitting this would be a headache..

Signed-off-by: Ran Benita <ran234@gmail.com>
33 files changed:
Makefile.am
src/map.c
src/xkb-priv.h
src/xkbcomp/action.c
src/xkbcomp/action.h
src/xkbcomp/ast-build.c [new file with mode: 0644]
src/xkbcomp/ast-build.h [new file with mode: 0644]
src/xkbcomp/ast.h [new file with mode: 0644]
src/xkbcomp/compat.c
src/xkbcomp/expr.c
src/xkbcomp/expr.h
src/xkbcomp/include.c [new file with mode: 0644]
src/xkbcomp/include.h [new file with mode: 0644]
src/xkbcomp/keycodes.c
src/xkbcomp/keycodes.h [new file with mode: 0644]
src/xkbcomp/keytypes.c [deleted file]
src/xkbcomp/parser-priv.h [new file with mode: 0644]
src/xkbcomp/parser.y
src/xkbcomp/parseutils.c [deleted file]
src/xkbcomp/parseutils.h [deleted file]
src/xkbcomp/path.c [deleted file]
src/xkbcomp/path.h [deleted file]
src/xkbcomp/rules.c
src/xkbcomp/rules.h
src/xkbcomp/scanner.l
src/xkbcomp/symbols.c
src/xkbcomp/types.c [new file with mode: 0644]
src/xkbcomp/vmod.c
src/xkbcomp/vmod.h
src/xkbcomp/xkbcomp-priv.h
src/xkbcomp/xkbcomp.c
src/xkbcomp/xkbcomp.h [deleted file]
test/rules-file.c

index 48bcccacf35965f81ac19b7cd781b45553153799..ed96b660cfc5812ae674c8b8fcdfe85d3bcd0b60 100644 (file)
@@ -41,24 +41,26 @@ libxkbcommon_la_LDFLAGS = -no-undefined
 libxkbcommon_la_SOURCES = \
        src/xkbcomp/action.c \
        src/xkbcomp/action.h \
+       src/xkbcomp/ast.h \
+       src/xkbcomp/ast-build.c \
+       src/xkbcomp/ast-build.h \
        src/xkbcomp/compat.c \
        src/xkbcomp/expr.c \
        src/xkbcomp/expr.h \
+       src/xkbcomp/include.c \
+       src/xkbcomp/include.h \
        src/xkbcomp/keycodes.c \
-       src/xkbcomp/keytypes.c \
+       src/xkbcomp/keycodes.h \
        src/xkbcomp/parser.y \
-       src/xkbcomp/parseutils.c \
-       src/xkbcomp/parseutils.h \
-       src/xkbcomp/path.c \
-       src/xkbcomp/path.h \
+       src/xkbcomp/parser-priv.h \
        src/xkbcomp/rules.c \
        src/xkbcomp/rules.h \
        src/xkbcomp/scanner.l \
        src/xkbcomp/symbols.c \
+       src/xkbcomp/types.c \
        src/xkbcomp/vmod.c \
        src/xkbcomp/vmod.h \
        src/xkbcomp/xkbcomp.c \
-       src/xkbcomp/xkbcomp.h \
        src/xkbcomp/xkbcomp-priv.h \
        src/atom.c \
        src/atom.h \
index fa64246f18f17ed4e932ea12bcc522f07d0484e3..9d65ba77d24ada0df9bdd6a4c5a52a1ebeca358f 100644 (file)
--- a/src/map.c
+++ b/src/map.c
 #include "xkb-priv.h"
 #include "text.h"
 
+struct xkb_keymap *
+xkb_map_new(struct xkb_context *ctx)
+{
+    struct xkb_keymap *keymap;
+
+    keymap = calloc(1, sizeof(*keymap));
+    if (!keymap)
+        return NULL;
+
+    keymap->refcnt = 1;
+    keymap->ctx = xkb_context_ref(ctx);
+
+    return keymap;
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_map_ref(struct xkb_keymap *keymap)
+{
+    keymap->refcnt++;
+    return keymap;
+}
+
+XKB_EXPORT void
+xkb_map_unref(struct xkb_keymap *keymap)
+{
+    unsigned int i;
+    struct xkb_key *key;
+
+    if (!keymap || --keymap->refcnt > 0)
+        return;
+
+    for (i = 0; i < keymap->num_types; i++) {
+        free(keymap->types[i].map);
+        free(keymap->types[i].level_names);
+    }
+    free(keymap->types);
+    darray_foreach(key, keymap->keys) {
+        free(key->sym_index);
+        free(key->num_syms);
+        darray_free(key->syms);
+        free(key->actions);
+    }
+    darray_free(keymap->keys);
+    darray_free(keymap->sym_interpret);
+    darray_free(keymap->key_aliases);
+    free(keymap->keycodes_section_name);
+    free(keymap->symbols_section_name);
+    free(keymap->types_section_name);
+    free(keymap->compat_section_name);
+    xkb_context_unref(keymap->ctx);
+    free(keymap);
+}
+
 /**
  * Returns the total number of modifiers active in the keymap.
  */
index 9c42aeb2e59eb77a81c3de581decb7b8db2180fd..f61e2a57812532e1dbbd32884ada5e3fc6464042 100644 (file)
@@ -438,6 +438,9 @@ XkbKeycodeInRange(struct xkb_keymap *keymap, xkb_keycode_t kc)
     return kc >= keymap->min_key_code && kc <= keymap->max_key_code;
 }
 
+struct xkb_keymap *
+xkb_map_new(struct xkb_context *ctx);
+
 xkb_atom_t
 xkb_atom_intern(struct xkb_context *ctx, const char *string);
 
index 0d376886e5af13e028be31adfd78cf8c752c8204..9aa3c95b29eef262e3c9f9415e3e7cb5e8b968e5 100644 (file)
  *
  ********************************************************/
 
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
 #include "action.h"
+#include "keycodes.h"
 
 static const ExprDef constTrue = {
     .common = { .type = STMT_EXPR, .next = NULL },
index 5cf67d97a723e3bab93cc455aa9bd971b93b74d2..f5c9443b4e9dd46ba6780eb74009a08407895ee1 100644 (file)
  *
  ********************************************************/
 
-#ifndef ACTION_H
-#define ACTION_H 1
-
-#include "xkbcomp-priv.h"
-#include "expr.h"
+#ifndef XKBCOMP_ACTION_H
+#define XKBCOMP_ACTION_H
 
 #define F_ClearLocks  0
 #define F_LatchToLock 1
@@ -66,16 +63,14 @@ typedef struct _ActionInfo {
     struct _ActionInfo *next;
 } ActionInfo;
 
-extern int
+int
 HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
-                union xkb_action *action,
-                ActionInfo *info);
+                union xkb_action *action, ActionInfo *info);
 
-extern int
+int
 SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field,
-               ExprDef *index, ExprDef *value,
-               ActionInfo **info_rtrn);
+               ExprDef *index, ExprDef *value, ActionInfo **info_rtrn);
 
 extern const LookupEntry ctrlNames[];
 
-#endif /* ACTION_H */
+#endif
diff --git a/src/xkbcomp/ast-build.c b/src/xkbcomp/ast-build.c
new file mode 100644 (file)
index 0000000..e785081
--- /dev/null
@@ -0,0 +1,677 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "xkbcomp-priv.h"
+#include "ast-build.h"
+#include "parser-priv.h"
+#include "include.h"
+
+ATTR_MALLOC static void *
+malloc_or_die(size_t size)
+{
+    void *p = malloc(size);
+    if (!p) {
+        fprintf(stderr, "Out of memory\n");
+        exit(1);
+    }
+    return p;
+}
+
+ParseCommon *
+AppendStmt(ParseCommon * to, ParseCommon * append)
+{
+    ParseCommon *start = to;
+
+    if (append == NULL)
+        return to;
+    while ((to != NULL) && (to->next != NULL))
+    {
+        to = to->next;
+    }
+    if (to) {
+        to->next = append;
+        return start;
+    }
+    return append;
+}
+
+ExprDef *
+ExprCreate(enum expr_op_type op, enum expr_value_type type)
+{
+    ExprDef *expr;
+
+    expr = malloc_or_die(sizeof(*expr));
+
+    expr->common.type = STMT_EXPR;
+    expr->common.next = NULL;
+    expr->op = op;
+    expr->value_type = type;
+    return expr;
+}
+
+ExprDef *
+ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
+                ExprDef *child)
+{
+    ExprDef *expr;
+    expr = malloc_or_die(sizeof(*expr));
+
+    expr->common.type = STMT_EXPR;
+    expr->common.next = NULL;
+    expr->op = op;
+    expr->value_type = type;
+    expr->value.child = child;
+    return expr;
+}
+
+ExprDef *
+ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
+{
+    ExprDef *expr;
+
+    expr = malloc_or_die(sizeof(*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;
+    return expr;
+}
+
+KeycodeDef *
+KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value)
+{
+    KeycodeDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_KEYCODE;
+    def->common.next = NULL;
+    strncpy(def->name, keyName, XkbKeyNameLength);
+    def->value = value;
+    return def;
+}
+
+KeyAliasDef *
+KeyAliasCreate(char alias[XkbKeyNameLength], char real[XkbKeyNameLength])
+{
+    KeyAliasDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_ALIAS;
+    def->common.next = NULL;
+    strncpy(def->alias, alias, XkbKeyNameLength);
+    strncpy(def->real, real, XkbKeyNameLength);
+    return def;
+}
+
+VModDef *
+VModCreate(xkb_atom_t name, ExprDef * value)
+{
+    VModDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_VMOD;
+    def->common.next = NULL;
+    def->name = name;
+    def->value = value;
+    return def;
+}
+
+VarDef *
+VarCreate(ExprDef * name, ExprDef * value)
+{
+    VarDef *def;
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_VAR;
+    def->common.next = NULL;
+    def->name = name;
+    def->value = value;
+    return def;
+}
+
+VarDef *
+BoolVarCreate(xkb_atom_t nameToken, unsigned set)
+{
+    ExprDef *name, *value;
+
+    name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
+    name->value.str = nameToken;
+    value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
+    value->value.uval = set;
+    return VarCreate(name, value);
+}
+
+InterpDef *
+InterpCreate(char *sym, ExprDef * match)
+{
+    InterpDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_INTERP;
+    def->common.next = NULL;
+    def->sym = sym;
+    def->match = match;
+    return def;
+}
+
+KeyTypeDef *
+KeyTypeCreate(xkb_atom_t name, VarDef * body)
+{
+    KeyTypeDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_TYPE;
+    def->common.next = NULL;
+    def->merge = MERGE_DEFAULT;
+    def->name = name;
+    def->body = body;
+    return def;
+}
+
+SymbolsDef *
+SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols)
+{
+    SymbolsDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_SYMBOLS;
+    def->common.next = NULL;
+    def->merge = MERGE_DEFAULT;
+    strncpy(def->keyName, keyName, XkbKeyNameLength);
+    def->symbols = symbols;
+    return def;
+}
+
+GroupCompatDef *
+GroupCompatCreate(int group, ExprDef * val)
+{
+    GroupCompatDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_GROUP_COMPAT;
+    def->common.next = NULL;
+    def->merge = MERGE_DEFAULT;
+    def->group = group;
+    def->def = val;
+    return def;
+}
+
+ModMapDef *
+ModMapCreate(uint32_t modifier, ExprDef * keys)
+{
+    ModMapDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_MODMAP;
+    def->common.next = NULL;
+    def->merge = MERGE_DEFAULT;
+    def->modifier = modifier;
+    def->keys = keys;
+    return def;
+}
+
+IndicatorMapDef *
+IndicatorMapCreate(xkb_atom_t name, VarDef * body)
+{
+    IndicatorMapDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_INDICATOR_MAP;
+    def->common.next = NULL;
+    def->merge = MERGE_DEFAULT;
+    def->name = name;
+    def->body = body;
+    return def;
+}
+
+IndicatorNameDef *
+IndicatorNameCreate(int ndx, ExprDef * name, bool virtual)
+{
+    IndicatorNameDef *def;
+
+    def = malloc_or_die(sizeof(*def));
+
+    def->common.type = STMT_INDICATOR_NAME;
+    def->common.next = NULL;
+    def->merge = MERGE_DEFAULT;
+    def->ndx = ndx;
+    def->name = name;
+    def->virtual = virtual;
+    return def;
+}
+
+ExprDef *
+ActionCreate(xkb_atom_t name, ExprDef * args)
+{
+    ExprDef *act;
+
+    act = malloc_or_die(sizeof(*act));
+
+    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);
+
+IncludeStmt *
+IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
+{
+    IncludeStmt *incl, *first;
+    char *file, *map, *stmt, *tmp, *extra_data;
+    char nextop;
+
+    incl = first = NULL;
+    file = map = NULL;
+    tmp = str;
+    stmt = strdup_safe(str);
+    while (tmp && *tmp)
+    {
+        if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
+            goto err;
+
+        if (first == NULL) {
+            first = incl = malloc(sizeof(*first));
+        } else {
+            incl->next_incl = malloc(sizeof(*first));
+            incl = incl->next_incl;
+        }
+
+        if (!incl) {
+            log_wsgo(ctx,
+                     "Allocation failure in IncludeCreate; "
+                     "Using only part of the include\n");
+            break;
+        }
+
+        incl->common.type = STMT_INCLUDE;
+        incl->common.next = NULL;
+        incl->merge = merge;
+        incl->stmt = NULL;
+        incl->file = file;
+        incl->map = map;
+        incl->modifier = extra_data;
+        incl->next_incl = NULL;
+
+        if (nextop == '|')
+            merge = MERGE_AUGMENT;
+        else
+            merge = MERGE_OVERRIDE;
+    }
+
+    if (first)
+        first->stmt = stmt;
+    else
+        free(stmt);
+
+    return first;
+
+err:
+    log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
+    FreeInclude(first);
+    free(stmt);
+    return NULL;
+}
+
+/*
+ * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
+ * wildcards.
+ */
+static const unsigned char componentSpecLegal[] = {
+    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
+};
+
+static void
+EnsureSafeMapName(char *name)
+{
+    if (!name)
+        return;
+
+    while (*name != '\0') {
+        if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
+            *name = '_';
+        name++;
+    }
+}
+
+XkbFile *
+XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
+              ParseCommon *defs, unsigned flags)
+{
+    XkbFile *file;
+
+    file = calloc(1, sizeof(*file));
+    if (!file)
+        return NULL;
+
+    EnsureSafeMapName(name);
+    file->file_type = type;
+    file->topName = strdup_safe(name);
+    file->name = name;
+    file->defs = defs;
+    file->id = xkb_context_take_file_id(ctx);
+    file->flags = flags;
+    return file;
+}
+
+XkbFile *
+XkbFileFromComponents(struct xkb_context *ctx,
+                      struct xkb_component_names *kkctgs)
+{
+    IncludeStmt *inc;
+    XkbFile *keycodes, *types, *compat, *symbols;
+
+    inc = IncludeCreate(ctx, kkctgs->keycodes, MERGE_DEFAULT);
+    keycodes = XkbFileCreate(ctx, FILE_TYPE_KEYCODES, NULL,
+                             (ParseCommon *) inc, 0);
+
+    inc = IncludeCreate(ctx, kkctgs->types, MERGE_DEFAULT);
+    types = XkbFileCreate(ctx, FILE_TYPE_TYPES, NULL,
+                          (ParseCommon *) inc, 0);
+    AppendStmt(&keycodes->common, &types->common);
+
+    inc = IncludeCreate(ctx, kkctgs->compat, MERGE_DEFAULT);
+    compat = XkbFileCreate(ctx, FILE_TYPE_COMPAT, NULL,
+                           (ParseCommon *) inc, 0);
+    AppendStmt(&keycodes->common, &compat->common);
+
+    inc = IncludeCreate(ctx, kkctgs->symbols, MERGE_DEFAULT);
+    symbols = XkbFileCreate(ctx, FILE_TYPE_SYMBOLS, NULL,
+                            (ParseCommon *) inc, 0);
+    AppendStmt(&keycodes->common, &symbols->common);
+
+    return XkbFileCreate(ctx, FILE_TYPE_KEYMAP, strdup(""),
+                         &keycodes->common, 0);
+}
+
+static void
+FreeExpr(ExprDef *expr)
+{
+    char **sym;
+
+    if (!expr)
+        return;
+
+    switch (expr->op) {
+    case EXPR_ACTION_LIST:
+    case EXPR_NEGATE:
+    case EXPR_UNARY_PLUS:
+    case EXPR_NOT:
+    case EXPR_INVERT:
+        FreeStmt(&expr->value.child->common);
+        break;
+
+    case EXPR_DIVIDE:
+    case EXPR_ADD:
+    case EXPR_SUBTRACT:
+    case EXPR_MULTIPLY:
+    case EXPR_ASSIGN:
+        FreeStmt(&expr->value.binary.left->common);
+        FreeStmt(&expr->value.binary.right->common);
+        break;
+
+    case EXPR_ACTION_DECL:
+        FreeStmt(&expr->value.action.args->common);
+        break;
+
+    case EXPR_ARRAY_REF:
+        FreeStmt(&expr->value.array.entry->common);
+        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);
+        break;
+
+    default:
+        break;
+    }
+}
+
+static void
+FreeInclude(IncludeStmt *incl)
+{
+    IncludeStmt *next;
+
+    while (incl)
+    {
+        next = incl->next_incl;
+
+        free(incl->file);
+        free(incl->map);
+        free(incl->modifier);
+        free(incl->stmt);
+
+        free(incl);
+        incl = next;
+    }
+}
+
+void
+FreeStmt(ParseCommon *stmt)
+{
+    ParseCommon *next;
+    YYSTYPE u;
+
+    while (stmt)
+    {
+        next = stmt->next;
+        u.any = stmt;
+
+        switch (stmt->type) {
+        case STMT_INCLUDE:
+            FreeInclude((IncludeStmt *) stmt);
+            /* stmt is already free'd here. */
+            stmt = NULL;
+            break;
+        case STMT_EXPR:
+            FreeExpr(u.expr);
+            break;
+        case STMT_VAR:
+            FreeStmt(&u.var->name->common);
+            FreeStmt(&u.var->value->common);
+            break;
+        case STMT_TYPE:
+            FreeStmt(&u.keyType->body->common);
+            break;
+        case STMT_INTERP:
+            free(u.interp->sym);
+            FreeStmt(&u.interp->match->common);
+            FreeStmt(&u.interp->def->common);
+            break;
+        case STMT_VMOD:
+            FreeStmt(&u.vmod->value->common);
+            break;
+        case STMT_SYMBOLS:
+            FreeStmt(&u.syms->symbols->common);
+            break;
+        case STMT_MODMAP:
+            FreeStmt(&u.modMask->keys->common);
+            break;
+        case STMT_GROUP_COMPAT:
+            FreeStmt(&u.groupCompat->def->common);
+            break;
+        case STMT_INDICATOR_MAP:
+            FreeStmt(&u.ledMap->body->common);
+            break;
+        case STMT_INDICATOR_NAME:
+            FreeStmt(&u.ledName->name->common);
+            break;
+        default:
+            break;
+        }
+
+        free(stmt);
+        stmt = next;
+    }
+}
+
+void
+FreeXkbFile(XkbFile *file)
+{
+    XkbFile *next;
+
+    while (file)
+    {
+        next = (XkbFile *) file->common.next;
+
+        switch (file->file_type) {
+        case FILE_TYPE_KEYMAP:
+            FreeXkbFile((XkbFile *) file->defs);
+            break;
+
+        case FILE_TYPE_TYPES:
+        case FILE_TYPE_COMPAT:
+        case FILE_TYPE_SYMBOLS:
+        case FILE_TYPE_KEYCODES:
+        case FILE_TYPE_GEOMETRY:
+            FreeStmt(file->defs);
+            break;
+
+        default:
+            break;
+        }
+
+        free(file->name);
+        free(file->topName);
+        free(file);
+        file = next;
+    }
+}
+
+const char *stmt_type_strings[_STMT_NUM_VALUES] = {
+    [STMT_UNKNOWN] = "unknown statement",
+    [STMT_INCLUDE] = "include statement",
+    [STMT_KEYCODE] = "key name definition",
+    [STMT_ALIAS] = "key alias definition",
+    [STMT_EXPR] = "expression",
+    [STMT_VAR] = "variable definition",
+    [STMT_TYPE] = "key type definition",
+    [STMT_INTERP] = "symbol interpretation definition",
+    [STMT_VMOD] = "virtual modifiers definition",
+    [STMT_SYMBOLS] = "key symbols definition",
+    [STMT_MODMAP] = "modifier map declaration",
+    [STMT_GROUP_COMPAT] = "group declaration",
+    [STMT_INDICATOR_MAP] = "indicator map declaration",
+    [STMT_INDICATOR_NAME] = "indicator name declaration",
+};
+
+const char *
+StmtTypeToString(enum stmt_type type)
+{
+    if (type >= _STMT_NUM_VALUES)
+        type = STMT_UNKNOWN;
+    return stmt_type_strings[type];
+}
diff --git a/src/xkbcomp/ast-build.h b/src/xkbcomp/ast-build.h
new file mode 100644 (file)
index 0000000..ec5ef38
--- /dev/null
@@ -0,0 +1,104 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_AST_BUILD_H
+#define XKBCOMP_AST_BUILD_H
+
+ParseCommon *
+AppendStmt(ParseCommon *to, ParseCommon *append);
+
+ExprDef *
+ExprCreate(enum expr_op_type op, enum expr_value_type type);
+
+ExprDef *
+ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
+                ExprDef *child);
+
+ExprDef *
+ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right);
+
+KeycodeDef *
+KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value);
+
+KeyAliasDef *
+KeyAliasCreate(char keyName[XkbKeyNameLength], char real[XkbKeyNameLength]);
+
+VModDef *
+VModCreate(xkb_atom_t name, ExprDef *value);
+
+VarDef *
+VarCreate(ExprDef *name, ExprDef *value);
+
+VarDef *
+BoolVarCreate(xkb_atom_t nameToken, unsigned set);
+
+InterpDef *
+InterpCreate(char *sym, ExprDef *match);
+
+KeyTypeDef *
+KeyTypeCreate(xkb_atom_t name, VarDef *body);
+
+SymbolsDef *
+SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols);
+
+GroupCompatDef *
+GroupCompatCreate(int group, ExprDef *def);
+
+ModMapDef *
+ModMapCreate(uint32_t modifier, ExprDef *keys);
+
+IndicatorMapDef *
+IndicatorMapCreate(xkb_atom_t name, VarDef *body);
+
+IndicatorNameDef *
+IndicatorNameCreate(int ndx, ExprDef *name, bool virtual);
+
+ExprDef *
+ActionCreate(xkb_atom_t name, ExprDef *args);
+
+ExprDef *
+CreateMultiKeysymList(ExprDef *list);
+
+ExprDef *
+CreateKeysymList(char *sym);
+
+ExprDef *
+AppendMultiKeysymList(ExprDef *list, ExprDef *append);
+
+ExprDef *
+AppendKeysymList(ExprDef *list, char *sym);
+
+IncludeStmt *
+IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
+
+XkbFile *
+XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
+              ParseCommon *defs, unsigned flags);
+
+void
+FreeStmt(ParseCommon *stmt);
+
+#endif
diff --git a/src/xkbcomp/ast.h b/src/xkbcomp/ast.h
new file mode 100644 (file)
index 0000000..85741db
--- /dev/null
@@ -0,0 +1,223 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_AST_H
+#define XKBCOMP_AST_H
+
+enum stmt_type {
+    STMT_UNKNOWN = 0,
+    STMT_INCLUDE,
+    STMT_KEYCODE,
+    STMT_ALIAS,
+    STMT_EXPR,
+    STMT_VAR,
+    STMT_TYPE,
+    STMT_INTERP,
+    STMT_VMOD,
+    STMT_SYMBOLS,
+    STMT_MODMAP,
+    STMT_GROUP_COMPAT,
+    STMT_INDICATOR_MAP,
+    STMT_INDICATOR_NAME,
+    _STMT_NUM_VALUES
+};
+
+enum expr_value_type {
+    EXPR_TYPE_UNKNOWN = 0,
+    EXPR_TYPE_BOOLEAN,
+    EXPR_TYPE_INT,
+    EXPR_TYPE_STRING,
+    EXPR_TYPE_ACTION,
+    EXPR_TYPE_KEYNAME,
+    EXPR_TYPE_SYMBOLS,
+};
+
+enum expr_op_type {
+    EXPR_VALUE = 0,
+    EXPR_IDENT,
+    EXPR_ACTION_DECL,
+    EXPR_FIELD_REF,
+    EXPR_ARRAY_REF,
+    EXPR_KEYSYM_LIST,
+    EXPR_ACTION_LIST,
+    EXPR_ADD,
+    EXPR_SUBTRACT,
+    EXPR_MULTIPLY,
+    EXPR_DIVIDE,
+    EXPR_ASSIGN,
+    EXPR_NOT,
+    EXPR_NEGATE,
+    EXPR_INVERT,
+    EXPR_UNARY_PLUS,
+};
+
+enum merge_mode {
+    MERGE_DEFAULT,
+    MERGE_AUGMENT,
+    MERGE_OVERRIDE,
+    MERGE_REPLACE,
+};
+
+typedef struct _ParseCommon {
+    enum stmt_type type;
+    struct _ParseCommon *next;
+} ParseCommon;
+
+typedef struct _IncludeStmt {
+    ParseCommon common;
+    enum merge_mode merge;
+    char *stmt;
+    char *file;
+    char *map;
+    char *modifier;
+    struct _IncludeStmt *next_incl;
+} IncludeStmt;
+
+typedef struct _Expr {
+    ParseCommon common;
+    enum expr_op_type op;
+    enum expr_value_type value_type;
+    union {
+        struct {
+            struct _Expr *left;
+            struct _Expr *right;
+        } binary;
+        struct {
+            xkb_atom_t element;
+            xkb_atom_t field;
+        } field;
+        struct {
+            xkb_atom_t element;
+            xkb_atom_t field;
+            struct _Expr *entry;
+        } array;
+        struct {
+            xkb_atom_t name;
+            struct _Expr *args;
+        } action;
+        struct {
+            darray(char *) syms;
+            darray(int) symsMapIndex;
+            darray(unsigned int) symsNumEntries;
+        } list;
+        struct _Expr *child;
+        xkb_atom_t str;
+        unsigned uval;
+        int ival;
+        char keyName[XkbKeyNameLength];
+    } value;
+} ExprDef;
+
+typedef struct _VarDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    ExprDef *name;
+    ExprDef *value;
+} VarDef;
+
+typedef struct _VModDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    xkb_atom_t name;
+    ExprDef *value;
+} VModDef;
+
+typedef struct _KeycodeDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    char name[XkbKeyNameLength];
+    unsigned long value;
+} KeycodeDef;
+
+typedef struct _KeyAliasDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    char alias[XkbKeyNameLength];
+    char real[XkbKeyNameLength];
+} KeyAliasDef;
+
+typedef struct _KeyTypeDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    xkb_atom_t name;
+    VarDef *body;
+} KeyTypeDef;
+
+typedef struct _SymbolsDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    char keyName[XkbKeyNameLength];
+    ExprDef *symbols;
+} SymbolsDef;
+
+typedef struct _ModMapDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    xkb_atom_t modifier;
+    ExprDef *keys;
+} ModMapDef;
+
+typedef struct _GroupCompatDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    int group;
+    ExprDef *def;
+} GroupCompatDef;
+
+typedef struct _InterpDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    char *sym;
+    ExprDef *match;
+    VarDef *def;
+} InterpDef;
+
+typedef struct _IndicatorNameDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    int ndx;
+    ExprDef *name;
+    bool virtual;
+} IndicatorNameDef;
+
+typedef struct _IndicatorMapDef {
+    ParseCommon common;
+    enum merge_mode merge;
+    xkb_atom_t name;
+    VarDef *body;
+} IndicatorMapDef;
+
+typedef struct _XkbFile {
+    ParseCommon common;
+    enum xkb_file_type file_type;
+    char *topName;
+    char *name;
+    ParseCommon *defs;
+    int id;
+    unsigned flags;
+} XkbFile;
+
+#endif
index b00f64ac6c7e24fc92eff3bf294eb57f9d01406c..e8f394bf079eb0461b9f44705e6c1e765bf7b08c 100644 (file)
  ********************************************************/
 
 #include "xkbcomp-priv.h"
-#include "parseutils.h"
+#include "text.h"
+#include "expr.h"
 #include "action.h"
 #include "vmod.h"
+#include "include.h"
 
 enum si_field {
     SI_FIELD_VIRTUAL_MOD    = (1 << 0),
@@ -607,7 +609,7 @@ HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *stmt)
             next_incl.act = NULL;
 
         ClearCompatInfo(&next_incl);
-        FreeXKBFile(rtrn);
+        FreeXkbFile(rtrn);
     }
 
     MergeIncludedCompatMaps(info, &included, merge);
index aaeba283eeb68ee901d7f62d56da7cac13e0e1c5..98b32eb33631af8cef8d6cbf1117ba3cef3d341f 100644 (file)
@@ -24,6 +24,8 @@
  *
  ********************************************************/
 
+#include "xkbcomp-priv.h"
+#include "text.h"
 #include "expr.h"
 
 typedef bool (*IdentLookupFunc)(struct xkb_context *ctx, const void *priv,
index 7a2bf781977043c9626d0ca787c87cb1d409be43..2771614b28342ce719d3640e3dc895a712f32c37 100644 (file)
  *
  ********************************************************/
 
-#ifndef EXPR_H
-#define EXPR_H 1
-
-#include "xkbcomp-priv.h"
+#ifndef XKBCOMP_EXPR_H
+#define XKBCOMP_EXPR_H
 
 typedef struct _LookupEntry {
     const char *name;
     unsigned int value;
 } LookupEntry;
 
-extern const char *
+const char *
 exprOpText(enum expr_op_type op);
 
 bool
@@ -106,4 +104,4 @@ bool
 ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
                   xkb_keysym_t *sym_rtrn);
 
-#endif /* EXPR_H */
+#endif
diff --git a/src/xkbcomp/include.c b/src/xkbcomp/include.c
new file mode 100644 (file)
index 0000000..a7a8bbc
--- /dev/null
@@ -0,0 +1,283 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "include.h"
+
+/**
+ * Extract the first token from an include statement.
+ * @param str_inout Input statement, modified in-place. Can be passed in
+ * repeatedly. If str_inout is NULL, the parsing has completed.
+ * @param file_rtrn Set to the include file to be used.
+ * @param map_rtrn Set to whatever comes after ), if any.
+ * @param nextop_rtrn Set to the next operation in the complete statement.
+ * @param extra_data Set to the string between ( and ), if any.
+ *
+ * @return true if parsing was succcessful, false for an illegal string.
+ *
+ * Example: "evdev+aliases(qwerty)"
+ *      str_inout = aliases(qwerty)
+ *      nextop_retrn = +
+ *      extra_data = NULL
+ *      file_rtrn = evdev
+ *      map_rtrn = NULL
+ *
+ * 2nd run with "aliases(qwerty)"
+ *      str_inout = NULL
+ *      file_rtrn = aliases
+ *      map_rtrn = qwerty
+ *      extra_data = NULL
+ *      nextop_retrn = ""
+ *
+ */
+bool
+ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
+                char *nextop_rtrn, char **extra_data)
+{
+    char *tmp, *str, *next;
+
+    str = *str_inout;
+
+    /* search for tokens inside the string */
+    next = strpbrk(str, "|+");
+    if (next) {
+        /* set nextop_rtrn to \0, next to next character */
+        *nextop_rtrn = *next;
+        *next++ = '\0';
+    }
+    else {
+        *nextop_rtrn = '\0';
+        next = NULL;
+    }
+
+    /* search for :, store result in extra_data */
+    tmp = strchr(str, ':');
+    if (tmp != NULL) {
+        *tmp++ = '\0';
+        *extra_data = strdup(tmp);
+    }
+    else {
+        *extra_data = NULL;
+    }
+
+    tmp = strchr(str, '(');
+    if (tmp == NULL) {
+        *file_rtrn = strdup(str);
+        *map_rtrn = NULL;
+    }
+    else if (str[0] == '(') {
+        free(*extra_data);
+        return false;
+    }
+    else {
+        *tmp++ = '\0';
+        *file_rtrn = strdup(str);
+        str = tmp;
+        tmp = strchr(str, ')');
+        if ((tmp == NULL) || (tmp[1] != '\0')) {
+            free(*file_rtrn);
+            free(*extra_data);
+            return false;
+        }
+        *tmp++ = '\0';
+        *map_rtrn = strdup(str);
+    }
+
+    if (*nextop_rtrn == '\0')
+        *str_inout = NULL;
+    else if ((*nextop_rtrn == '|') || (*nextop_rtrn == '+'))
+        *str_inout = next;
+    else
+        return false;
+
+    return true;
+}
+
+/***====================================================================***/
+
+/**
+ * Return the xkb directory based on the type.
+ */
+static const char *
+DirectoryForInclude(enum xkb_file_type type)
+{
+    switch (type) {
+    case FILE_TYPE_KEYMAP:
+        return "keymap";
+
+    case FILE_TYPE_KEYCODES:
+        return "keycodes";
+
+    case FILE_TYPE_TYPES:
+        return "types";
+
+    case FILE_TYPE_SYMBOLS:
+        return "symbols";
+
+    case FILE_TYPE_COMPAT:
+        return "compat";
+
+    case FILE_TYPE_GEOMETRY:
+        return "geometry";
+
+    case FILE_TYPE_RULES:
+        return "rules";
+
+    default:
+        return "";
+    }
+}
+
+/***====================================================================***/
+
+/**
+ * Search for the given file name in the include directories.
+ *
+ * @param ctx the XKB ctx containing the include paths
+ * @param type one of FILE_TYPE_TYPES, FILE_TYPE_COMPAT, ..., or
+ *             FILE_TYPE_KEYMAP or FILE_TYPE_RULES
+ * @param pathRtrn is set to the full path of the file if found.
+ *
+ * @return an FD to the file or NULL. If NULL is returned, the value of
+ * pathRtrn is undefined.
+ */
+FILE *
+FindFileInXkbPath(struct xkb_context *ctx, const char *name,
+                  enum xkb_file_type type, char **pathRtrn)
+{
+    size_t i;
+    int ret;
+    FILE *file = NULL;
+    char buf[PATH_MAX];
+    const char *typeDir;
+
+    typeDir = DirectoryForInclude(type);
+    for (i = 0; i < xkb_context_num_include_paths(ctx); i++) {
+        ret = snprintf(buf, sizeof(buf), "%s/%s/%s",
+                       xkb_context_include_path_get(ctx, i), typeDir, name);
+        if (ret >= (ssize_t) sizeof(buf)) {
+            log_err(ctx, "File name (%s/%s/%s) too long\n",
+                    xkb_context_include_path_get(ctx, i), typeDir, name);
+            continue;
+        }
+        file = fopen(buf, "r");
+        if (file == NULL) {
+            log_err(ctx, "Couldn't open file (%s/%s/%s): %s\n",
+                    xkb_context_include_path_get(ctx, i), typeDir, name,
+                    strerror(errno));
+            continue;
+        }
+        break;
+    }
+
+    if ((file != NULL) && (pathRtrn != NULL))
+        *pathRtrn = strdup(buf);
+    return file;
+}
+
+/**
+ * Open the file given in the include statement and parse it's content.
+ * If the statement defines a specific map to use, this map is returned in
+ * file_rtrn. Otherwise, the default map is returned.
+ *
+ * @param ctx The ctx containing include paths
+ * @param stmt The include statement, specifying the file name to look for.
+ * @param file_type Type of file (FILE_TYPE_KEYCODES, etc.)
+ * @param file_rtrn Returns the key map to be used.
+ * @param merge_rtrn Always returns stmt->merge.
+ *
+ * @return true on success or false otherwise.
+ */
+bool
+ProcessIncludeFile(struct xkb_context *ctx,
+                   IncludeStmt * stmt,
+                   enum xkb_file_type file_type,
+                   XkbFile ** file_rtrn, enum merge_mode *merge_rtrn)
+{
+    FILE *file;
+    XkbFile *rtrn, *mapToUse, *next;
+
+    file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL);
+    if (file == NULL) {
+        log_err(ctx, "Can't find file \"%s\" for %s include\n", stmt->file,
+                DirectoryForInclude(file_type));
+        return false;
+    }
+
+    if (!XkbParseFile(ctx, file, stmt->file, &rtrn)) {
+        log_err(ctx, "Error interpreting include file \"%s\"\n", stmt->file);
+        fclose(file);
+        return false;
+    }
+    fclose(file);
+
+    mapToUse = rtrn;
+    if (stmt->map != NULL) {
+        while (mapToUse)
+        {
+            next = (XkbFile *) mapToUse->common.next;
+            mapToUse->common.next = NULL;
+            if (streq(mapToUse->name, stmt->map) &&
+                mapToUse->file_type == file_type) {
+                FreeXkbFile(next);
+                break;
+            }
+            else {
+                FreeXkbFile(mapToUse);
+            }
+            mapToUse = next;
+        }
+        if (!mapToUse) {
+            log_err(ctx, "No %s named \"%s\" in the include file \"%s\"\n",
+                    FileTypeText(file_type), stmt->map, stmt->file);
+            return false;
+        }
+    }
+    else if (rtrn->common.next) {
+        log_lvl(ctx, 5,
+                "No map in include statement, but \"%s\" contains several; "
+                "Using first defined map, \"%s\"\n",
+                stmt->file, rtrn->name);
+    }
+    if (mapToUse->file_type != file_type) {
+        log_err(ctx,
+                "Include file wrong type (expected %s, got %s); "
+                "Include file \"%s\" ignored\n",
+                FileTypeText(file_type), FileTypeText(mapToUse->file_type),
+                stmt->file);
+        return false;
+    }
+    /* FIXME: we have to check recursive includes here (or somewhere) */
+
+    *file_rtrn = mapToUse;
+    *merge_rtrn = stmt->merge;
+    return true;
+}
diff --git a/src/xkbcomp/include.h b/src/xkbcomp/include.h
new file mode 100644 (file)
index 0000000..9ba0b55
--- /dev/null
@@ -0,0 +1,43 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_INCLUDE_H
+#define XKBCOMP_INCLUDE_H
+
+bool
+ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
+                char *nextop_rtrn, char **extra_data);
+
+FILE *
+FindFileInXkbPath(struct xkb_context *ctx, const char *name,
+                  enum xkb_file_type type, char **pathRtrn);
+
+bool
+ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
+                   enum xkb_file_type file_type, XkbFile **file_rtrn,
+                   enum merge_mode *merge_rtrn);
+
+#endif
index 57d73a0a133c84a3e8e99d8bc274fb92c38339d0..c3be7ffd310e51b9f4c04ff42281e9de6f2a3e22 100644 (file)
  ********************************************************/
 
 #include "xkbcomp-priv.h"
+#include "text.h"
 #include "expr.h"
-#include "parseutils.h"
+#include "keycodes.h"
+#include "include.h"
 
 /*
  * The xkb_keycodes section
@@ -563,7 +565,7 @@ HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *stmt)
         MergeIncludedKeycodes(&included, &next_incl, merge);
 
         ClearKeyNamesInfo(&next_incl);
-        FreeXKBFile(rtrn);
+        FreeXkbFile(rtrn);
     }
 
     MergeIncludedKeycodes(info, &included, merge);
diff --git a/src/xkbcomp/keycodes.h b/src/xkbcomp/keycodes.h
new file mode 100644 (file)
index 0000000..cb75250
--- /dev/null
@@ -0,0 +1,65 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_KEYCODES_H
+#define XKBCOMP_KEYCODES_H
+
+static inline unsigned long
+KeyNameToLong(const char name[XkbKeyNameLength])
+{
+    return
+        (((unsigned long)name[0]) << 24) |
+        (((unsigned long)name[1]) << 16) |
+        (((unsigned long)name[2]) << 8)  |
+        (((unsigned long)name[3]) << 0);
+}
+
+static inline void
+LongToKeyName(unsigned long val, char name[XkbKeyNameLength])
+{
+    name[0] = ((val >> 24) & 0xff);
+    name[1] = ((val >> 16) & 0xff);
+    name[2] = ((val >> 8) & 0xff);
+    name[3] = ((val >> 0) & 0xff);
+}
+
+static inline const char *
+LongKeyNameText(unsigned long val)
+{
+    char buf[XkbKeyNameLength];
+    LongToKeyName(val, buf);
+    return KeyNameText(buf);
+}
+
+struct xkb_key *
+FindNamedKey(struct xkb_keymap *keymap, unsigned long name,
+             bool use_aliases, xkb_keycode_t start_from);
+
+bool
+FindKeyNameForAlias(struct xkb_keymap *keymap, unsigned long lname,
+                    unsigned long *real_name);
+
+#endif
diff --git a/src/xkbcomp/keytypes.c b/src/xkbcomp/keytypes.c
deleted file mode 100644 (file)
index 45015ea..0000000
+++ /dev/null
@@ -1,908 +0,0 @@
-/************************************************************
- * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of Silicon Graphics not be
- * used in advertising or publicity pertaining to distribution
- * of the software without specific prior written permission.
- * Silicon Graphics makes no representation about the suitability
- * of this software for any purpose. It is provided "as is"
- * without any express or implied warranty.
- *
- * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- ********************************************************/
-
-#include "xkbcomp-priv.h"
-#include "parseutils.h"
-#include "vmod.h"
-
-/*
- * The xkb_types section
- * =====================
- * This section is the second to be processesed, after xkb_keycodes.
- * However, it is completely independent and could have been the first
- * to be processed (it does not refer to specific keys as specified in
- * the xkb_keycodes section).
- *
- * This section defines key types, which, given a key and a keyboard
- * state (i.e. modifier state and group), determine the shift level to
- * be used in translating the key to keysyms. These types are assigned
- * to each group in each key, in the xkb_symbols section.
- *
- * Key types are called this way because, in a way, they really describe
- * the "type" of the key (or more correctly, a specific group of the
- * key). For example, an ordinary keymap will provide a type called
- * "KEYPAD", which consists of two levels, with the second level being
- * chosen according to the state of the Num Lock (or Shift) modifiers.
- * Another example is a type called "ONE_LEVEL", which is usually
- * assigned to keys such as Escape; these have just one level and are
- * not affected by the modifier state. Yet more common examples are
- * "TWO_LEVEL" (with Shift choosing the second level), "ALPHABETIC"
- * (where Caps Lock may also choose the second level), etc.
- *
- * Type definitions
- * ----------------
- *  Statements of the form:
- *      type "FOUR_LEVEL" { ... }
- *
- * The above would create a new type named "FOUR_LEVEL".
- * The body of the definition may include statements of the following
- * forms:
- *
- * - level_name statements (mandatory for each level in the type):
- *      level_name[Level1] = "Base";
- *
- *   Gives each level in this type a descriptive name. It isn't used
- *   for any thing.
- *   Note: A level may be specified as Level[1-8] or just a number (can
- *   be more than 8).
- *
- * - modifiers statement (mandatory, should be specified only once):
- *      modifiers = Shift+Lock+LevelThree;
- *
- *   A mask of real and virtual modifiers. These are the only modifiers
- *   being considered when matching the modifier state against the type.
- *   The other modifiers, whether active or not, are masked out in the
- *   calculation.
- *
- * - map entry statements (should have at least as many mappings as there
- *   are levels in the type):
- *      map[Shift+LevelThree] = Level4;
- *
- *   If the active modifiers, masked with the type's modifiers (as stated
- *   above), match (i.e. equal) the modifiers inside the map[] statement,
- *   then the level in the right hand side is chosen. For example, in the
- *   above, if in the current keyboard state the Shift and LevelThree
- *   modifiers are active, while the Lock modifier is not, then the
- *   keysym(s) in the 4th level of the group will be returned to the
- *   user.
- *
- * - preserve statements:
- *      map[Shift+Lock+LevelThree] = Level5;
- *      preserve[Shift+Lock+LevelThree] = Lock;
- *
- *   When a map entry matches the active modifiers and the level it
- *   specified is chosen, then these modifiers are said to be "consumed";
- *   for example, in a simple US keymap where the "g" key is assigned an
- *   ordinary ALPHABETIC key type, if the Lock (Caps Lock) modifier is
- *   active and the key is pressed, then a "G" keysym is produced (as
- *   opposed to lower-case "g"). This is because the type definition has
- *   a map entry like the following:
- *      map[Lock] = Level2;
- *   And as such the Lock modifier is consumed. This information is
- *   relevant for applications which further process the modifiers,
- *   since by then the consumed modifiers have already "done their part"
- *   and should be masked out.
- *
- *   However, sometimes even if a modifier is actually used to choose
- *   the shift level (as Lock above), it should *not* be reported as
- *   consumed, for various reasons. In this case, a preserve[] statement
- *   can be used to augment the map entry. The modifiers inside the square
- *   brackets should match one of the map[] statements in the type. The
- *   right hand side should consists of modifiers from the left hand
- *   side; these modifiers are then "preserved" and not reported as
- *   consumed.
- *
- * Virtual modifier statements
- * ---------------------------
- * Statements of the form:
- *     virtual_modifiers LControl;
- *
- * Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
- * TODO
- */
-
-enum type_field {
-    TYPE_FIELD_MASK       = (1 << 0),
-    TYPE_FIELD_MAP        = (1 << 1),
-    TYPE_FIELD_PRESERVE   = (1 << 2),
-    TYPE_FIELD_LEVEL_NAME = (1 << 3),
-};
-
-typedef struct _KeyTypeInfo {
-    enum type_field defined;
-    unsigned file_id;
-    enum merge_mode merge;
-    struct list entry;
-
-    xkb_atom_t name;
-    xkb_mod_mask_t mods;
-    xkb_level_index_t num_levels;
-    darray(struct xkb_kt_map_entry) entries;
-    darray(xkb_atom_t) level_names;
-} KeyTypeInfo;
-
-typedef struct _KeyTypesInfo {
-    char *name;
-    int errorCount;
-    unsigned file_id;
-    unsigned num_types;
-    struct list types;
-    VModInfo vmods;
-    struct xkb_keymap *keymap;
-} KeyTypesInfo;
-
-/***====================================================================***/
-
-static inline const char *
-MapEntryTxt(KeyTypesInfo *info, struct xkb_kt_map_entry *entry)
-{
-    return VModMaskText(info->keymap, entry->mods.mods);
-}
-
-static inline const char *
-TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type)
-{
-    return xkb_atom_text(info->keymap->ctx, type->name);
-}
-
-static inline const char *
-TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type)
-{
-    return VModMaskText(info->keymap, type->mods);
-}
-
-static inline bool
-ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type,
-                        const char *field)
-{
-    return ReportShouldBeArray(info->keymap, "key type", field,
-                               TypeTxt(info, type));
-}
-
-static inline bool
-ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
-                  const char *field, const char *wanted)
-{
-    return ReportBadType(info->keymap->ctx, "key type", field,
-                         TypeTxt(info, type), wanted);
-}
-
-static inline bool
-ReportTypeBadWidth(KeyTypesInfo *info, const char *type, int has, int needs)
-{
-    log_err(info->keymap->ctx,
-            "Key type \"%s\" has %d levels, must have %d; "
-            "Illegal type definition ignored\n",
-            type, has, needs);
-    return false;
-}
-
-/***====================================================================***/
-
-static void
-InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
-                 unsigned file_id)
-{
-    info->name = strdup("default");
-    info->errorCount = 0;
-    info->num_types = 0;
-    list_init(&info->types);
-    info->file_id = file_id;
-    InitVModInfo(&info->vmods, keymap);
-    info->keymap = keymap;
-}
-
-static void
-FreeKeyTypeInfo(KeyTypeInfo * type)
-{
-    darray_free(type->entries);
-    darray_free(type->level_names);
-}
-
-static void
-FreeKeyTypesInfo(KeyTypesInfo * info)
-{
-    KeyTypeInfo *type, *next_type;
-    free(info->name);
-    info->name = NULL;
-    list_foreach_safe(type, next_type, &info->types, entry) {
-        FreeKeyTypeInfo(type);
-        free(type);
-    }
-}
-
-static KeyTypeInfo *
-NextKeyType(KeyTypesInfo * info)
-{
-    KeyTypeInfo *type;
-
-    type = calloc(1, sizeof(*type));
-    if (!type)
-        return NULL;
-
-    type->file_id = info->file_id;
-
-    list_append(&type->entry, &info->types);
-    info->num_types++;
-    return type;
-}
-
-static KeyTypeInfo *
-FindMatchingKeyType(KeyTypesInfo *info, xkb_atom_t name)
-{
-    KeyTypeInfo *old;
-
-    list_foreach(old, &info->types, entry)
-        if (old->name == name)
-            return old;
-
-    return NULL;
-}
-
-static bool
-AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new)
-{
-    KeyTypeInfo *old;
-    struct list entry;
-    int verbosity = xkb_get_log_verbosity(info->keymap->ctx);
-
-    old = FindMatchingKeyType(info, new->name);
-    if (old) {
-        if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) {
-            if ((old->file_id == new->file_id && verbosity > 0) ||
-                verbosity > 9) {
-                log_warn(info->keymap->ctx,
-                         "Multiple definitions of the %s key type; "
-                         "Earlier definition ignored\n",
-                         xkb_atom_text(info->keymap->ctx, new->name));
-            }
-
-            entry = old->entry;
-            FreeKeyTypeInfo(old);
-            *old = *new;
-            old->entry = entry;
-            darray_init(new->entries);
-            darray_init(new->level_names);
-            return true;
-        }
-
-        if (old->file_id == new->file_id)
-            log_lvl(info->keymap->ctx, 4,
-                    "Multiple definitions of the %s key type; "
-                    "Later definition ignored\n",
-                    xkb_atom_text(info->keymap->ctx, new->name));
-
-        FreeKeyTypeInfo(new);
-        return true;
-    }
-
-    old = NextKeyType(info);
-    if (!old)
-        return false;
-
-    entry = old->entry;
-    *old = *new;
-    old->entry = entry;
-    darray_init(new->entries);
-    darray_init(new->level_names);
-    return true;
-}
-
-/***====================================================================***/
-
-static void
-MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
-                      enum merge_mode merge)
-{
-    KeyTypeInfo *type, *next_type;
-
-    if (from->errorCount > 0) {
-        into->errorCount += from->errorCount;
-        return;
-    }
-
-    if (into->name == NULL) {
-        into->name = from->name;
-        from->name = NULL;
-    }
-
-    list_foreach_safe(type, next_type, &from->types, entry) {
-        type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
-        if (!AddKeyType(into, type))
-            into->errorCount++;
-    }
-}
-
-static void
-HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge);
-
-static bool
-HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *stmt)
-{
-    enum merge_mode merge = MERGE_DEFAULT;
-    XkbFile *rtrn;
-    KeyTypesInfo included, next_incl;
-
-    InitKeyTypesInfo(&included, info->keymap, info->file_id);
-    if (stmt->stmt) {
-        free(included.name);
-        included.name = stmt->stmt;
-        stmt->stmt = NULL;
-    }
-
-    for (; stmt; stmt = stmt->next_incl) {
-        if (!ProcessIncludeFile(info->keymap->ctx, stmt, FILE_TYPE_TYPES,
-                                &rtrn, &merge)) {
-            info->errorCount += 10;
-            FreeKeyTypesInfo(&included);
-            return false;
-        }
-
-        InitKeyTypesInfo(&next_incl, info->keymap, rtrn->id);
-
-        HandleKeyTypesFile(&next_incl, rtrn, merge);
-
-        MergeIncludedKeyTypes(&included, &next_incl, merge);
-
-        FreeKeyTypesInfo(&next_incl);
-        FreeXKBFile(rtrn);
-    }
-
-    MergeIncludedKeyTypes(info, &included, merge);
-    FreeKeyTypesInfo(&included);
-
-    return (info->errorCount == 0);
-}
-
-/***====================================================================***/
-
-static bool
-SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
-             ExprDef *value)
-{
-    xkb_mod_mask_t mods;
-
-    if (arrayNdx)
-        log_warn(info->keymap->ctx,
-                 "The modifiers field of a key type is not an array; "
-                 "Illegal array subscript ignored\n");
-
-    /* get modifier mask for current type */
-    if (!ExprResolveVModMask(info->keymap, value, &mods)) {
-        log_err(info->keymap->ctx,
-                "Key type mask field must be a modifier mask; "
-                "Key type definition ignored\n");
-        return false;
-    }
-
-    if (type->defined & TYPE_FIELD_MASK) {
-        log_warn(info->keymap->ctx,
-                 "Multiple modifier mask definitions for key type %s; "
-                 "Using %s, ignoring %s\n",
-                 xkb_atom_text(info->keymap->ctx, type->name),
-                 TypeMaskTxt(info, type),
-                 VModMaskText(info->keymap, mods));
-        return false;
-    }
-
-    type->mods = mods;
-    return true;
-}
-
-/***====================================================================***/
-
-static struct xkb_kt_map_entry *
-FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods)
-{
-    struct xkb_kt_map_entry *entry;
-
-    darray_foreach(entry, type->entries)
-        if (entry->mods.mods == mods)
-            return entry;
-
-    return NULL;
-}
-
-/**
- * Add a new KTMapEntry to the given key type. If an entry with the same mods
- * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
- * entry is created.
- *
- * @param clobber Overwrite existing entry.
- * @param report true if a warning is to be printed on.
- */
-static bool
-AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
-            struct xkb_kt_map_entry *new, bool clobber, bool report)
-{
-    struct xkb_kt_map_entry * old;
-
-    old = FindMatchingMapEntry(type, new->mods.mods);
-    if (old) {
-        if (report && old->level != new->level) {
-            log_warn(info->keymap->ctx,
-                     "Multiple map entries for %s in %s; "
-                     "Using %d, ignoring %d\n",
-                     MapEntryTxt(info, new), TypeTxt(info, type),
-                     (clobber ? new->level : old->level) + 1,
-                     (clobber ? old->level : new->level) + 1);
-        }
-        else {
-            log_lvl(info->keymap->ctx, 10,
-                    "Multiple occurences of map[%s]= %d in %s; Ignored\n",
-                    MapEntryTxt(info, new), new->level + 1,
-                    TypeTxt(info, type));
-            return true;
-        }
-
-        if (clobber) {
-            if (new->level >= type->num_levels)
-                type->num_levels = new->level + 1;
-            old->level = new->level;
-        }
-
-        return true;
-    }
-
-    if (new->level >= type->num_levels)
-        type->num_levels = new->level + 1;
-
-    darray_append(type->entries, *new);
-    return true;
-}
-
-static bool
-SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
-            ExprDef *value)
-{
-    struct xkb_kt_map_entry entry;
-
-    if (arrayNdx == NULL)
-        return ReportTypeShouldBeArray(info, type, "map entry");
-
-    if (!ExprResolveVModMask(info->keymap, arrayNdx, &entry.mods.mods))
-        return ReportTypeBadType(info, type, "map entry", "modifier mask");
-
-    if (entry.mods.mods & (~type->mods)) {
-        log_lvl(info->keymap->ctx, 1,
-                "Map entry for unused modifiers in %s; "
-                "Using %s instead of %s\n",
-                TypeTxt(info, type),
-                VModMaskText(info->keymap, entry.mods.mods & type->mods),
-                MapEntryTxt(info, &entry));
-        entry.mods.mods &= type->mods;
-    }
-
-    if (!ExprResolveLevel(info->keymap->ctx, value, &entry.level)) {
-        log_err(info->keymap->ctx,
-                "Level specifications in a key type must be integer; "
-                "Ignoring malformed level specification\n");
-        return false;
-    }
-
-    entry.preserve.mods = 0;
-
-    return AddMapEntry(info, type, &entry, true, true);
-}
-
-/***====================================================================***/
-
-static bool
-AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
-            xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods)
-{
-    struct xkb_kt_map_entry *entry;
-    struct xkb_kt_map_entry new;
-
-    darray_foreach(entry, type->entries) {
-        if (entry->mods.mods != mods)
-            continue;
-
-        /* Map exists without previous preserve (or "None"); override. */
-        if (entry->preserve.mods == 0) {
-            entry->preserve.mods = preserve_mods;
-            return true;
-        }
-
-        /* Map exists with same preserve; do nothing. */
-        if (entry->preserve.mods == preserve_mods) {
-            log_lvl(info->keymap->ctx, 10,
-                    "Identical definitions for preserve[%s] in %s; "
-                    "Ignored\n",
-                    VModMaskText(info->keymap, mods),
-                    TypeTxt(info, type));
-            return true;
-        }
-
-        /* Map exists with different preserve; latter wins. */
-        log_lvl(info->keymap->ctx, 1,
-                "Multiple definitions for preserve[%s] in %s; "
-                "Using %s, ignoring %s\n",
-                VModMaskText(info->keymap, mods),
-                TypeTxt(info, type),
-                VModMaskText(info->keymap, preserve_mods),
-                VModMaskText(info->keymap, entry->preserve.mods));
-
-        entry->preserve.mods = preserve_mods;
-        return true;
-    }
-
-    /*
-     * Map does not exist, i.e. preserve[] came before map[].
-     * Create a map with the specified mask mapping to Level1. The level
-     * may be overriden later with an explicit map[] statement.
-     */
-    new.level = 0;
-    new.mods.mods = mods;
-    new.preserve.mods = preserve_mods;
-    darray_append(type->entries, new);
-    return true;
-}
-
-static bool
-SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
-            ExprDef *value)
-{
-    xkb_mod_mask_t mods, preserve_mods;
-
-    if (arrayNdx == NULL)
-        return ReportTypeShouldBeArray(info, type, "preserve entry");
-
-    if (!ExprResolveVModMask(info->keymap, arrayNdx, &mods))
-        return ReportTypeBadType(info, type, "preserve entry",
-                                 "modifier mask");
-
-    if (mods & ~type->mods) {
-        const char *before, *after;
-
-        before = VModMaskText(info->keymap, mods);
-        mods &= type->mods;
-        after = VModMaskText(info->keymap, mods);
-
-        log_lvl(info->keymap->ctx, 1,
-                "Preserve for modifiers not used by the %s type; "
-                "Index %s converted to %s\n",
-                TypeTxt(info, type), before, after);
-    }
-
-    if (!ExprResolveVModMask(info->keymap, value, &preserve_mods)) {
-        log_err(info->keymap->ctx,
-                "Preserve value in a key type is not a modifier mask; "
-                "Ignoring preserve[%s] in type %s\n",
-                VModMaskText(info->keymap, mods),
-                TypeTxt(info, type));
-        return false;
-    }
-
-    if (preserve_mods & ~mods) {
-        const char *before, *after;
-
-        before = VModMaskText(info->keymap, preserve_mods);
-        preserve_mods &= mods;
-        after = VModMaskText(info->keymap, preserve_mods);
-
-        log_lvl(info->keymap->ctx, 1,
-                "Illegal value for preserve[%s] in type %s; "
-                "Converted %s to %s\n",
-                VModMaskText(info->keymap, mods),
-                TypeTxt(info, type), before, after);
-    }
-
-    return AddPreserve(info, type, mods, preserve_mods);
-}
-
-/***====================================================================***/
-
-static bool
-AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type,
-             xkb_level_index_t level, xkb_atom_t name, bool clobber)
-{
-    /* New name. */
-    if (level >= darray_size(type->level_names)) {
-        darray_resize0(type->level_names, level + 1);
-        goto finish;
-    }
-
-    /* Same level, same name. */
-    if (darray_item(type->level_names, level) == name) {
-        log_lvl(info->keymap->ctx, 10,
-                "Duplicate names for level %d of key type %s; Ignored\n",
-                level + 1, TypeTxt(info, type));
-        return true;
-    }
-
-    /* Same level, different name. */
-    if (darray_item(type->level_names, level) != XKB_ATOM_NONE) {
-        const char *old, *new;
-        old = xkb_atom_text(info->keymap->ctx,
-                            darray_item(type->level_names, level));
-        new = xkb_atom_text(info->keymap->ctx, name);
-        log_lvl(info->keymap->ctx, 1,
-                "Multiple names for level %d of key type %s; "
-                "Using %s, ignoring %s\n",
-                level + 1, TypeTxt(info, type),
-                (clobber ? new : old), (clobber ? old : new));
-
-        if (!clobber)
-            return true;
-    }
-
-    /* XXX: What about different level, same name? */
-
-finish:
-    darray_item(type->level_names, level) = name;
-    return true;
-}
-
-static bool
-SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
-             ExprDef *value)
-{
-    xkb_level_index_t level;
-    xkb_atom_t level_name;
-    struct xkb_context *ctx = info->keymap->ctx;
-    const char *str;
-
-    if (arrayNdx == NULL)
-        return ReportTypeShouldBeArray(info, type, "level name");
-
-    if (!ExprResolveLevel(ctx, arrayNdx, &level))
-        return ReportTypeBadType(info, type, "level name", "integer");
-
-    if (!ExprResolveString(ctx, value, &str)) {
-        log_err(info->keymap->ctx,
-                "Non-string name for level %d in key type %s; "
-                "Ignoring illegal level name definition\n",
-                level + 1, xkb_atom_text(ctx, type->name));
-        return false;
-    }
-
-    level_name = xkb_atom_intern(ctx, str);
-
-    return AddLevelName(info, type, level, level_name, true);
-}
-
-/***====================================================================***/
-
-/**
- * Parses the fields in a type "..." { } description.
- *
- * @param field The field to parse (e.g. modifiers, map, level_name)
- */
-static bool
-SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type,
-                const char *field, ExprDef *arrayNdx, ExprDef *value)
-{
-    bool ok = false;
-    enum type_field type_field = 0;
-
-    if (istreq(field, "modifiers")) {
-        type_field = TYPE_FIELD_MASK;
-        ok = SetModifiers(info, type, arrayNdx, value);
-    }
-    else if (istreq(field, "map")) {
-        type_field = TYPE_FIELD_MAP;
-        ok = SetMapEntry(info, type, arrayNdx, value);
-    }
-    else if (istreq(field, "preserve")) {
-        type_field = TYPE_FIELD_PRESERVE;
-        ok = SetPreserve(info, type, arrayNdx, value);
-    }
-    else if (istreq(field, "levelname") || istreq(field, "level_name")) {
-        type_field = TYPE_FIELD_LEVEL_NAME;
-        ok = SetLevelName(info, type, arrayNdx, value);
-    } else {
-        log_err(info->keymap->ctx,
-                "Unknown field %s in key type %s; Definition ignored\n",
-                field, TypeTxt(info, type));
-    }
-
-    type->defined |= type_field;
-    return ok;
-}
-
-static bool
-HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type)
-{
-    bool ok = true;
-    const char *elem, *field;
-    ExprDef *arrayNdx;
-
-    for (; def; def = (VarDef *) def->common.next) {
-        ok = ExprResolveLhs(info->keymap->ctx, def->name, &elem, &field,
-                            &arrayNdx);
-        if (!ok)
-            continue;
-
-        if (elem && istreq(elem, "type")) {
-            log_err(info->keymap->ctx,
-                    "Support for changing the default type has been removed; "
-                    "Statement ignored\n");
-            continue;
-        }
-
-        ok = SetKeyTypeField(info, type, field, arrayNdx, def->value);
-    }
-
-    return ok;
-}
-
-/**
- * Process a type "XYZ" { } specification in the xkb_types section.
- *
- */
-static bool
-HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge)
-{
-    KeyTypeInfo type = {
-        .defined = 0,
-        .file_id = info->file_id,
-        .merge = (def->merge == MERGE_DEFAULT ? merge : def->merge),
-        .name = def->name,
-        .mods = 0,
-        .num_levels = 1,
-        .entries = darray_new(),
-        .level_names = darray_new(),
-    };
-
-    /* Parse the actual content. */
-    if (!HandleKeyTypeBody(info, def->body, &type)) {
-        info->errorCount++;
-        return false;
-    }
-
-    /* Now add the new keytype to the info struct */
-    if (!AddKeyType(info, &type)) {
-        info->errorCount++;
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * Process an xkb_types section.
- *
- * @param file The parsed xkb_types section.
- * @param merge Merge Strategy (e.g. MERGE_OVERRIDE)
- * @param info Pointer to memory where the outcome will be stored.
- */
-static void
-HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
-{
-    bool ok;
-    ParseCommon *stmt;
-
-    free(info->name);
-    info->name = strdup_safe(file->name);
-
-    for (stmt = file->defs; stmt; stmt = stmt->next) {
-        switch (stmt->type) {
-        case STMT_INCLUDE:
-            ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt);
-            break;
-        case STMT_TYPE: /* e.g. type "ONE_LEVEL" */
-            ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge);
-            break;
-        case STMT_VAR:
-            log_err(info->keymap->ctx,
-                    "Support for changing the default type has been removed; "
-                    "Statement ignored\n");
-            ok = true;
-            break;
-        case STMT_VMOD: /* virtual_modifiers NumLock, ... */
-            ok = HandleVModDef((VModDef *) stmt, info->keymap, merge,
-                               &info->vmods);
-            break;
-        default:
-            log_err(info->keymap->ctx,
-                    "Key type files may not include other declarations; "
-                    "Ignoring %s\n", StmtTypeToString(stmt->type));
-            ok = false;
-            break;
-        }
-
-        if (!ok)
-            info->errorCount++;
-
-        if (info->errorCount > 10) {
-            log_err(info->keymap->ctx,
-                    "Abandoning keytypes file \"%s\"\n", file->topName);
-            break;
-        }
-    }
-}
-
-static bool
-CopyDefToKeyType(KeyTypesInfo *info, KeyTypeInfo *def,
-                 struct xkb_key_type *type)
-{
-    type->mods.mods = def->mods;
-    type->num_levels = def->num_levels;
-    type->map = darray_mem(def->entries, 0);
-    type->num_entries = darray_size(def->entries);
-    darray_init(def->entries);
-    type->name = def->name;
-    type->level_names = darray_mem(def->level_names, 0);
-    darray_init(def->level_names);
-
-    return true;
-}
-
-bool
-CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
-                enum merge_mode merge)
-{
-    unsigned int i;
-    unsigned int num_types;
-    KeyTypesInfo info;
-    KeyTypeInfo *def;
-
-    InitKeyTypesInfo(&info, keymap, file->id);
-
-    HandleKeyTypesFile(&info, file, merge);
-
-    if (info.errorCount != 0)
-        goto err_info;
-
-    if (info.name)
-        keymap->types_section_name = strdup(info.name);
-
-    num_types = info.num_types ? info.num_types : 1;
-    keymap->types = calloc(num_types, sizeof(*keymap->types));
-    if (!keymap->types)
-        goto err_info;
-    keymap->num_types = num_types;
-
-    /*
-     * If no types were specified, a default unnamed one-level type is
-     * used for all keys.
-     */
-    if (info.num_types == 0) {
-        KeyTypeInfo dflt = {
-            .name = xkb_atom_intern(keymap->ctx, "default"),
-            .mods = 0,
-            .num_levels = 1,
-            .entries = darray_new(),
-            .level_names = darray_new(),
-        };
-
-        if (!CopyDefToKeyType(&info, &dflt, &keymap->types[0]))
-            goto err_info;
-    } else {
-        i = 0;
-        list_foreach(def, &info.types, entry)
-            if (!CopyDefToKeyType(&info, def, &keymap->types[i++]))
-                goto err_info;
-    }
-
-    FreeKeyTypesInfo(&info);
-    return true;
-
-err_info:
-    FreeKeyTypesInfo(&info);
-    return false;
-}
diff --git a/src/xkbcomp/parser-priv.h b/src/xkbcomp/parser-priv.h
new file mode 100644 (file)
index 0000000..17db6ed
--- /dev/null
@@ -0,0 +1,48 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_PARSER_PRIV_H
+#define XKBCOMP_PARSER_PRIV_H
+
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+
+struct scanner_extra;
+
+struct parser_param {
+    struct xkb_context *ctx;
+    void *scanner;
+    XkbFile *rtrn;
+};
+
+#include "parser.h"
+
+void
+scanner_error(YYLTYPE *loc, void *scanner, const char *msg);
+
+int
+yylex(YYSTYPE *val, YYLTYPE *loc, void *scanner);
+
+#endif
index 5d8e0800f8b65d60054935d9f70f2af32a4b22dc..b038371fdd4f6a5343ff77f5a1ee5b5b41321a5d 100644 (file)
 
 %{
 #include "xkbcomp-priv.h"
-#include "parseutils.h"
-
-#pragma GCC diagnostic ignored "-Wredundant-decls"
-
-extern int yylex(union YYSTYPE *val, struct YYLTYPE *loc, void *scanner);
+#include "ast-build.h"
+#include "parser-priv.h"
 
 static void
 yyerror(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
@@ -193,7 +190,7 @@ XkbCompMapList  :       XkbCompMapList XkbCompositeMap
 XkbCompositeMap :       OptFlags XkbCompositeType OptMapName OBRACE
                             XkbMapConfigList
                         CBRACE SEMI
-                        { $$ = CreateXKBFile(param->ctx, $2, $3, &$5->common, $1); }
+                        { $$ = XkbFileCreate(param->ctx, $2, $3, &$5->common, $1); }
                 ;
 
 XkbCompositeType:       XKB_KEYMAP      { $$ = FILE_TYPE_KEYMAP; }
@@ -222,7 +219,7 @@ XkbMapConfig    :       OptFlags FileType OptMapName OBRACE
                                 $$ = NULL;
                             }
                             else {
-                                $$ = CreateXKBFile(param->ctx, $2, $3, $5, $1);
+                                $$ = XkbFileCreate(param->ctx, $2, $3, $5, $1);
                             }
                         }
                 ;
@@ -235,7 +232,7 @@ XkbConfig       :       OptFlags FileType OptMapName DeclList
                                 $$ = NULL;
                             }
                             else {
-                                $$ = CreateXKBFile(param->ctx, $2, $3, $4, $1);
+                                $$ = XkbFileCreate(param->ctx, $2, $3, $4, $1);
                             }
                         }
                 ;
diff --git a/src/xkbcomp/parseutils.c b/src/xkbcomp/parseutils.c
deleted file mode 100644 (file)
index fb6271d..0000000
+++ /dev/null
@@ -1,693 +0,0 @@
-/************************************************************
- * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of Silicon Graphics not be
- * used in advertising or publicity pertaining to distribution
- * of the software without specific prior written permission.
- * Silicon Graphics makes no representation about the suitability
- * of this software for any purpose. It is provided "as is"
- * without any express or implied warranty.
- *
- * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- ********************************************************/
-
-#include "parseutils.h"
-#include "path.h"
-
-ATTR_MALLOC static void *
-malloc_or_die(size_t size)
-{
-    void *p = malloc(size);
-    if (!p) {
-        fprintf(stderr, "Out of memory\n");
-        exit(1);
-    }
-    return p;
-}
-
-ParseCommon *
-AppendStmt(ParseCommon * to, ParseCommon * append)
-{
-    ParseCommon *start = to;
-
-    if (append == NULL)
-        return to;
-    while ((to != NULL) && (to->next != NULL))
-    {
-        to = to->next;
-    }
-    if (to) {
-        to->next = append;
-        return start;
-    }
-    return append;
-}
-
-ExprDef *
-ExprCreate(enum expr_op_type op, enum expr_value_type type)
-{
-    ExprDef *expr;
-
-    expr = malloc_or_die(sizeof(*expr));
-
-    expr->common.type = STMT_EXPR;
-    expr->common.next = NULL;
-    expr->op = op;
-    expr->value_type = type;
-    return expr;
-}
-
-ExprDef *
-ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
-                ExprDef *child)
-{
-    ExprDef *expr;
-    expr = malloc_or_die(sizeof(*expr));
-
-    expr->common.type = STMT_EXPR;
-    expr->common.next = NULL;
-    expr->op = op;
-    expr->value_type = type;
-    expr->value.child = child;
-    return expr;
-}
-
-ExprDef *
-ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
-{
-    ExprDef *expr;
-
-    expr = malloc_or_die(sizeof(*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;
-    return expr;
-}
-
-KeycodeDef *
-KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value)
-{
-    KeycodeDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_KEYCODE;
-    def->common.next = NULL;
-    strncpy(def->name, keyName, XkbKeyNameLength);
-    def->value = value;
-    return def;
-}
-
-KeyAliasDef *
-KeyAliasCreate(char alias[XkbKeyNameLength], char real[XkbKeyNameLength])
-{
-    KeyAliasDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_ALIAS;
-    def->common.next = NULL;
-    strncpy(def->alias, alias, XkbKeyNameLength);
-    strncpy(def->real, real, XkbKeyNameLength);
-    return def;
-}
-
-VModDef *
-VModCreate(xkb_atom_t name, ExprDef * value)
-{
-    VModDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_VMOD;
-    def->common.next = NULL;
-    def->name = name;
-    def->value = value;
-    return def;
-}
-
-VarDef *
-VarCreate(ExprDef * name, ExprDef * value)
-{
-    VarDef *def;
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_VAR;
-    def->common.next = NULL;
-    def->name = name;
-    def->value = value;
-    return def;
-}
-
-VarDef *
-BoolVarCreate(xkb_atom_t nameToken, unsigned set)
-{
-    ExprDef *name, *value;
-
-    name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
-    name->value.str = nameToken;
-    value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
-    value->value.uval = set;
-    return VarCreate(name, value);
-}
-
-InterpDef *
-InterpCreate(char *sym, ExprDef * match)
-{
-    InterpDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_INTERP;
-    def->common.next = NULL;
-    def->sym = sym;
-    def->match = match;
-    return def;
-}
-
-KeyTypeDef *
-KeyTypeCreate(xkb_atom_t name, VarDef * body)
-{
-    KeyTypeDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_TYPE;
-    def->common.next = NULL;
-    def->merge = MERGE_DEFAULT;
-    def->name = name;
-    def->body = body;
-    return def;
-}
-
-SymbolsDef *
-SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols)
-{
-    SymbolsDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_SYMBOLS;
-    def->common.next = NULL;
-    def->merge = MERGE_DEFAULT;
-    strncpy(def->keyName, keyName, XkbKeyNameLength);
-    def->symbols = symbols;
-    return def;
-}
-
-GroupCompatDef *
-GroupCompatCreate(int group, ExprDef * val)
-{
-    GroupCompatDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_GROUP_COMPAT;
-    def->common.next = NULL;
-    def->merge = MERGE_DEFAULT;
-    def->group = group;
-    def->def = val;
-    return def;
-}
-
-ModMapDef *
-ModMapCreate(uint32_t modifier, ExprDef * keys)
-{
-    ModMapDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_MODMAP;
-    def->common.next = NULL;
-    def->merge = MERGE_DEFAULT;
-    def->modifier = modifier;
-    def->keys = keys;
-    return def;
-}
-
-IndicatorMapDef *
-IndicatorMapCreate(xkb_atom_t name, VarDef * body)
-{
-    IndicatorMapDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_INDICATOR_MAP;
-    def->common.next = NULL;
-    def->merge = MERGE_DEFAULT;
-    def->name = name;
-    def->body = body;
-    return def;
-}
-
-IndicatorNameDef *
-IndicatorNameCreate(int ndx, ExprDef * name, bool virtual)
-{
-    IndicatorNameDef *def;
-
-    def = malloc_or_die(sizeof(*def));
-
-    def->common.type = STMT_INDICATOR_NAME;
-    def->common.next = NULL;
-    def->merge = MERGE_DEFAULT;
-    def->ndx = ndx;
-    def->name = name;
-    def->virtual = virtual;
-    return def;
-}
-
-ExprDef *
-ActionCreate(xkb_atom_t name, ExprDef * args)
-{
-    ExprDef *act;
-
-    act = malloc_or_die(sizeof(*act));
-
-    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;
-}
-
-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 1;
-    }
-
-    if (istreq(str, "none") || istreq(str, "voidsymbol")) {
-        *sym_rtrn = XKB_KEY_VoidSymbol;
-        return 1;
-    }
-
-    sym = xkb_keysym_from_name(str);
-    if (sym != XKB_KEY_NoSymbol) {
-        *sym_rtrn = sym;
-        return 1;
-    }
-
-    return 0;
-}
-
-static void
-FreeInclude(IncludeStmt *incl);
-
-IncludeStmt *
-IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
-{
-    IncludeStmt *incl, *first;
-    char *file, *map, *stmt, *tmp, *extra_data;
-    char nextop;
-
-    incl = first = NULL;
-    file = map = NULL;
-    tmp = str;
-    stmt = strdup_safe(str);
-    while (tmp && *tmp)
-    {
-        if (!XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
-            goto err;
-
-        if (first == NULL) {
-            first = incl = malloc(sizeof(*first));
-        } else {
-            incl->next_incl = malloc(sizeof(*first));
-            incl = incl->next_incl;
-        }
-
-        if (!incl) {
-            log_wsgo(ctx,
-                     "Allocation failure in IncludeCreate; "
-                     "Using only part of the include\n");
-            break;
-        }
-
-        incl->common.type = STMT_INCLUDE;
-        incl->common.next = NULL;
-        incl->merge = merge;
-        incl->stmt = NULL;
-        incl->file = file;
-        incl->map = map;
-        incl->modifier = extra_data;
-        incl->next_incl = NULL;
-
-        if (nextop == '|')
-            merge = MERGE_AUGMENT;
-        else
-            merge = MERGE_OVERRIDE;
-    }
-
-    if (first)
-        first->stmt = stmt;
-    else
-        free(stmt);
-
-    return first;
-
-err:
-    log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
-    FreeInclude(first);
-    free(stmt);
-    return NULL;
-}
-
-void
-CheckDefaultMap(struct xkb_context *ctx, XkbFile *maps, const char *fileName)
-{
-    XkbFile *dflt = NULL, *tmp;
-
-    for (tmp = maps; tmp; tmp = (XkbFile *) tmp->common.next) {
-        if (!(tmp->flags & XkbLC_Default))
-            continue;
-        if (!dflt) {
-            dflt = tmp;
-            continue;
-        }
-
-        log_lvl(ctx, 3,
-                "Multiple default components in %s; "
-                "Using %s, ignoring %s\n",
-                (fileName ? fileName : "(unknown)"),
-                (dflt->name ? dflt->name : "(first)"),
-                (tmp->name ? tmp->name : "(subsequent)"));
-
-        tmp->flags &= (~XkbLC_Default);
-    }
-}
-
-/*
- * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
- * wildcards.
- */
-static const unsigned char componentSpecLegal[] = {
-    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
-};
-
-static void
-EnsureSafeMapName(char *name)
-{
-    if (!name)
-        return;
-
-    while (*name != '\0') {
-        if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
-            *name = '_';
-        name++;
-    }
-}
-
-XkbFile *
-CreateXKBFile(struct xkb_context *ctx, enum xkb_file_type type, char *name,
-              ParseCommon *defs, unsigned flags)
-{
-    XkbFile *file;
-
-    file = calloc(1, sizeof(*file));
-    if (!file)
-        return NULL;
-
-    EnsureSafeMapName(name);
-    file->file_type = type;
-    file->topName = strdup_safe(name);
-    file->name = name;
-    file->defs = defs;
-    file->id = xkb_context_take_file_id(ctx);
-    file->flags = flags;
-    return file;
-}
-
-static void
-FreeExpr(ExprDef *expr)
-{
-    char **sym;
-
-    if (!expr)
-        return;
-
-    switch (expr->op) {
-    case EXPR_ACTION_LIST:
-    case EXPR_NEGATE:
-    case EXPR_UNARY_PLUS:
-    case EXPR_NOT:
-    case EXPR_INVERT:
-        FreeStmt(&expr->value.child->common);
-        break;
-
-    case EXPR_DIVIDE:
-    case EXPR_ADD:
-    case EXPR_SUBTRACT:
-    case EXPR_MULTIPLY:
-    case EXPR_ASSIGN:
-        FreeStmt(&expr->value.binary.left->common);
-        FreeStmt(&expr->value.binary.right->common);
-        break;
-
-    case EXPR_ACTION_DECL:
-        FreeStmt(&expr->value.action.args->common);
-        break;
-
-    case EXPR_ARRAY_REF:
-        FreeStmt(&expr->value.array.entry->common);
-        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);
-        break;
-
-    default:
-        break;
-    }
-}
-
-static void
-FreeInclude(IncludeStmt *incl)
-{
-    IncludeStmt *next;
-
-    while (incl)
-    {
-        next = incl->next_incl;
-
-        free(incl->file);
-        free(incl->map);
-        free(incl->modifier);
-        free(incl->stmt);
-
-        free(incl);
-        incl = next;
-    }
-}
-
-void
-FreeStmt(ParseCommon *stmt)
-{
-    ParseCommon *next;
-    YYSTYPE u;
-
-    while (stmt)
-    {
-        next = stmt->next;
-        u.any = stmt;
-
-        switch (stmt->type) {
-        case STMT_INCLUDE:
-            FreeInclude((IncludeStmt *) stmt);
-            /* stmt is already free'd here. */
-            stmt = NULL;
-            break;
-        case STMT_EXPR:
-            FreeExpr(u.expr);
-            break;
-        case STMT_VAR:
-            FreeStmt(&u.var->name->common);
-            FreeStmt(&u.var->value->common);
-            break;
-        case STMT_TYPE:
-            FreeStmt(&u.keyType->body->common);
-            break;
-        case STMT_INTERP:
-            free(u.interp->sym);
-            FreeStmt(&u.interp->match->common);
-            FreeStmt(&u.interp->def->common);
-            break;
-        case STMT_VMOD:
-            FreeStmt(&u.vmod->value->common);
-            break;
-        case STMT_SYMBOLS:
-            FreeStmt(&u.syms->symbols->common);
-            break;
-        case STMT_MODMAP:
-            FreeStmt(&u.modMask->keys->common);
-            break;
-        case STMT_GROUP_COMPAT:
-            FreeStmt(&u.groupCompat->def->common);
-            break;
-        case STMT_INDICATOR_MAP:
-            FreeStmt(&u.ledMap->body->common);
-            break;
-        case STMT_INDICATOR_NAME:
-            FreeStmt(&u.ledName->name->common);
-            break;
-        default:
-            break;
-        }
-
-        free(stmt);
-        stmt = next;
-    }
-}
-
-void
-FreeXKBFile(XkbFile *file)
-{
-    XkbFile *next;
-
-    while (file)
-    {
-        next = (XkbFile *) file->common.next;
-
-        switch (file->file_type) {
-        case FILE_TYPE_KEYMAP:
-            FreeXKBFile((XkbFile *) file->defs);
-            break;
-
-        case FILE_TYPE_TYPES:
-        case FILE_TYPE_COMPAT:
-        case FILE_TYPE_SYMBOLS:
-        case FILE_TYPE_KEYCODES:
-        case FILE_TYPE_GEOMETRY:
-            FreeStmt(file->defs);
-            break;
-
-        default:
-            break;
-        }
-
-        free(file->name);
-        free(file->topName);
-        free(file);
-        file = next;
-    }
-}
-
-const char *stmt_type_strings[_STMT_NUM_VALUES] = {
-    [STMT_UNKNOWN] = "unknown statement",
-    [STMT_INCLUDE] = "include statement",
-    [STMT_KEYCODE] = "key name definition",
-    [STMT_ALIAS] = "key alias definition",
-    [STMT_EXPR] = "expression",
-    [STMT_VAR] = "variable definition",
-    [STMT_TYPE] = "key type definition",
-    [STMT_INTERP] = "symbol interpretation definition",
-    [STMT_VMOD] = "virtual modifiers definition",
-    [STMT_SYMBOLS] = "key symbols definition",
-    [STMT_MODMAP] = "modifier map declaration",
-    [STMT_GROUP_COMPAT] = "group declaration",
-    [STMT_INDICATOR_MAP] = "indicator map declaration",
-    [STMT_INDICATOR_NAME] = "indicator name declaration",
-};
-
-const char *
-StmtTypeToString(enum stmt_type type)
-{
-    if (type >= _STMT_NUM_VALUES)
-        type = STMT_UNKNOWN;
-    return stmt_type_strings[type];
-}
diff --git a/src/xkbcomp/parseutils.h b/src/xkbcomp/parseutils.h
deleted file mode 100644 (file)
index 73db3d8..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/************************************************************
- * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of Silicon Graphics not be
- * used in advertising or publicity pertaining to distribution
- * of the software without specific prior written permission.
- * Silicon Graphics makes no representation about the suitability
- * of this software for any purpose. It is provided "as is"
- * without any express or implied warranty.
- *
- * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- ********************************************************/
-
-#ifndef PARSEUTILS_H
-#define PARSEUTILS_H
-
-#include <stdio.h>
-
-#include "xkbcomp-priv.h"
-
-struct parser_param {
-    struct xkb_context *ctx;
-    void *scanner;
-    XkbFile *rtrn;
-};
-
-#include "parser.h"
-
-struct scanner_extra {
-    struct xkb_context *ctx;
-    char *scanFile;
-    char scanBuf[1024];
-    char *s;
-};
-
-extern ParseCommon *
-AppendStmt(ParseCommon *to, ParseCommon *append);
-
-extern ExprDef *
-ExprCreate(enum expr_op_type op, enum expr_value_type type);
-
-extern ExprDef *
-ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
-                ExprDef *child);
-
-extern ExprDef *
-ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right);
-
-KeycodeDef *
-KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value);
-
-extern KeyAliasDef *
-KeyAliasCreate(char keyName[XkbKeyNameLength], char real[XkbKeyNameLength]);
-
-extern VModDef *
-VModCreate(xkb_atom_t name, ExprDef *value);
-
-extern VarDef *
-VarCreate(ExprDef *name, ExprDef *value);
-
-extern VarDef *
-BoolVarCreate(xkb_atom_t nameToken, unsigned set);
-
-extern InterpDef *
-InterpCreate(char *sym, ExprDef *match);
-
-extern KeyTypeDef *
-KeyTypeCreate(xkb_atom_t name, VarDef *body);
-
-extern SymbolsDef *
-SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols);
-
-extern GroupCompatDef *
-GroupCompatCreate(int group, ExprDef *def);
-
-extern ModMapDef *
-ModMapCreate(uint32_t modifier, ExprDef *keys);
-
-extern IndicatorMapDef *
-IndicatorMapCreate(xkb_atom_t name, VarDef *body);
-
-extern IndicatorNameDef *
-IndicatorNameCreate(int ndx, ExprDef *name, bool virtual);
-
-extern ExprDef *
-ActionCreate(xkb_atom_t name, ExprDef *args);
-
-extern ExprDef *
-CreateMultiKeysymList(ExprDef *list);
-
-extern ExprDef *
-CreateKeysymList(char *sym);
-
-extern ExprDef *
-AppendMultiKeysymList(ExprDef *list, ExprDef *append);
-
-extern ExprDef *
-AppendKeysymList(ExprDef *list, char *sym);
-
-bool
-LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn);
-
-extern IncludeStmt *
-IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
-
-extern void
-CheckDefaultMap(struct xkb_context *ctx, XkbFile *maps, const char *fileName);
-
-extern XkbFile *
-CreateXKBFile(struct xkb_context *ctx, enum xkb_file_type type, char *name,
-              ParseCommon *defs,
-              unsigned flags);
-
-extern bool
-XKBParseFile(struct xkb_context *ctx, FILE *file, const char *file_name,
-             XkbFile **out);
-
-extern bool
-XKBParseString(struct xkb_context *context, const char *string,
-               const char *file_name,
-               XkbFile **out);
-
-extern void
-FreeXKBFile(XkbFile *file);
-
-extern void
-FreeStmt(ParseCommon *stmt);
-
-void
-scanner_error(struct YYLTYPE *loc, void *scanner, const char *msg);
-
-#endif /* PARSEUTILS_H */
diff --git a/src/xkbcomp/path.c b/src/xkbcomp/path.c
deleted file mode 100644 (file)
index 5089f2c..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/************************************************************
- * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of Silicon Graphics not be
- * used in advertising or publicity pertaining to distribution
- * of the software without specific prior written permission.
- * Silicon Graphics makes no representation about the suitability
- * of this software for any purpose. It is provided "as is"
- * without any express or implied warranty.
- *
- * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- ********************************************************/
-
-#include <errno.h>
-#include <limits.h>
-
-#include "path.h"
-#include "parseutils.h"
-
-/**
- * Extract the first token from an include statement.
- * @param str_inout Input statement, modified in-place. Can be passed in
- * repeatedly. If str_inout is NULL, the parsing has completed.
- * @param file_rtrn Set to the include file to be used.
- * @param map_rtrn Set to whatever comes after ), if any.
- * @param nextop_rtrn Set to the next operation in the complete statement.
- * @param extra_data Set to the string between ( and ), if any.
- *
- * @return true if parsing was succcessful, false for an illegal string.
- *
- * Example: "evdev+aliases(qwerty)"
- *      str_inout = aliases(qwerty)
- *      nextop_retrn = +
- *      extra_data = NULL
- *      file_rtrn = evdev
- *      map_rtrn = NULL
- *
- * 2nd run with "aliases(qwerty)"
- *      str_inout = NULL
- *      file_rtrn = aliases
- *      map_rtrn = qwerty
- *      extra_data = NULL
- *      nextop_retrn = ""
- *
- */
-bool
-XkbParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
-                   char *nextop_rtrn, char **extra_data)
-{
-    char *tmp, *str, *next;
-
-    str = *str_inout;
-
-    /* search for tokens inside the string */
-    next = strpbrk(str, "|+");
-    if (next) {
-        /* set nextop_rtrn to \0, next to next character */
-        *nextop_rtrn = *next;
-        *next++ = '\0';
-    }
-    else {
-        *nextop_rtrn = '\0';
-        next = NULL;
-    }
-
-    /* search for :, store result in extra_data */
-    tmp = strchr(str, ':');
-    if (tmp != NULL) {
-        *tmp++ = '\0';
-        *extra_data = strdup(tmp);
-    }
-    else {
-        *extra_data = NULL;
-    }
-
-    tmp = strchr(str, '(');
-    if (tmp == NULL) {
-        *file_rtrn = strdup(str);
-        *map_rtrn = NULL;
-    }
-    else if (str[0] == '(') {
-        free(*extra_data);
-        return false;
-    }
-    else {
-        *tmp++ = '\0';
-        *file_rtrn = strdup(str);
-        str = tmp;
-        tmp = strchr(str, ')');
-        if ((tmp == NULL) || (tmp[1] != '\0')) {
-            free(*file_rtrn);
-            free(*extra_data);
-            return false;
-        }
-        *tmp++ = '\0';
-        *map_rtrn = strdup(str);
-    }
-
-    if (*nextop_rtrn == '\0')
-        *str_inout = NULL;
-    else if ((*nextop_rtrn == '|') || (*nextop_rtrn == '+'))
-        *str_inout = next;
-    else
-        return false;
-
-    return true;
-}
-
-/***====================================================================***/
-
-/**
- * Return the xkb directory based on the type.
- */
-const char *
-XkbDirectoryForInclude(enum xkb_file_type type)
-{
-    switch (type) {
-    case FILE_TYPE_KEYMAP:
-        return "keymap";
-
-    case FILE_TYPE_KEYCODES:
-        return "keycodes";
-
-    case FILE_TYPE_TYPES:
-        return "types";
-
-    case FILE_TYPE_SYMBOLS:
-        return "symbols";
-
-    case FILE_TYPE_COMPAT:
-        return "compat";
-
-    case FILE_TYPE_GEOMETRY:
-        return "geometry";
-
-    case FILE_TYPE_RULES:
-        return "rules";
-
-    default:
-        return "";
-    }
-}
-
-/***====================================================================***/
-
-/**
- * Search for the given file name in the include directories.
- *
- * @param ctx the XKB ctx containing the include paths
- * @param type one of FILE_TYPE_TYPES, FILE_TYPE_COMPAT, ..., or
- *             FILE_TYPE_KEYMAP or FILE_TYPE_RULES
- * @param pathRtrn is set to the full path of the file if found.
- *
- * @return an FD to the file or NULL. If NULL is returned, the value of
- * pathRtrn is undefined.
- */
-FILE *
-XkbFindFileInPath(struct xkb_context *ctx, const char *name,
-                  enum xkb_file_type type, char **pathRtrn)
-{
-    size_t i;
-    int ret;
-    FILE *file = NULL;
-    char buf[PATH_MAX];
-    const char *typeDir;
-
-    typeDir = XkbDirectoryForInclude(type);
-    for (i = 0; i < xkb_context_num_include_paths(ctx); i++) {
-        ret = snprintf(buf, sizeof(buf), "%s/%s/%s",
-                       xkb_context_include_path_get(ctx, i), typeDir, name);
-        if (ret >= (ssize_t) sizeof(buf)) {
-            log_err(ctx, "File name (%s/%s/%s) too long\n",
-                    xkb_context_include_path_get(ctx, i), typeDir, name);
-            continue;
-        }
-        file = fopen(buf, "r");
-        if (file == NULL) {
-            log_err(ctx, "Couldn't open file (%s/%s/%s): %s\n",
-                    xkb_context_include_path_get(ctx, i), typeDir, name,
-                    strerror(errno));
-            continue;
-        }
-        break;
-    }
-
-    if ((file != NULL) && (pathRtrn != NULL))
-        *pathRtrn = strdup(buf);
-    return file;
-}
-
-/**
- * Open the file given in the include statement and parse it's content.
- * If the statement defines a specific map to use, this map is returned in
- * file_rtrn. Otherwise, the default map is returned.
- *
- * @param ctx The ctx containing include paths
- * @param stmt The include statement, specifying the file name to look for.
- * @param file_type Type of file (FILE_TYPE_KEYCODES, etc.)
- * @param file_rtrn Returns the key map to be used.
- * @param merge_rtrn Always returns stmt->merge.
- *
- * @return true on success or false otherwise.
- */
-bool
-ProcessIncludeFile(struct xkb_context *ctx,
-                   IncludeStmt * stmt,
-                   enum xkb_file_type file_type,
-                   XkbFile ** file_rtrn, enum merge_mode *merge_rtrn)
-{
-    FILE *file;
-    XkbFile *rtrn, *mapToUse, *next;
-
-    file = XkbFindFileInPath(ctx, stmt->file, file_type, NULL);
-    if (file == NULL) {
-        log_err(ctx, "Can't find file \"%s\" for %s include\n", stmt->file,
-                XkbDirectoryForInclude(file_type));
-        return false;
-    }
-
-    if (!XKBParseFile(ctx, file, stmt->file, &rtrn)) {
-        log_err(ctx, "Error interpreting include file \"%s\"\n", stmt->file);
-        fclose(file);
-        return false;
-    }
-    fclose(file);
-
-    mapToUse = rtrn;
-    if (stmt->map != NULL) {
-        while (mapToUse)
-        {
-            next = (XkbFile *) mapToUse->common.next;
-            mapToUse->common.next = NULL;
-            if (streq(mapToUse->name, stmt->map) &&
-                mapToUse->file_type == file_type) {
-                FreeXKBFile(next);
-                break;
-            }
-            else {
-                FreeXKBFile(mapToUse);
-            }
-            mapToUse = next;
-        }
-        if (!mapToUse) {
-            log_err(ctx, "No %s named \"%s\" in the include file \"%s\"\n",
-                    FileTypeText(file_type), stmt->map, stmt->file);
-            return false;
-        }
-    }
-    else if (rtrn->common.next) {
-        log_lvl(ctx, 5,
-                "No map in include statement, but \"%s\" contains several; "
-                "Using first defined map, \"%s\"\n",
-                stmt->file, rtrn->name);
-    }
-    if (mapToUse->file_type != file_type) {
-        log_err(ctx,
-                "Include file wrong type (expected %s, got %s); "
-                "Include file \"%s\" ignored\n",
-                FileTypeText(file_type), FileTypeText(mapToUse->file_type),
-                stmt->file);
-        return false;
-    }
-    /* FIXME: we have to check recursive includes here (or somewhere) */
-
-    *file_rtrn = mapToUse;
-    *merge_rtrn = stmt->merge;
-    return true;
-}
diff --git a/src/xkbcomp/path.h b/src/xkbcomp/path.h
deleted file mode 100644 (file)
index be1a9cf..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/************************************************************
- * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of Silicon Graphics not be
- * used in advertising or publicity pertaining to distribution
- * of the software without specific prior written permission.
- * Silicon Graphics makes no representation about the suitability
- * of this software for any purpose. It is provided "as is"
- * without any express or implied warranty.
- *
- * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- ********************************************************/
-
-#ifndef XKBCOMP_PATH_H
-#define XKBCOMP_PATH_H
-
-#include <stdio.h>
-
-#include "xkbcomp-priv.h"
-
-bool
-XkbParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
-                   char *nextop_rtrn,
-                   char **extra_data);
-
-const char *
-XkbDirectoryForInclude(enum xkb_file_type type);
-
-FILE *
-XkbFindFileInPath(struct xkb_context *ctx, const char *name,
-                  enum xkb_file_type type, char **pathRtrn);
-
-#endif /* XKBCOMP_PATH_H */
index 02d7b2335230a3d332319165c4a704fd9e2ded5f..a1a0da15f1d8e2ea96f4750669f4791a337db0a7 100644 (file)
@@ -32,8 +32,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include "xkbcomp-priv.h"
 #include "rules.h"
-#include "path.h"
+#include "include.h"
 
 static const char *
 input_line_get(struct xkb_context *ctx, const char *buf, const char *end,
@@ -1089,7 +1090,7 @@ xkb_components_from_rules(struct xkb_context *ctx,
     char *path;
     char **include;
 
-    file = XkbFindFileInPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path);
+    file = FindFileInXkbPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path);
     if (!file) {
         log_err(ctx, "Could not find \"%s\" rules in XKB path\n",
                 rmlvo->rules);
index 0567a7b664d0a7b3dba50bf15d1078027617b283..9e73c3e2b16618c15230de112a24a41bc32cecc1 100644 (file)
  * authorization from the authors.
  */
 
-#ifndef RULES_H
-#define RULES_H
-
-#include "xkbcomp-priv.h"
+#ifndef XKBCOMP_RULES_H
+#define XKBCOMP_RULES_H
 
 bool
 xkb_components_from_rules(struct xkb_context *ctx,
                           const struct xkb_rule_names *rmlvo,
                           struct xkb_component_names *out);
 
-#endif /* RULES_H */
+#endif
index d60515bf407aededc998118490fdcb23feaafcd1..6dfa28b5fbb9b7d367f386e256b3003b324f39cb 100644 (file)
  ********************************************************/
 
 %{
-#include <stdio.h>
-
 #include "xkbcomp-priv.h"
-#include "parseutils.h"
+#include "parser-priv.h"
 
-#pragma GCC diagnostic ignored "-Wredundant-decls"
 #pragma GCC diagnostic ignored "-Wmissing-noreturn"
 
-extern int yyparse(struct parser_param *param);
+struct scanner_extra {
+    struct xkb_context *ctx;
+    char *scanFile;
+    char scanBuf[1024];
+    char *s;
+};
 
 static void
 scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
@@ -226,8 +228,33 @@ scanner_error(struct YYLTYPE *loc, void *scanner, const char *msg)
     scanner_error_extra(loc, extra, msg);
 }
 
+static void
+CheckDefaultMap(struct xkb_context *ctx, XkbFile *maps, const char *fileName)
+{
+    XkbFile *dflt = NULL, *tmp;
+
+    for (tmp = maps; tmp; tmp = (XkbFile *) tmp->common.next) {
+        if (!(tmp->flags & XkbLC_Default))
+            continue;
+
+        if (!dflt) {
+            dflt = tmp;
+            continue;
+        }
+
+        log_lvl(ctx, 3,
+                "Multiple default components in %s; "
+                "Using %s, ignoring %s\n",
+                (fileName ? fileName : "(unknown)"),
+                (dflt->name ? dflt->name : "(first)"),
+                (tmp->name ? tmp->name : "(subsequent)"));
+
+        tmp->flags &= (~XkbLC_Default);
+    }
+}
+
 bool
-XKBParseString(struct xkb_context *ctx, const char *string,
+XkbParseString(struct xkb_context *ctx, const char *string,
                const char *file_name, XkbFile **out)
 {
     int ret;
@@ -265,7 +292,7 @@ XKBParseString(struct xkb_context *ctx, const char *string,
 }
 
 bool
-XKBParseFile(struct xkb_context *ctx, FILE *file,
+XkbParseFile(struct xkb_context *ctx, FILE *file,
              const char *file_name, XkbFile **out)
 {
     int ret;
index bd1bfdc41f3afacb75329ecd2cbd872c00d72107..b978debb0c7cddcb0be775223558fd01e15b7c43 100644 (file)
  ********************************************************/
 
 #include "xkbcomp-priv.h"
-#include "parseutils.h"
+#include "text.h"
+#include "expr.h"
 #include "action.h"
 #include "vmod.h"
-
-/***====================================================================***/
+#include "keycodes.h"
+#include "include.h"
 
 /* Needed to work with the typechecker. */
 typedef darray(xkb_keysym_t) darray_xkb_keysym_t;
@@ -772,7 +773,7 @@ HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *stmt)
         MergeIncludedSymbols(&included, &next_incl, merge);
 
         FreeSymbolsInfo(&next_incl);
-        FreeXKBFile(rtrn);
+        FreeXkbFile(rtrn);
     }
 
     MergeIncludedSymbols(info, &included, merge);
@@ -829,6 +830,30 @@ 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 1;
+    }
+
+    if (istreq(str, "none") || istreq(str, "voidsymbol")) {
+        *sym_rtrn = XKB_KEY_VoidSymbol;
+        return 1;
+    }
+
+    sym = xkb_keysym_from_name(str);
+    if (sym != XKB_KEY_NoSymbol) {
+        *sym_rtrn = sym;
+        return 1;
+    }
+
+    return 0;
+}
+
 static bool
 AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
                 ExprDef *value)
diff --git a/src/xkbcomp/types.c b/src/xkbcomp/types.c
new file mode 100644 (file)
index 0000000..8b60f61
--- /dev/null
@@ -0,0 +1,910 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "vmod.h"
+#include "expr.h"
+#include "include.h"
+
+/*
+ * The xkb_types section
+ * =====================
+ * This section is the second to be processesed, after xkb_keycodes.
+ * However, it is completely independent and could have been the first
+ * to be processed (it does not refer to specific keys as specified in
+ * the xkb_keycodes section).
+ *
+ * This section defines key types, which, given a key and a keyboard
+ * state (i.e. modifier state and group), determine the shift level to
+ * be used in translating the key to keysyms. These types are assigned
+ * to each group in each key, in the xkb_symbols section.
+ *
+ * Key types are called this way because, in a way, they really describe
+ * the "type" of the key (or more correctly, a specific group of the
+ * key). For example, an ordinary keymap will provide a type called
+ * "KEYPAD", which consists of two levels, with the second level being
+ * chosen according to the state of the Num Lock (or Shift) modifiers.
+ * Another example is a type called "ONE_LEVEL", which is usually
+ * assigned to keys such as Escape; these have just one level and are
+ * not affected by the modifier state. Yet more common examples are
+ * "TWO_LEVEL" (with Shift choosing the second level), "ALPHABETIC"
+ * (where Caps Lock may also choose the second level), etc.
+ *
+ * Type definitions
+ * ----------------
+ *  Statements of the form:
+ *      type "FOUR_LEVEL" { ... }
+ *
+ * The above would create a new type named "FOUR_LEVEL".
+ * The body of the definition may include statements of the following
+ * forms:
+ *
+ * - level_name statements (mandatory for each level in the type):
+ *      level_name[Level1] = "Base";
+ *
+ *   Gives each level in this type a descriptive name. It isn't used
+ *   for any thing.
+ *   Note: A level may be specified as Level[1-8] or just a number (can
+ *   be more than 8).
+ *
+ * - modifiers statement (mandatory, should be specified only once):
+ *      modifiers = Shift+Lock+LevelThree;
+ *
+ *   A mask of real and virtual modifiers. These are the only modifiers
+ *   being considered when matching the modifier state against the type.
+ *   The other modifiers, whether active or not, are masked out in the
+ *   calculation.
+ *
+ * - map entry statements (should have at least as many mappings as there
+ *   are levels in the type):
+ *      map[Shift+LevelThree] = Level4;
+ *
+ *   If the active modifiers, masked with the type's modifiers (as stated
+ *   above), match (i.e. equal) the modifiers inside the map[] statement,
+ *   then the level in the right hand side is chosen. For example, in the
+ *   above, if in the current keyboard state the Shift and LevelThree
+ *   modifiers are active, while the Lock modifier is not, then the
+ *   keysym(s) in the 4th level of the group will be returned to the
+ *   user.
+ *
+ * - preserve statements:
+ *      map[Shift+Lock+LevelThree] = Level5;
+ *      preserve[Shift+Lock+LevelThree] = Lock;
+ *
+ *   When a map entry matches the active modifiers and the level it
+ *   specified is chosen, then these modifiers are said to be "consumed";
+ *   for example, in a simple US keymap where the "g" key is assigned an
+ *   ordinary ALPHABETIC key type, if the Lock (Caps Lock) modifier is
+ *   active and the key is pressed, then a "G" keysym is produced (as
+ *   opposed to lower-case "g"). This is because the type definition has
+ *   a map entry like the following:
+ *      map[Lock] = Level2;
+ *   And as such the Lock modifier is consumed. This information is
+ *   relevant for applications which further process the modifiers,
+ *   since by then the consumed modifiers have already "done their part"
+ *   and should be masked out.
+ *
+ *   However, sometimes even if a modifier is actually used to choose
+ *   the shift level (as Lock above), it should *not* be reported as
+ *   consumed, for various reasons. In this case, a preserve[] statement
+ *   can be used to augment the map entry. The modifiers inside the square
+ *   brackets should match one of the map[] statements in the type. The
+ *   right hand side should consists of modifiers from the left hand
+ *   side; these modifiers are then "preserved" and not reported as
+ *   consumed.
+ *
+ * Virtual modifier statements
+ * ---------------------------
+ * Statements of the form:
+ *     virtual_modifiers LControl;
+ *
+ * Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
+ * TODO
+ */
+
+enum type_field {
+    TYPE_FIELD_MASK       = (1 << 0),
+    TYPE_FIELD_MAP        = (1 << 1),
+    TYPE_FIELD_PRESERVE   = (1 << 2),
+    TYPE_FIELD_LEVEL_NAME = (1 << 3),
+};
+
+typedef struct _KeyTypeInfo {
+    enum type_field defined;
+    unsigned file_id;
+    enum merge_mode merge;
+    struct list entry;
+
+    xkb_atom_t name;
+    xkb_mod_mask_t mods;
+    xkb_level_index_t num_levels;
+    darray(struct xkb_kt_map_entry) entries;
+    darray(xkb_atom_t) level_names;
+} KeyTypeInfo;
+
+typedef struct _KeyTypesInfo {
+    char *name;
+    int errorCount;
+    unsigned file_id;
+    unsigned num_types;
+    struct list types;
+    VModInfo vmods;
+    struct xkb_keymap *keymap;
+} KeyTypesInfo;
+
+/***====================================================================***/
+
+static inline const char *
+MapEntryTxt(KeyTypesInfo *info, struct xkb_kt_map_entry *entry)
+{
+    return VModMaskText(info->keymap, entry->mods.mods);
+}
+
+static inline const char *
+TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type)
+{
+    return xkb_atom_text(info->keymap->ctx, type->name);
+}
+
+static inline const char *
+TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type)
+{
+    return VModMaskText(info->keymap, type->mods);
+}
+
+static inline bool
+ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type,
+                        const char *field)
+{
+    return ReportShouldBeArray(info->keymap, "key type", field,
+                               TypeTxt(info, type));
+}
+
+static inline bool
+ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
+                  const char *field, const char *wanted)
+{
+    return ReportBadType(info->keymap->ctx, "key type", field,
+                         TypeTxt(info, type), wanted);
+}
+
+static inline bool
+ReportTypeBadWidth(KeyTypesInfo *info, const char *type, int has, int needs)
+{
+    log_err(info->keymap->ctx,
+            "Key type \"%s\" has %d levels, must have %d; "
+            "Illegal type definition ignored\n",
+            type, has, needs);
+    return false;
+}
+
+/***====================================================================***/
+
+static void
+InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
+                 unsigned file_id)
+{
+    info->name = strdup("default");
+    info->errorCount = 0;
+    info->num_types = 0;
+    list_init(&info->types);
+    info->file_id = file_id;
+    InitVModInfo(&info->vmods, keymap);
+    info->keymap = keymap;
+}
+
+static void
+FreeKeyTypeInfo(KeyTypeInfo * type)
+{
+    darray_free(type->entries);
+    darray_free(type->level_names);
+}
+
+static void
+FreeKeyTypesInfo(KeyTypesInfo * info)
+{
+    KeyTypeInfo *type, *next_type;
+    free(info->name);
+    info->name = NULL;
+    list_foreach_safe(type, next_type, &info->types, entry) {
+        FreeKeyTypeInfo(type);
+        free(type);
+    }
+}
+
+static KeyTypeInfo *
+NextKeyType(KeyTypesInfo * info)
+{
+    KeyTypeInfo *type;
+
+    type = calloc(1, sizeof(*type));
+    if (!type)
+        return NULL;
+
+    type->file_id = info->file_id;
+
+    list_append(&type->entry, &info->types);
+    info->num_types++;
+    return type;
+}
+
+static KeyTypeInfo *
+FindMatchingKeyType(KeyTypesInfo *info, xkb_atom_t name)
+{
+    KeyTypeInfo *old;
+
+    list_foreach(old, &info->types, entry)
+        if (old->name == name)
+            return old;
+
+    return NULL;
+}
+
+static bool
+AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new)
+{
+    KeyTypeInfo *old;
+    struct list entry;
+    int verbosity = xkb_get_log_verbosity(info->keymap->ctx);
+
+    old = FindMatchingKeyType(info, new->name);
+    if (old) {
+        if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) {
+            if ((old->file_id == new->file_id && verbosity > 0) ||
+                verbosity > 9) {
+                log_warn(info->keymap->ctx,
+                         "Multiple definitions of the %s key type; "
+                         "Earlier definition ignored\n",
+                         xkb_atom_text(info->keymap->ctx, new->name));
+            }
+
+            entry = old->entry;
+            FreeKeyTypeInfo(old);
+            *old = *new;
+            old->entry = entry;
+            darray_init(new->entries);
+            darray_init(new->level_names);
+            return true;
+        }
+
+        if (old->file_id == new->file_id)
+            log_lvl(info->keymap->ctx, 4,
+                    "Multiple definitions of the %s key type; "
+                    "Later definition ignored\n",
+                    xkb_atom_text(info->keymap->ctx, new->name));
+
+        FreeKeyTypeInfo(new);
+        return true;
+    }
+
+    old = NextKeyType(info);
+    if (!old)
+        return false;
+
+    entry = old->entry;
+    *old = *new;
+    old->entry = entry;
+    darray_init(new->entries);
+    darray_init(new->level_names);
+    return true;
+}
+
+/***====================================================================***/
+
+static void
+MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
+                      enum merge_mode merge)
+{
+    KeyTypeInfo *type, *next_type;
+
+    if (from->errorCount > 0) {
+        into->errorCount += from->errorCount;
+        return;
+    }
+
+    if (into->name == NULL) {
+        into->name = from->name;
+        from->name = NULL;
+    }
+
+    list_foreach_safe(type, next_type, &from->types, entry) {
+        type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
+        if (!AddKeyType(into, type))
+            into->errorCount++;
+    }
+}
+
+static void
+HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge);
+
+static bool
+HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *stmt)
+{
+    enum merge_mode merge = MERGE_DEFAULT;
+    XkbFile *rtrn;
+    KeyTypesInfo included, next_incl;
+
+    InitKeyTypesInfo(&included, info->keymap, info->file_id);
+    if (stmt->stmt) {
+        free(included.name);
+        included.name = stmt->stmt;
+        stmt->stmt = NULL;
+    }
+
+    for (; stmt; stmt = stmt->next_incl) {
+        if (!ProcessIncludeFile(info->keymap->ctx, stmt, FILE_TYPE_TYPES,
+                                &rtrn, &merge)) {
+            info->errorCount += 10;
+            FreeKeyTypesInfo(&included);
+            return false;
+        }
+
+        InitKeyTypesInfo(&next_incl, info->keymap, rtrn->id);
+
+        HandleKeyTypesFile(&next_incl, rtrn, merge);
+
+        MergeIncludedKeyTypes(&included, &next_incl, merge);
+
+        FreeKeyTypesInfo(&next_incl);
+        FreeXkbFile(rtrn);
+    }
+
+    MergeIncludedKeyTypes(info, &included, merge);
+    FreeKeyTypesInfo(&included);
+
+    return (info->errorCount == 0);
+}
+
+/***====================================================================***/
+
+static bool
+SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+             ExprDef *value)
+{
+    xkb_mod_mask_t mods;
+
+    if (arrayNdx)
+        log_warn(info->keymap->ctx,
+                 "The modifiers field of a key type is not an array; "
+                 "Illegal array subscript ignored\n");
+
+    /* get modifier mask for current type */
+    if (!ExprResolveVModMask(info->keymap, value, &mods)) {
+        log_err(info->keymap->ctx,
+                "Key type mask field must be a modifier mask; "
+                "Key type definition ignored\n");
+        return false;
+    }
+
+    if (type->defined & TYPE_FIELD_MASK) {
+        log_warn(info->keymap->ctx,
+                 "Multiple modifier mask definitions for key type %s; "
+                 "Using %s, ignoring %s\n",
+                 xkb_atom_text(info->keymap->ctx, type->name),
+                 TypeMaskTxt(info, type),
+                 VModMaskText(info->keymap, mods));
+        return false;
+    }
+
+    type->mods = mods;
+    return true;
+}
+
+/***====================================================================***/
+
+static struct xkb_kt_map_entry *
+FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods)
+{
+    struct xkb_kt_map_entry *entry;
+
+    darray_foreach(entry, type->entries)
+        if (entry->mods.mods == mods)
+            return entry;
+
+    return NULL;
+}
+
+/**
+ * Add a new KTMapEntry to the given key type. If an entry with the same mods
+ * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
+ * entry is created.
+ *
+ * @param clobber Overwrite existing entry.
+ * @param report true if a warning is to be printed on.
+ */
+static bool
+AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
+            struct xkb_kt_map_entry *new, bool clobber, bool report)
+{
+    struct xkb_kt_map_entry * old;
+
+    old = FindMatchingMapEntry(type, new->mods.mods);
+    if (old) {
+        if (report && old->level != new->level) {
+            log_warn(info->keymap->ctx,
+                     "Multiple map entries for %s in %s; "
+                     "Using %d, ignoring %d\n",
+                     MapEntryTxt(info, new), TypeTxt(info, type),
+                     (clobber ? new->level : old->level) + 1,
+                     (clobber ? old->level : new->level) + 1);
+        }
+        else {
+            log_lvl(info->keymap->ctx, 10,
+                    "Multiple occurences of map[%s]= %d in %s; Ignored\n",
+                    MapEntryTxt(info, new), new->level + 1,
+                    TypeTxt(info, type));
+            return true;
+        }
+
+        if (clobber) {
+            if (new->level >= type->num_levels)
+                type->num_levels = new->level + 1;
+            old->level = new->level;
+        }
+
+        return true;
+    }
+
+    if (new->level >= type->num_levels)
+        type->num_levels = new->level + 1;
+
+    darray_append(type->entries, *new);
+    return true;
+}
+
+static bool
+SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+            ExprDef *value)
+{
+    struct xkb_kt_map_entry entry;
+
+    if (arrayNdx == NULL)
+        return ReportTypeShouldBeArray(info, type, "map entry");
+
+    if (!ExprResolveVModMask(info->keymap, arrayNdx, &entry.mods.mods))
+        return ReportTypeBadType(info, type, "map entry", "modifier mask");
+
+    if (entry.mods.mods & (~type->mods)) {
+        log_lvl(info->keymap->ctx, 1,
+                "Map entry for unused modifiers in %s; "
+                "Using %s instead of %s\n",
+                TypeTxt(info, type),
+                VModMaskText(info->keymap, entry.mods.mods & type->mods),
+                MapEntryTxt(info, &entry));
+        entry.mods.mods &= type->mods;
+    }
+
+    if (!ExprResolveLevel(info->keymap->ctx, value, &entry.level)) {
+        log_err(info->keymap->ctx,
+                "Level specifications in a key type must be integer; "
+                "Ignoring malformed level specification\n");
+        return false;
+    }
+
+    entry.preserve.mods = 0;
+
+    return AddMapEntry(info, type, &entry, true, true);
+}
+
+/***====================================================================***/
+
+static bool
+AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
+            xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods)
+{
+    struct xkb_kt_map_entry *entry;
+    struct xkb_kt_map_entry new;
+
+    darray_foreach(entry, type->entries) {
+        if (entry->mods.mods != mods)
+            continue;
+
+        /* Map exists without previous preserve (or "None"); override. */
+        if (entry->preserve.mods == 0) {
+            entry->preserve.mods = preserve_mods;
+            return true;
+        }
+
+        /* Map exists with same preserve; do nothing. */
+        if (entry->preserve.mods == preserve_mods) {
+            log_lvl(info->keymap->ctx, 10,
+                    "Identical definitions for preserve[%s] in %s; "
+                    "Ignored\n",
+                    VModMaskText(info->keymap, mods),
+                    TypeTxt(info, type));
+            return true;
+        }
+
+        /* Map exists with different preserve; latter wins. */
+        log_lvl(info->keymap->ctx, 1,
+                "Multiple definitions for preserve[%s] in %s; "
+                "Using %s, ignoring %s\n",
+                VModMaskText(info->keymap, mods),
+                TypeTxt(info, type),
+                VModMaskText(info->keymap, preserve_mods),
+                VModMaskText(info->keymap, entry->preserve.mods));
+
+        entry->preserve.mods = preserve_mods;
+        return true;
+    }
+
+    /*
+     * Map does not exist, i.e. preserve[] came before map[].
+     * Create a map with the specified mask mapping to Level1. The level
+     * may be overriden later with an explicit map[] statement.
+     */
+    new.level = 0;
+    new.mods.mods = mods;
+    new.preserve.mods = preserve_mods;
+    darray_append(type->entries, new);
+    return true;
+}
+
+static bool
+SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+            ExprDef *value)
+{
+    xkb_mod_mask_t mods, preserve_mods;
+
+    if (arrayNdx == NULL)
+        return ReportTypeShouldBeArray(info, type, "preserve entry");
+
+    if (!ExprResolveVModMask(info->keymap, arrayNdx, &mods))
+        return ReportTypeBadType(info, type, "preserve entry",
+                                 "modifier mask");
+
+    if (mods & ~type->mods) {
+        const char *before, *after;
+
+        before = VModMaskText(info->keymap, mods);
+        mods &= type->mods;
+        after = VModMaskText(info->keymap, mods);
+
+        log_lvl(info->keymap->ctx, 1,
+                "Preserve for modifiers not used by the %s type; "
+                "Index %s converted to %s\n",
+                TypeTxt(info, type), before, after);
+    }
+
+    if (!ExprResolveVModMask(info->keymap, value, &preserve_mods)) {
+        log_err(info->keymap->ctx,
+                "Preserve value in a key type is not a modifier mask; "
+                "Ignoring preserve[%s] in type %s\n",
+                VModMaskText(info->keymap, mods),
+                TypeTxt(info, type));
+        return false;
+    }
+
+    if (preserve_mods & ~mods) {
+        const char *before, *after;
+
+        before = VModMaskText(info->keymap, preserve_mods);
+        preserve_mods &= mods;
+        after = VModMaskText(info->keymap, preserve_mods);
+
+        log_lvl(info->keymap->ctx, 1,
+                "Illegal value for preserve[%s] in type %s; "
+                "Converted %s to %s\n",
+                VModMaskText(info->keymap, mods),
+                TypeTxt(info, type), before, after);
+    }
+
+    return AddPreserve(info, type, mods, preserve_mods);
+}
+
+/***====================================================================***/
+
+static bool
+AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type,
+             xkb_level_index_t level, xkb_atom_t name, bool clobber)
+{
+    /* New name. */
+    if (level >= darray_size(type->level_names)) {
+        darray_resize0(type->level_names, level + 1);
+        goto finish;
+    }
+
+    /* Same level, same name. */
+    if (darray_item(type->level_names, level) == name) {
+        log_lvl(info->keymap->ctx, 10,
+                "Duplicate names for level %d of key type %s; Ignored\n",
+                level + 1, TypeTxt(info, type));
+        return true;
+    }
+
+    /* Same level, different name. */
+    if (darray_item(type->level_names, level) != XKB_ATOM_NONE) {
+        const char *old, *new;
+        old = xkb_atom_text(info->keymap->ctx,
+                            darray_item(type->level_names, level));
+        new = xkb_atom_text(info->keymap->ctx, name);
+        log_lvl(info->keymap->ctx, 1,
+                "Multiple names for level %d of key type %s; "
+                "Using %s, ignoring %s\n",
+                level + 1, TypeTxt(info, type),
+                (clobber ? new : old), (clobber ? old : new));
+
+        if (!clobber)
+            return true;
+    }
+
+    /* XXX: What about different level, same name? */
+
+finish:
+    darray_item(type->level_names, level) = name;
+    return true;
+}
+
+static bool
+SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+             ExprDef *value)
+{
+    xkb_level_index_t level;
+    xkb_atom_t level_name;
+    struct xkb_context *ctx = info->keymap->ctx;
+    const char *str;
+
+    if (arrayNdx == NULL)
+        return ReportTypeShouldBeArray(info, type, "level name");
+
+    if (!ExprResolveLevel(ctx, arrayNdx, &level))
+        return ReportTypeBadType(info, type, "level name", "integer");
+
+    if (!ExprResolveString(ctx, value, &str)) {
+        log_err(info->keymap->ctx,
+                "Non-string name for level %d in key type %s; "
+                "Ignoring illegal level name definition\n",
+                level + 1, xkb_atom_text(ctx, type->name));
+        return false;
+    }
+
+    level_name = xkb_atom_intern(ctx, str);
+
+    return AddLevelName(info, type, level, level_name, true);
+}
+
+/***====================================================================***/
+
+/**
+ * Parses the fields in a type "..." { } description.
+ *
+ * @param field The field to parse (e.g. modifiers, map, level_name)
+ */
+static bool
+SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type,
+                const char *field, ExprDef *arrayNdx, ExprDef *value)
+{
+    bool ok = false;
+    enum type_field type_field = 0;
+
+    if (istreq(field, "modifiers")) {
+        type_field = TYPE_FIELD_MASK;
+        ok = SetModifiers(info, type, arrayNdx, value);
+    }
+    else if (istreq(field, "map")) {
+        type_field = TYPE_FIELD_MAP;
+        ok = SetMapEntry(info, type, arrayNdx, value);
+    }
+    else if (istreq(field, "preserve")) {
+        type_field = TYPE_FIELD_PRESERVE;
+        ok = SetPreserve(info, type, arrayNdx, value);
+    }
+    else if (istreq(field, "levelname") || istreq(field, "level_name")) {
+        type_field = TYPE_FIELD_LEVEL_NAME;
+        ok = SetLevelName(info, type, arrayNdx, value);
+    } else {
+        log_err(info->keymap->ctx,
+                "Unknown field %s in key type %s; Definition ignored\n",
+                field, TypeTxt(info, type));
+    }
+
+    type->defined |= type_field;
+    return ok;
+}
+
+static bool
+HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type)
+{
+    bool ok = true;
+    const char *elem, *field;
+    ExprDef *arrayNdx;
+
+    for (; def; def = (VarDef *) def->common.next) {
+        ok = ExprResolveLhs(info->keymap->ctx, def->name, &elem, &field,
+                            &arrayNdx);
+        if (!ok)
+            continue;
+
+        if (elem && istreq(elem, "type")) {
+            log_err(info->keymap->ctx,
+                    "Support for changing the default type has been removed; "
+                    "Statement ignored\n");
+            continue;
+        }
+
+        ok = SetKeyTypeField(info, type, field, arrayNdx, def->value);
+    }
+
+    return ok;
+}
+
+/**
+ * Process a type "XYZ" { } specification in the xkb_types section.
+ *
+ */
+static bool
+HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge)
+{
+    KeyTypeInfo type = {
+        .defined = 0,
+        .file_id = info->file_id,
+        .merge = (def->merge == MERGE_DEFAULT ? merge : def->merge),
+        .name = def->name,
+        .mods = 0,
+        .num_levels = 1,
+        .entries = darray_new(),
+        .level_names = darray_new(),
+    };
+
+    /* Parse the actual content. */
+    if (!HandleKeyTypeBody(info, def->body, &type)) {
+        info->errorCount++;
+        return false;
+    }
+
+    /* Now add the new keytype to the info struct */
+    if (!AddKeyType(info, &type)) {
+        info->errorCount++;
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * Process an xkb_types section.
+ *
+ * @param file The parsed xkb_types section.
+ * @param merge Merge Strategy (e.g. MERGE_OVERRIDE)
+ * @param info Pointer to memory where the outcome will be stored.
+ */
+static void
+HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
+{
+    bool ok;
+    ParseCommon *stmt;
+
+    free(info->name);
+    info->name = strdup_safe(file->name);
+
+    for (stmt = file->defs; stmt; stmt = stmt->next) {
+        switch (stmt->type) {
+        case STMT_INCLUDE:
+            ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt);
+            break;
+        case STMT_TYPE: /* e.g. type "ONE_LEVEL" */
+            ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge);
+            break;
+        case STMT_VAR:
+            log_err(info->keymap->ctx,
+                    "Support for changing the default type has been removed; "
+                    "Statement ignored\n");
+            ok = true;
+            break;
+        case STMT_VMOD: /* virtual_modifiers NumLock, ... */
+            ok = HandleVModDef((VModDef *) stmt, info->keymap, merge,
+                               &info->vmods);
+            break;
+        default:
+            log_err(info->keymap->ctx,
+                    "Key type files may not include other declarations; "
+                    "Ignoring %s\n", StmtTypeToString(stmt->type));
+            ok = false;
+            break;
+        }
+
+        if (!ok)
+            info->errorCount++;
+
+        if (info->errorCount > 10) {
+            log_err(info->keymap->ctx,
+                    "Abandoning keytypes file \"%s\"\n", file->topName);
+            break;
+        }
+    }
+}
+
+static bool
+CopyDefToKeyType(KeyTypesInfo *info, KeyTypeInfo *def,
+                 struct xkb_key_type *type)
+{
+    type->mods.mods = def->mods;
+    type->num_levels = def->num_levels;
+    type->map = darray_mem(def->entries, 0);
+    type->num_entries = darray_size(def->entries);
+    darray_init(def->entries);
+    type->name = def->name;
+    type->level_names = darray_mem(def->level_names, 0);
+    darray_init(def->level_names);
+
+    return true;
+}
+
+bool
+CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
+                enum merge_mode merge)
+{
+    unsigned int i;
+    unsigned int num_types;
+    KeyTypesInfo info;
+    KeyTypeInfo *def;
+
+    InitKeyTypesInfo(&info, keymap, file->id);
+
+    HandleKeyTypesFile(&info, file, merge);
+
+    if (info.errorCount != 0)
+        goto err_info;
+
+    if (info.name)
+        keymap->types_section_name = strdup(info.name);
+
+    num_types = info.num_types ? info.num_types : 1;
+    keymap->types = calloc(num_types, sizeof(*keymap->types));
+    if (!keymap->types)
+        goto err_info;
+    keymap->num_types = num_types;
+
+    /*
+     * If no types were specified, a default unnamed one-level type is
+     * used for all keys.
+     */
+    if (info.num_types == 0) {
+        KeyTypeInfo dflt = {
+            .name = xkb_atom_intern(keymap->ctx, "default"),
+            .mods = 0,
+            .num_levels = 1,
+            .entries = darray_new(),
+            .level_names = darray_new(),
+        };
+
+        if (!CopyDefToKeyType(&info, &dflt, &keymap->types[0]))
+            goto err_info;
+    } else {
+        i = 0;
+        list_foreach(def, &info.types, entry)
+            if (!CopyDefToKeyType(&info, def, &keymap->types[i++]))
+                goto err_info;
+    }
+
+    FreeKeyTypesInfo(&info);
+    return true;
+
+err_info:
+    FreeKeyTypesInfo(&info);
+    return false;
+}
index 72ec199125ff07761b05d638c8e84277b45c3b72..3560d70f76925cf9afc265aea8614caf836b1f01 100644 (file)
@@ -24,6 +24,9 @@
  *
  ********************************************************/
 
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
 #include "vmod.h"
 
 void
index 070ff6913e7fa95d9c7ce3987cd5b76dcd26d745..5748d0178a0cf9c1932b25ab8fe193d92b6b7387 100644 (file)
  *
  ********************************************************/
 
-#ifndef VMOD_H
-#define VMOD_H 1
-
-#include "xkbcomp-priv.h"
-#include "expr.h"
+#ifndef XKBCOMP_VMOD_H
+#define XKBCOMP_VMOD_H
 
 typedef struct _VModInfo {
     xkb_mod_mask_t defined;
     xkb_mod_mask_t available;
 } VModInfo;
 
-extern void
+void
 InitVModInfo(VModInfo *info, struct xkb_keymap *keymap);
 
-extern void
+void
 ClearVModInfo(VModInfo *info, struct xkb_keymap *keymap);
 
-extern bool
+bool
 HandleVModDef(VModDef *stmt, struct xkb_keymap *keymap,
               enum merge_mode mergeMode, VModInfo *info);
 
@@ -49,4 +46,4 @@ bool
 ResolveVirtualModifier(ExprDef *def, struct xkb_keymap *keymap,
                        xkb_mod_index_t *ndx_rtrn, VModInfo *info);
 
-#endif /* VMOD_H */
+#endif
index 33e967113f46e9b5df09732553fe4f6842c6849d..256307a76d2597da6195f1a0717aeb7740ce4d4e 100644 (file)
 #ifndef XKBCOMP_PRIV_H
 #define XKBCOMP_PRIV_H
 
-#include "xkbcomp.h"
-#include "text.h"
+#include "xkb-priv.h"
+#include "ast.h"
 
-extern bool
-ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
-                   enum xkb_file_type file_type, XkbFile **file_rtrn,
-                   enum merge_mode *merge_rtrn);
+bool
+XkbParseFile(struct xkb_context *ctx, FILE *file, const char *file_name,
+             XkbFile **out);
 
-struct xkb_key *
-FindNamedKey(struct xkb_keymap *keymap, unsigned long name,
-             bool use_aliases, xkb_keycode_t start_from);
+bool
+XkbParseString(struct xkb_context *context, const char *string,
+               const char *file_name, XkbFile **out);
 
-extern bool
-FindKeyNameForAlias(struct xkb_keymap *keymap, unsigned long lname,
-                    unsigned long *real_name);
+void
+FreeXkbFile(XkbFile *file);
 
-extern bool
+XkbFile *
+XkbFileFromComponents(struct xkb_context *ctx,
+                      struct xkb_component_names *kkctgs);
+
+bool
+CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap,
+                enum merge_mode merge);
+
+bool
+CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
+                enum merge_mode merge);
+
+bool
+CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap,
+                 enum merge_mode merge);
+
+bool
+CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
+               enum merge_mode merge);
+
+bool
 UpdateModifiersFromCompat(struct xkb_keymap *keymap);
 
+bool
+LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn);
+
 const char *
 StmtTypeToString(enum stmt_type type);
 
-static inline unsigned long
-KeyNameToLong(const char name[XkbKeyNameLength])
-{
-    return
-        (((unsigned long)name[0]) << 24) |
-        (((unsigned long)name[1]) << 16) |
-        (((unsigned long)name[2]) << 8)  |
-        (((unsigned long)name[3]) << 0);
-}
-
-static inline void
-LongToKeyName(unsigned long val, char name[XkbKeyNameLength])
-{
-    name[0] = ((val >> 24) & 0xff);
-    name[1] = ((val >> 16) & 0xff);
-    name[2] = ((val >> 8) & 0xff);
-    name[3] = ((val >> 0) & 0xff);
-}
-
-static inline const char *
-LongKeyNameText(unsigned long val)
-{
-    char buf[XkbKeyNameLength];
-    LongToKeyName(val, buf);
-    return KeyNameText(buf);
-}
+/***====================================================================***/
 
 static inline bool
 ReportNotArray(struct xkb_keymap *keymap, const char *type, const char *field,
@@ -119,4 +115,4 @@ ReportBadField(struct xkb_keymap *keymap, const char *type, const char *field,
     return false;
 }
 
-#endif /* XKBCOMP_PRIV_H */
+#endif
index 35e0ee13abd4779f42a6430118ee9d001fc083f5..a65550a9f1df2619c854f0b390adb109eaec0aa8 100644 (file)
  */
 
 #include "xkbcomp-priv.h"
+#include "text.h"
 #include "rules.h"
-#include "parseutils.h"
-
-static XkbFile *
-keymap_file_from_names(struct xkb_context *ctx,
-                       const struct xkb_rule_names *rmlvo)
-{
-    struct xkb_component_names kkctgs;
-    XkbFile *keycodes, *types, *compat, *symbols;
-    IncludeStmt *inc;
-
-    if (!xkb_components_from_rules(ctx, rmlvo, &kkctgs)) {
-        log_err(ctx,
-                "Couldn't look up rules '%s', model '%s', layout '%s', "
-                "variant '%s', options '%s'\n",
-                rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
-                rmlvo->options);
-        return NULL;
-    }
-
-    inc = IncludeCreate(ctx, kkctgs.keycodes, MERGE_DEFAULT);
-    keycodes = CreateXKBFile(ctx, FILE_TYPE_KEYCODES, NULL,
-                             (ParseCommon *) inc, 0);
-
-    inc = IncludeCreate(ctx, kkctgs.types, MERGE_DEFAULT);
-    types = CreateXKBFile(ctx, FILE_TYPE_TYPES, NULL,
-                          (ParseCommon *) inc, 0);
-    AppendStmt(&keycodes->common, &types->common);
-
-    inc = IncludeCreate(ctx, kkctgs.compat, MERGE_DEFAULT);
-    compat = CreateXKBFile(ctx, FILE_TYPE_COMPAT, NULL,
-                           (ParseCommon *) inc, 0);
-    AppendStmt(&keycodes->common, &compat->common);
-
-    inc = IncludeCreate(ctx, kkctgs.symbols, MERGE_DEFAULT);
-    symbols = CreateXKBFile(ctx, FILE_TYPE_SYMBOLS, NULL,
-                            (ParseCommon *) inc, 0);
-    AppendStmt(&keycodes->common, &symbols->common);
-
-    free(kkctgs.keycodes);
-    free(kkctgs.types);
-    free(kkctgs.compat);
-    free(kkctgs.symbols);
-
-    return CreateXKBFile(ctx, FILE_TYPE_KEYMAP, strdup(""),
-                         &keycodes->common, 0);
-}
-
-static struct xkb_keymap *
-new_keymap(struct xkb_context *ctx)
-{
-    struct xkb_keymap *keymap;
-
-    keymap = calloc(1, sizeof(*keymap));
-    if (!keymap)
-        return NULL;
-
-    keymap->refcnt = 1;
-    keymap->ctx = xkb_context_ref(ctx);
-
-    return keymap;
-}
 
 /**
  * Compile the given file and store the output in keymap.
@@ -105,7 +45,7 @@ compile_keymap(struct xkb_context *ctx, XkbFile *file)
     XkbFile *compat = NULL;
     XkbFile *symbols = NULL;
 
-    keymap = new_keymap(ctx);
+    keymap = xkb_map_new(ctx);
     if (!keymap)
         goto err;
 
@@ -218,6 +158,8 @@ xkb_map_new_from_names(struct xkb_context *ctx,
                        const struct xkb_rule_names *rmlvo_in,
                        enum xkb_map_compile_flags flags)
 {
+    bool ok;
+    struct xkb_component_names kccgst;
     struct xkb_rule_names rmlvo = *rmlvo_in;
     XkbFile *file;
     struct xkb_keymap *keymap;
@@ -229,7 +171,23 @@ xkb_map_new_from_names(struct xkb_context *ctx,
     if (isempty(rmlvo.layout))
         rmlvo.layout = DEFAULT_XKB_LAYOUT;
 
-    file = keymap_file_from_names(ctx, &rmlvo);
+    ok = xkb_components_from_rules(ctx, &rmlvo, &kccgst);
+    if (!ok) {
+        log_err(ctx,
+                "Couldn't look up rules '%s', model '%s', layout '%s', "
+                "variant '%s', options '%s'\n",
+                rmlvo.rules, rmlvo.model, rmlvo.layout, rmlvo.variant,
+                rmlvo.options);
+        return NULL;
+    }
+
+    file = XkbFileFromComponents(ctx, &kccgst);
+
+    free(kccgst.keycodes);
+    free(kccgst.types);
+    free(kccgst.compat);
+    free(kccgst.symbols);
+
     if (!file) {
         log_err(ctx,
                 "Failed to generate parsed XKB file from components\n");
@@ -237,7 +195,7 @@ xkb_map_new_from_names(struct xkb_context *ctx,
     }
 
     keymap = compile_keymap(ctx, file);
-    FreeXKBFile(file);
+    FreeXkbFile(file);
     return keymap;
 }
 
@@ -261,14 +219,14 @@ xkb_map_new_from_string(struct xkb_context *ctx,
         return NULL;
     }
 
-    ok = XKBParseString(ctx, string, "input", &file);
+    ok = XkbParseString(ctx, string, "input", &file);
     if (!ok) {
         log_err(ctx, "Failed to parse input xkb file\n");
         return NULL;
     }
 
     keymap = compile_keymap(ctx, file);
-    FreeXKBFile(file);
+    FreeXkbFile(file);
     return keymap;
 }
 
@@ -292,57 +250,13 @@ xkb_map_new_from_file(struct xkb_context *ctx,
         return NULL;
     }
 
-    ok = XKBParseFile(ctx, file, "(unknown file)", &xkb_file);
+    ok = XkbParseFile(ctx, file, "(unknown file)", &xkb_file);
     if (!ok) {
         log_err(ctx, "Failed to parse input xkb file\n");
         return NULL;
     }
 
     keymap = compile_keymap(ctx, xkb_file);
-    FreeXKBFile(xkb_file);
-    return keymap;
-}
-
-XKB_EXPORT struct xkb_keymap *
-xkb_map_ref(struct xkb_keymap *keymap)
-{
-    keymap->refcnt++;
+    FreeXkbFile(xkb_file);
     return keymap;
 }
-
-XKB_EXPORT void
-xkb_map_unref(struct xkb_keymap *keymap)
-{
-    unsigned int i;
-    struct xkb_key *key;
-
-    if (!keymap || --keymap->refcnt > 0)
-        return;
-
-    for (i = 0; i < keymap->num_types; i++) {
-        free(keymap->types[i].map);
-        free(keymap->types[i].level_names);
-    }
-    free(keymap->types);
-
-    darray_foreach(key, keymap->keys) {
-        free(key->sym_index);
-        free(key->num_syms);
-        darray_free(key->syms);
-        free(key->actions);
-    }
-    darray_free(keymap->keys);
-
-    darray_free(keymap->sym_interpret);
-
-    darray_free(keymap->key_aliases);
-
-    free(keymap->keycodes_section_name);
-    free(keymap->symbols_section_name);
-    free(keymap->types_section_name);
-    free(keymap->compat_section_name);
-
-    xkb_context_unref(keymap->ctx);
-
-    free(keymap);
-}
diff --git a/src/xkbcomp/xkbcomp.h b/src/xkbcomp/xkbcomp.h
deleted file mode 100644 (file)
index b74d1c6..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/************************************************************
- * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of Silicon Graphics not be
- * used in advertising or publicity pertaining to distribution
- * of the software without specific prior written permission.
- * Silicon Graphics makes no representation about the suitability
- * of this software for any purpose. It is provided "as is"
- * without any express or implied warranty.
- *
- * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- ********************************************************/
-
-#ifndef XKBCOMP_H
-#define XKBCOMP_H 1
-
-#include "xkb-priv.h"
-
-enum stmt_type {
-    STMT_UNKNOWN = 0,
-    STMT_INCLUDE,
-    STMT_KEYCODE,
-    STMT_ALIAS,
-    STMT_EXPR,
-    STMT_VAR,
-    STMT_TYPE,
-    STMT_INTERP,
-    STMT_VMOD,
-    STMT_SYMBOLS,
-    STMT_MODMAP,
-    STMT_GROUP_COMPAT,
-    STMT_INDICATOR_MAP,
-    STMT_INDICATOR_NAME,
-    _STMT_NUM_VALUES
-};
-
-enum expr_value_type {
-    EXPR_TYPE_UNKNOWN = 0,
-    EXPR_TYPE_BOOLEAN,
-    EXPR_TYPE_INT,
-    EXPR_TYPE_STRING,
-    EXPR_TYPE_ACTION,
-    EXPR_TYPE_KEYNAME,
-    EXPR_TYPE_SYMBOLS,
-};
-
-enum expr_op_type {
-    EXPR_VALUE = 0,
-    EXPR_IDENT,
-    EXPR_ACTION_DECL,
-    EXPR_FIELD_REF,
-    EXPR_ARRAY_REF,
-    EXPR_KEYSYM_LIST,
-    EXPR_ACTION_LIST,
-    EXPR_ADD,
-    EXPR_SUBTRACT,
-    EXPR_MULTIPLY,
-    EXPR_DIVIDE,
-    EXPR_ASSIGN,
-    EXPR_NOT,
-    EXPR_NEGATE,
-    EXPR_INVERT,
-    EXPR_UNARY_PLUS,
-};
-
-enum merge_mode {
-    MERGE_DEFAULT,
-    MERGE_AUGMENT,
-    MERGE_OVERRIDE,
-    MERGE_REPLACE,
-};
-
-typedef struct _ParseCommon {
-    enum stmt_type type;
-    struct _ParseCommon *next;
-} ParseCommon;
-
-typedef struct _IncludeStmt {
-    ParseCommon common;
-    enum merge_mode merge;
-    char *stmt;
-    char *file;
-    char *map;
-    char *modifier;
-    struct _IncludeStmt *next_incl;
-} IncludeStmt;
-
-typedef struct _Expr {
-    ParseCommon common;
-    enum expr_op_type op;
-    enum expr_value_type value_type;
-    union {
-        struct {
-            struct _Expr *left;
-            struct _Expr *right;
-        } binary;
-        struct {
-            xkb_atom_t element;
-            xkb_atom_t field;
-        } field;
-        struct {
-            xkb_atom_t element;
-            xkb_atom_t field;
-            struct _Expr *entry;
-        } array;
-        struct {
-            xkb_atom_t name;
-            struct _Expr *args;
-        } action;
-        struct {
-            darray(char *) syms;
-            darray(int) symsMapIndex;
-            darray(unsigned int) symsNumEntries;
-        } list;
-        struct _Expr *child;
-        xkb_atom_t str;
-        unsigned uval;
-        int ival;
-        char keyName[XkbKeyNameLength];
-    } value;
-} ExprDef;
-
-typedef struct _VarDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    ExprDef *name;
-    ExprDef *value;
-} VarDef;
-
-typedef struct _VModDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    xkb_atom_t name;
-    ExprDef *value;
-} VModDef;
-
-typedef struct _KeycodeDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    char name[XkbKeyNameLength];
-    unsigned long value;
-} KeycodeDef;
-
-typedef struct _KeyAliasDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    char alias[XkbKeyNameLength];
-    char real[XkbKeyNameLength];
-} KeyAliasDef;
-
-typedef struct _KeyTypeDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    xkb_atom_t name;
-    VarDef *body;
-} KeyTypeDef;
-
-typedef struct _SymbolsDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    char keyName[XkbKeyNameLength];
-    ExprDef *symbols;
-} SymbolsDef;
-
-typedef struct _ModMapDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    xkb_atom_t modifier;
-    ExprDef *keys;
-} ModMapDef;
-
-typedef struct _GroupCompatDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    int group;
-    ExprDef *def;
-} GroupCompatDef;
-
-typedef struct _InterpDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    char *sym;
-    ExprDef *match;
-    VarDef *def;
-} InterpDef;
-
-typedef struct _IndicatorNameDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    int ndx;
-    ExprDef *name;
-    bool virtual;
-} IndicatorNameDef;
-
-typedef struct _IndicatorMapDef {
-    ParseCommon common;
-    enum merge_mode merge;
-    xkb_atom_t name;
-    VarDef *body;
-} IndicatorMapDef;
-
-typedef struct _XkbFile {
-    ParseCommon common;
-    enum xkb_file_type file_type;
-    char *topName;
-    char *name;
-    ParseCommon *defs;
-    int id;
-    unsigned flags;
-} XkbFile;
-
-extern bool
-CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap,
-                enum merge_mode merge);
-
-extern bool
-CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
-                enum merge_mode merge);
-
-extern bool
-CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap,
-                 enum merge_mode merge);
-
-extern bool
-CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
-               enum merge_mode merge);
-
-#endif /* XKBCOMP_H */
index d239c2e7bbcffc1c7bd2286367baf4f609bbd15e..ee53f09292108ee0135ade2c2924c9994cad1ced 100644 (file)
@@ -26,9 +26,9 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "xkbcommon/xkbcommon.h"
-#include "rules.h"
 #include "test.h"
+#include "xkb-priv.h"
+#include "rules.h"
 
 struct test_data {
     /* Rules file */