parseutils.c revision c82dfdfb
1f46a6179Smrg/************************************************************
2f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3f46a6179Smrg
4f46a6179Smrg Permission to use, copy, modify, and distribute this
5f46a6179Smrg software and its documentation for any purpose and without
6f46a6179Smrg fee is hereby granted, provided that the above copyright
7f46a6179Smrg notice appear in all copies and that both that copyright
8f46a6179Smrg notice and this permission notice appear in supporting
9f46a6179Smrg documentation, and that the name of Silicon Graphics not be
10f46a6179Smrg used in advertising or publicity pertaining to distribution
11f46a6179Smrg of the software without specific prior written permission.
12f46a6179Smrg Silicon Graphics makes no representation about the suitability
13f46a6179Smrg of this software for any purpose. It is provided "as is"
14f46a6179Smrg without any express or implied warranty.
15f46a6179Smrg
16f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
24f46a6179Smrg
25f46a6179Smrg ********************************************************/
26f46a6179Smrg
27f46a6179Smrg#define	DEBUG_VAR parseDebug
28f46a6179Smrg#include "parseutils.h"
29f46a6179Smrg#include "xkbpath.h"
30f46a6179Smrg#include <X11/keysym.h>
31f46a6179Smrg#include <X11/extensions/XKBgeom.h>
32f46a6179Smrg#include <X11/Xalloca.h>
3383e5f723Smrg#include <limits.h>
3483e5f723Smrg#include <stdlib.h>
35f46a6179Smrg
3634345a63SmrgXkbFile *rtrnValue;
37f46a6179Smrg
38f46a6179SmrgParseCommon *
3934345a63SmrgAppendStmt(ParseCommon * to, ParseCommon * append)
40f46a6179Smrg{
4134345a63Smrg    ParseCommon *start = to;
42f46a6179Smrg
4334345a63Smrg    if (append == NULL)
4434345a63Smrg        return to;
4534345a63Smrg    while ((to != NULL) && (to->next != NULL))
4634345a63Smrg    {
4734345a63Smrg        to = to->next;
48f46a6179Smrg    }
4934345a63Smrg    if (to)
5034345a63Smrg    {
5134345a63Smrg        to->next = append;
5234345a63Smrg        return start;
53f46a6179Smrg    }
54f46a6179Smrg    return append;
55f46a6179Smrg}
56f46a6179Smrg
57f46a6179SmrgExprDef *
5834345a63SmrgExprCreate(unsigned op, unsigned type)
5934345a63Smrg{
6034345a63Smrg    ExprDef *expr;
6134345a63Smrg    expr = uTypedAlloc(ExprDef);
6234345a63Smrg    if (expr)
6334345a63Smrg    {
6434345a63Smrg        expr->common.stmtType = StmtExpr;
6534345a63Smrg        expr->common.next = NULL;
6634345a63Smrg        expr->op = op;
6734345a63Smrg        expr->type = type;
6834345a63Smrg    }
6934345a63Smrg    else
7034345a63Smrg    {
7134345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
7234345a63Smrg        /* NOTREACHED */
73f46a6179Smrg    }
74f46a6179Smrg    return expr;
75f46a6179Smrg}
76f46a6179Smrg
77f46a6179SmrgExprDef *
7834345a63SmrgExprCreateUnary(unsigned op, unsigned type, ExprDef * child)
7934345a63Smrg{
8034345a63Smrg    ExprDef *expr;
8134345a63Smrg    expr = uTypedAlloc(ExprDef);
8234345a63Smrg    if (expr)
8334345a63Smrg    {
8434345a63Smrg        expr->common.stmtType = StmtExpr;
8534345a63Smrg        expr->common.next = NULL;
8634345a63Smrg        expr->op = op;
8734345a63Smrg        expr->type = type;
8834345a63Smrg        expr->value.child = child;
8934345a63Smrg    }
9034345a63Smrg    else
9134345a63Smrg    {
9234345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
9334345a63Smrg        /* NOTREACHED */
94f46a6179Smrg    }
95f46a6179Smrg    return expr;
96f46a6179Smrg}
97f46a6179Smrg
98f46a6179SmrgExprDef *
9934345a63SmrgExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
10034345a63Smrg{
10134345a63Smrg    ExprDef *expr;
10234345a63Smrg    expr = uTypedAlloc(ExprDef);
10334345a63Smrg    if (expr)
10434345a63Smrg    {
10534345a63Smrg        expr->common.stmtType = StmtExpr;
10634345a63Smrg        expr->common.next = NULL;
10734345a63Smrg        expr->op = op;
10834345a63Smrg        if ((op == OpAssign) || (left->type == TypeUnknown))
10934345a63Smrg            expr->type = right->type;
11034345a63Smrg        else if ((left->type == right->type) || (right->type == TypeUnknown))
11134345a63Smrg            expr->type = left->type;
11234345a63Smrg        else
11334345a63Smrg            expr->type = TypeUnknown;
11434345a63Smrg        expr->value.binary.left = left;
11534345a63Smrg        expr->value.binary.right = right;
11634345a63Smrg    }
11734345a63Smrg    else
11834345a63Smrg    {
11934345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
12034345a63Smrg        /* NOTREACHED */
121f46a6179Smrg    }
122f46a6179Smrg    return expr;
123f46a6179Smrg}
124f46a6179Smrg
125f46a6179SmrgKeycodeDef *
12634345a63SmrgKeycodeCreate(char *name, ExprDef * value)
127f46a6179Smrg{
12834345a63Smrg    KeycodeDef *def;
129f46a6179Smrg
13034345a63Smrg    def = uTypedAlloc(KeycodeDef);
13134345a63Smrg    if (def)
13234345a63Smrg    {
13334345a63Smrg        def->common.stmtType = StmtKeycodeDef;
13434345a63Smrg        def->common.next = NULL;
13534345a63Smrg        strncpy(def->name, name, XkbKeyNameLength);
13634345a63Smrg        def->name[XkbKeyNameLength] = '\0';
13734345a63Smrg        def->value = value;
138f46a6179Smrg    }
13934345a63Smrg    else
14034345a63Smrg    {
14134345a63Smrg        FATAL("Couldn't allocate key name definition in parser\n");
14234345a63Smrg        /* NOTREACHED */
143f46a6179Smrg    }
144f46a6179Smrg    return def;
145f46a6179Smrg}
146f46a6179Smrg
147f46a6179SmrgKeyAliasDef *
14834345a63SmrgKeyAliasCreate(char *alias, char *real)
149f46a6179Smrg{
15034345a63Smrg    KeyAliasDef *def;
151f46a6179Smrg
15234345a63Smrg    def = uTypedAlloc(KeyAliasDef);
15334345a63Smrg    if (def)
15434345a63Smrg    {
15534345a63Smrg        def->common.stmtType = StmtKeyAliasDef;
15634345a63Smrg        def->common.next = NULL;
15734345a63Smrg        strncpy(def->alias, alias, XkbKeyNameLength);
15834345a63Smrg        def->alias[XkbKeyNameLength] = '\0';
15934345a63Smrg        strncpy(def->real, real, XkbKeyNameLength);
16034345a63Smrg        def->real[XkbKeyNameLength] = '\0';
161f46a6179Smrg    }
16234345a63Smrg    else
16334345a63Smrg    {
16434345a63Smrg        FATAL("Couldn't allocate key alias definition in parser\n");
16534345a63Smrg        /* NOTREACHED */
166f46a6179Smrg    }
167f46a6179Smrg    return def;
168f46a6179Smrg}
169f46a6179Smrg
170f46a6179SmrgVModDef *
17134345a63SmrgVModCreate(Atom name, ExprDef * value)
17234345a63Smrg{
17334345a63Smrg    VModDef *def;
17434345a63Smrg    def = uTypedAlloc(VModDef);
17534345a63Smrg    if (def)
17634345a63Smrg    {
17734345a63Smrg        def->common.stmtType = StmtVModDef;
17834345a63Smrg        def->common.next = NULL;
17934345a63Smrg        def->name = name;
18034345a63Smrg        def->value = value;
18134345a63Smrg    }
18234345a63Smrg    else
18334345a63Smrg    {
18434345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
18534345a63Smrg        /* NOTREACHED */
186f46a6179Smrg    }
187f46a6179Smrg    return def;
188f46a6179Smrg}
189f46a6179Smrg
190f46a6179SmrgVarDef *
19134345a63SmrgVarCreate(ExprDef * name, ExprDef * value)
19234345a63Smrg{
19334345a63Smrg    VarDef *def;
19434345a63Smrg    def = uTypedAlloc(VarDef);
19534345a63Smrg    if (def)
19634345a63Smrg    {
19734345a63Smrg        def->common.stmtType = StmtVarDef;
19834345a63Smrg        def->common.next = NULL;
19934345a63Smrg        def->name = name;
20034345a63Smrg        def->value = value;
20134345a63Smrg    }
20234345a63Smrg    else
20334345a63Smrg    {
20434345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
20534345a63Smrg        /* NOTREACHED */
206f46a6179Smrg    }
207f46a6179Smrg    return def;
208f46a6179Smrg}
209f46a6179Smrg
210f46a6179SmrgVarDef *
21134345a63SmrgBoolVarCreate(Atom nameToken, unsigned set)
212f46a6179Smrg{
21334345a63Smrg    ExprDef *name, *value;
214f46a6179Smrg
21534345a63Smrg    name = ExprCreate(ExprIdent, TypeUnknown);
21634345a63Smrg    name->value.str = nameToken;
21734345a63Smrg    value = ExprCreate(ExprValue, TypeBoolean);
21834345a63Smrg    value->value.uval = set;
21934345a63Smrg    return VarCreate(name, value);
220f46a6179Smrg}
221f46a6179Smrg
222f46a6179SmrgInterpDef *
223690143ccSmrgInterpCreate(const char *sym_str, ExprDef * match)
224f46a6179Smrg{
22534345a63Smrg    InterpDef *def;
226f46a6179Smrg
22734345a63Smrg    def = uTypedAlloc(InterpDef);
22834345a63Smrg    if (def)
22934345a63Smrg    {
23034345a63Smrg        def->common.stmtType = StmtInterpDef;
23134345a63Smrg        def->common.next = NULL;
232690143ccSmrg        if (LookupKeysym(sym_str, &def->sym) == 0)
233690143ccSmrg            def->ignore = True;
234690143ccSmrg        else
235690143ccSmrg            def->ignore = False;
23634345a63Smrg        def->match = match;
237f46a6179Smrg    }
23834345a63Smrg    else
23934345a63Smrg    {
24034345a63Smrg        FATAL("Couldn't allocate interp definition in parser\n");
24134345a63Smrg        /* NOTREACHED */
242f46a6179Smrg    }
243f46a6179Smrg    return def;
244f46a6179Smrg}
245f46a6179Smrg
246f46a6179SmrgKeyTypeDef *
24734345a63SmrgKeyTypeCreate(Atom name, VarDef * body)
248f46a6179Smrg{
24934345a63Smrg    KeyTypeDef *def;
250f46a6179Smrg
25134345a63Smrg    def = uTypedAlloc(KeyTypeDef);
25234345a63Smrg    if (def)
25334345a63Smrg    {
25434345a63Smrg        def->common.stmtType = StmtKeyTypeDef;
25534345a63Smrg        def->common.next = NULL;
25634345a63Smrg        def->merge = MergeDefault;
25734345a63Smrg        def->name = name;
25834345a63Smrg        def->body = body;
259f46a6179Smrg    }
26034345a63Smrg    else
26134345a63Smrg    {
26234345a63Smrg        FATAL("Couldn't allocate key type definition in parser\n");
26334345a63Smrg        /* NOTREACHED */
264f46a6179Smrg    }
265f46a6179Smrg    return def;
266f46a6179Smrg}
267f46a6179Smrg
268f46a6179SmrgSymbolsDef *
26934345a63SmrgSymbolsCreate(char *keyName, ExprDef * symbols)
270f46a6179Smrg{
27134345a63Smrg    SymbolsDef *def;
272f46a6179Smrg
27334345a63Smrg    def = uTypedAlloc(SymbolsDef);
27434345a63Smrg    if (def)
27534345a63Smrg    {
27634345a63Smrg        def->common.stmtType = StmtSymbolsDef;
27734345a63Smrg        def->common.next = NULL;
27834345a63Smrg        def->merge = MergeDefault;
27934345a63Smrg        bzero(def->keyName, 5);
28034345a63Smrg        strncpy(def->keyName, keyName, 4);
28134345a63Smrg        def->symbols = symbols;
282f46a6179Smrg    }
28334345a63Smrg    else
28434345a63Smrg    {
28534345a63Smrg        FATAL("Couldn't allocate symbols definition in parser\n");
28634345a63Smrg        /* NOTREACHED */
287f46a6179Smrg    }
288f46a6179Smrg    return def;
289f46a6179Smrg}
290f46a6179Smrg
291f46a6179SmrgGroupCompatDef *
29234345a63SmrgGroupCompatCreate(int group, ExprDef * val)
293f46a6179Smrg{
29434345a63Smrg    GroupCompatDef *def;
295f46a6179Smrg
29634345a63Smrg    def = uTypedAlloc(GroupCompatDef);
29734345a63Smrg    if (def)
29834345a63Smrg    {
29934345a63Smrg        def->common.stmtType = StmtGroupCompatDef;
30034345a63Smrg        def->common.next = NULL;
30134345a63Smrg        def->merge = MergeDefault;
30234345a63Smrg        def->group = group;
30334345a63Smrg        def->def = val;
304f46a6179Smrg    }
30534345a63Smrg    else
30634345a63Smrg    {
30734345a63Smrg        FATAL("Couldn't allocate group compat definition in parser\n");
30834345a63Smrg        /* NOTREACHED */
309f46a6179Smrg    }
310f46a6179Smrg    return def;
311f46a6179Smrg}
312f46a6179Smrg
313f46a6179SmrgModMapDef *
31434345a63SmrgModMapCreate(Atom modifier, ExprDef * keys)
315f46a6179Smrg{
31634345a63Smrg    ModMapDef *def;
317f46a6179Smrg
31834345a63Smrg    def = uTypedAlloc(ModMapDef);
31934345a63Smrg    if (def)
32034345a63Smrg    {
32134345a63Smrg        def->common.stmtType = StmtModMapDef;
32234345a63Smrg        def->common.next = NULL;
32334345a63Smrg        def->merge = MergeDefault;
32434345a63Smrg        def->modifier = modifier;
32534345a63Smrg        def->keys = keys;
326f46a6179Smrg    }
32734345a63Smrg    else
32834345a63Smrg    {
32934345a63Smrg        FATAL("Couldn't allocate mod mask definition in parser\n");
33034345a63Smrg        /* NOTREACHED */
331f46a6179Smrg    }
332f46a6179Smrg    return def;
333f46a6179Smrg}
334f46a6179Smrg
335f46a6179SmrgIndicatorMapDef *
33634345a63SmrgIndicatorMapCreate(Atom name, VarDef * body)
337f46a6179Smrg{
33834345a63Smrg    IndicatorMapDef *def;
339f46a6179Smrg
34034345a63Smrg    def = uTypedAlloc(IndicatorMapDef);
34134345a63Smrg    if (def)
34234345a63Smrg    {
34334345a63Smrg        def->common.stmtType = StmtIndicatorMapDef;
34434345a63Smrg        def->common.next = NULL;
34534345a63Smrg        def->merge = MergeDefault;
34634345a63Smrg        def->name = name;
34734345a63Smrg        def->body = body;
348f46a6179Smrg    }
34934345a63Smrg    else
35034345a63Smrg    {
35134345a63Smrg        FATAL("Couldn't allocate indicator map definition in parser\n");
35234345a63Smrg        /* NOTREACHED */
353f46a6179Smrg    }
354f46a6179Smrg    return def;
355f46a6179Smrg}
356f46a6179Smrg
357f46a6179SmrgIndicatorNameDef *
35834345a63SmrgIndicatorNameCreate(int ndx, ExprDef * name, Bool virtual)
359f46a6179Smrg{
36034345a63Smrg    IndicatorNameDef *def;
361f46a6179Smrg
36234345a63Smrg    def = uTypedAlloc(IndicatorNameDef);
36334345a63Smrg    if (def)
36434345a63Smrg    {
36534345a63Smrg        def->common.stmtType = StmtIndicatorNameDef;
36634345a63Smrg        def->common.next = NULL;
36734345a63Smrg        def->merge = MergeDefault;
36834345a63Smrg        def->ndx = ndx;
36934345a63Smrg        def->name = name;
37034345a63Smrg        def->virtual = virtual;
371f46a6179Smrg    }
37234345a63Smrg    else
37334345a63Smrg    {
37434345a63Smrg        FATAL("Couldn't allocate indicator index definition in parser\n");
37534345a63Smrg        /* NOTREACHED */
376f46a6179Smrg    }
377f46a6179Smrg    return def;
378f46a6179Smrg}
379f46a6179Smrg
380f46a6179SmrgExprDef *
38134345a63SmrgActionCreate(Atom name, ExprDef * args)
382f46a6179Smrg{
38334345a63Smrg    ExprDef *act;
384f46a6179Smrg
38534345a63Smrg    act = uTypedAlloc(ExprDef);
38634345a63Smrg    if (act)
38734345a63Smrg    {
38834345a63Smrg        act->common.stmtType = StmtExpr;
38934345a63Smrg        act->common.next = NULL;
39034345a63Smrg        act->op = ExprActionDecl;
39134345a63Smrg        act->value.action.name = name;
39234345a63Smrg        act->value.action.args = args;
39334345a63Smrg        return act;
394f46a6179Smrg    }
395f46a6179Smrg    FATAL("Couldn't allocate ActionDef in parser\n");
396f46a6179Smrg    return NULL;
397f46a6179Smrg}
398f46a6179Smrg
399f46a6179SmrgExprDef *
40083e5f723SmrgCreateKeysymList(char *sym)
401f46a6179Smrg{
40234345a63Smrg    ExprDef *def;
403f46a6179Smrg
40434345a63Smrg    def = ExprCreate(ExprKeysymList, TypeSymbols);
40534345a63Smrg    if (def)
40634345a63Smrg    {
40734345a63Smrg        def->value.list.nSyms = 1;
40883e5f723Smrg        def->value.list.szSyms = 4;
40983e5f723Smrg        def->value.list.syms = uTypedCalloc(4, char *);
41034345a63Smrg        if (def->value.list.syms != NULL)
41134345a63Smrg        {
41234345a63Smrg            def->value.list.syms[0] = sym;
41334345a63Smrg            return def;
41434345a63Smrg        }
415f46a6179Smrg    }
416f46a6179Smrg    FATAL("Couldn't allocate expression for keysym list in parser\n");
417f46a6179Smrg    return NULL;
418f46a6179Smrg}
419f46a6179Smrg
420f46a6179SmrgShapeDef *
42134345a63SmrgShapeDeclCreate(Atom name, OutlineDef * outlines)
42234345a63Smrg{
42334345a63Smrg    ShapeDef *shape;
42434345a63Smrg    OutlineDef *ol;
42534345a63Smrg
42634345a63Smrg    shape = uTypedAlloc(ShapeDef);
42734345a63Smrg    if (shape != NULL)
42834345a63Smrg    {
42934345a63Smrg        bzero(shape, sizeof(ShapeDef));
43034345a63Smrg        shape->common.stmtType = StmtShapeDef;
43134345a63Smrg        shape->common.next = NULL;
43234345a63Smrg        shape->merge = MergeDefault;
43334345a63Smrg        shape->name = name;
43434345a63Smrg        shape->nOutlines = 0;
43534345a63Smrg        shape->outlines = outlines;
43634345a63Smrg        for (ol = outlines; ol != NULL; ol = (OutlineDef *) ol->common.next)
43734345a63Smrg        {
43834345a63Smrg            if (ol->nPoints > 0)
43934345a63Smrg                shape->nOutlines++;
44034345a63Smrg        }
441f46a6179Smrg    }
442f46a6179Smrg    return shape;
443f46a6179Smrg}
444f46a6179Smrg
445f46a6179SmrgOutlineDef *
44634345a63SmrgOutlineCreate(Atom field, ExprDef * points)
44734345a63Smrg{
44834345a63Smrg    OutlineDef *outline;
44934345a63Smrg    ExprDef *pt;
45034345a63Smrg
45134345a63Smrg    outline = uTypedAlloc(OutlineDef);
45234345a63Smrg    if (outline != NULL)
45334345a63Smrg    {
45434345a63Smrg        bzero(outline, sizeof(OutlineDef));
45534345a63Smrg        outline->common.stmtType = StmtOutlineDef;
45634345a63Smrg        outline->common.next = NULL;
45734345a63Smrg        outline->field = field;
45834345a63Smrg        outline->nPoints = 0;
45934345a63Smrg        if (points->op == ExprCoord)
46034345a63Smrg        {
46134345a63Smrg            for (pt = points; pt != NULL; pt = (ExprDef *) pt->common.next)
46234345a63Smrg            {
46334345a63Smrg                outline->nPoints++;
46434345a63Smrg            }
46534345a63Smrg        }
46634345a63Smrg        outline->points = points;
467f46a6179Smrg    }
468f46a6179Smrg    return outline;
469f46a6179Smrg}
470f46a6179Smrg
471f46a6179SmrgKeyDef *
47234345a63SmrgKeyDeclCreate(char *name, ExprDef * expr)
473f46a6179Smrg{
47434345a63Smrg    KeyDef *key;
475f46a6179Smrg
47634345a63Smrg    key = uTypedAlloc(KeyDef);
47734345a63Smrg    if (key != NULL)
47834345a63Smrg    {
47934345a63Smrg        bzero(key, sizeof(KeyDef));
48034345a63Smrg        key->common.stmtType = StmtKeyDef;
48134345a63Smrg        key->common.next = NULL;
48234345a63Smrg        if (name)
48334345a63Smrg            key->name = name;
48434345a63Smrg        else
48534345a63Smrg            key->expr = expr;
486f46a6179Smrg    }
487f46a6179Smrg    return key;
488f46a6179Smrg}
489f46a6179Smrg
490f46a6179SmrgKeyDef *
49134345a63SmrgKeyDeclMerge(KeyDef * into, KeyDef * from)
492f46a6179Smrg{
49334345a63Smrg    into->expr =
49434345a63Smrg        (ExprDef *) AppendStmt(&into->expr->common, &from->expr->common);
49534345a63Smrg    from->expr = NULL;
496f46a6179Smrg    uFree(from);
497f46a6179Smrg    return into;
498f46a6179Smrg}
499f46a6179Smrg
500f46a6179SmrgRowDef *
50134345a63SmrgRowDeclCreate(KeyDef * keys)
50234345a63Smrg{
50334345a63Smrg    RowDef *row;
50434345a63Smrg    KeyDef *key;
50534345a63Smrg
50634345a63Smrg    row = uTypedAlloc(RowDef);
50734345a63Smrg    if (row != NULL)
50834345a63Smrg    {
50934345a63Smrg        bzero(row, sizeof(RowDef));
51034345a63Smrg        row->common.stmtType = StmtRowDef;
51134345a63Smrg        row->common.next = NULL;
51234345a63Smrg        row->nKeys = 0;
51334345a63Smrg        row->keys = keys;
51434345a63Smrg        for (key = keys; key != NULL; key = (KeyDef *) key->common.next)
51534345a63Smrg        {
51634345a63Smrg            if (key->common.stmtType == StmtKeyDef)
51734345a63Smrg                row->nKeys++;
51834345a63Smrg        }
519f46a6179Smrg    }
520f46a6179Smrg    return row;
521f46a6179Smrg}
522f46a6179Smrg
523f46a6179SmrgSectionDef *
52434345a63SmrgSectionDeclCreate(Atom name, RowDef * rows)
52534345a63Smrg{
52634345a63Smrg    SectionDef *section;
52734345a63Smrg    RowDef *row;
52834345a63Smrg
52934345a63Smrg    section = uTypedAlloc(SectionDef);
53034345a63Smrg    if (section != NULL)
53134345a63Smrg    {
53234345a63Smrg        bzero(section, sizeof(SectionDef));
53334345a63Smrg        section->common.stmtType = StmtSectionDef;
53434345a63Smrg        section->common.next = NULL;
53534345a63Smrg        section->name = name;
53634345a63Smrg        section->nRows = 0;
53734345a63Smrg        section->rows = rows;
53834345a63Smrg        for (row = rows; row != NULL; row = (RowDef *) row->common.next)
53934345a63Smrg        {
54034345a63Smrg            if (row->common.stmtType == StmtRowDef)
54134345a63Smrg                section->nRows++;
54234345a63Smrg        }
543f46a6179Smrg    }
544f46a6179Smrg    return section;
545f46a6179Smrg}
546f46a6179Smrg
547f46a6179SmrgOverlayKeyDef *
54834345a63SmrgOverlayKeyCreate(char *under, char *over)
54934345a63Smrg{
55034345a63Smrg    OverlayKeyDef *key;
55134345a63Smrg
55234345a63Smrg    key = uTypedAlloc(OverlayKeyDef);
55334345a63Smrg    if (key != NULL)
55434345a63Smrg    {
55534345a63Smrg        bzero(key, sizeof(OverlayKeyDef));
55634345a63Smrg        key->common.stmtType = StmtOverlayKeyDef;
55734345a63Smrg        strncpy(key->over, over, XkbKeyNameLength);
55834345a63Smrg        strncpy(key->under, under, XkbKeyNameLength);
559c82dfdfbSmrg        uFree(over);
560c82dfdfbSmrg        uFree(under);
561f46a6179Smrg    }
562f46a6179Smrg    return key;
563f46a6179Smrg}
564f46a6179Smrg
565f46a6179SmrgOverlayDef *
56634345a63SmrgOverlayDeclCreate(Atom name, OverlayKeyDef * keys)
56734345a63Smrg{
56834345a63Smrg    OverlayDef *ol;
56934345a63Smrg    OverlayKeyDef *key;
57034345a63Smrg
57134345a63Smrg    ol = uTypedAlloc(OverlayDef);
57234345a63Smrg    if (ol != NULL)
57334345a63Smrg    {
57434345a63Smrg        bzero(ol, sizeof(OverlayDef));
57534345a63Smrg        ol->common.stmtType = StmtOverlayDef;
57634345a63Smrg        ol->name = name;
57734345a63Smrg        ol->keys = keys;
57834345a63Smrg        for (key = keys; key != NULL;
57934345a63Smrg             key = (OverlayKeyDef *) key->common.next)
58034345a63Smrg        {
58134345a63Smrg            ol->nKeys++;
58234345a63Smrg        }
583f46a6179Smrg    }
584f46a6179Smrg    return ol;
585f46a6179Smrg}
586f46a6179Smrg
587f46a6179SmrgDoodadDef *
58834345a63SmrgDoodadCreate(unsigned type, Atom name, VarDef * body)
589f46a6179Smrg{
59034345a63Smrg    DoodadDef *doodad;
591f46a6179Smrg
59234345a63Smrg    doodad = uTypedAlloc(DoodadDef);
59334345a63Smrg    if (doodad != NULL)
59434345a63Smrg    {
59534345a63Smrg        bzero(doodad, sizeof(DoodadDef));
59634345a63Smrg        doodad->common.stmtType = StmtDoodadDef;
59734345a63Smrg        doodad->common.next = NULL;
59834345a63Smrg        doodad->type = type;
59934345a63Smrg        doodad->name = name;
60034345a63Smrg        doodad->body = body;
601f46a6179Smrg    }
602f46a6179Smrg    return doodad;
603f46a6179Smrg}
604f46a6179Smrg
605f46a6179SmrgExprDef *
60683e5f723SmrgAppendKeysymList(ExprDef * list, char *sym)
60734345a63Smrg{
60834345a63Smrg    if (list->value.list.nSyms >= list->value.list.szSyms)
60934345a63Smrg    {
61034345a63Smrg        list->value.list.szSyms *= 2;
61134345a63Smrg        list->value.list.syms = uTypedRecalloc(list->value.list.syms,
61234345a63Smrg                                               list->value.list.nSyms,
61334345a63Smrg                                               list->value.list.szSyms,
61483e5f723Smrg                                               char *);
61534345a63Smrg        if (list->value.list.syms == NULL)
61634345a63Smrg        {
61734345a63Smrg            FATAL("Couldn't resize list of symbols for append\n");
61834345a63Smrg            return NULL;
61934345a63Smrg        }
62034345a63Smrg    }
62134345a63Smrg    list->value.list.syms[list->value.list.nSyms++] = sym;
622f46a6179Smrg    return list;
623f46a6179Smrg}
624f46a6179Smrg
625f46a6179Smrgint
626690143ccSmrgLookupKeysym(const char *str, KeySym * sym_rtrn)
627f46a6179Smrg{
62834345a63Smrg    KeySym sym;
62983e5f723Smrg    char *tmp;
630f46a6179Smrg
63134345a63Smrg    if ((!str) || (uStrCaseCmp(str, "any") == 0)
63234345a63Smrg        || (uStrCaseCmp(str, "nosymbol") == 0))
63334345a63Smrg    {
63434345a63Smrg        *sym_rtrn = NoSymbol;
63534345a63Smrg        return 1;
636f46a6179Smrg    }
63734345a63Smrg    else if ((uStrCaseCmp(str, "none") == 0)
63834345a63Smrg             || (uStrCaseCmp(str, "voidsymbol") == 0))
63934345a63Smrg    {
64034345a63Smrg        *sym_rtrn = XK_VoidSymbol;
64134345a63Smrg        return 1;
642f46a6179Smrg    }
64334345a63Smrg    sym = XStringToKeysym(str);
64434345a63Smrg    if (sym != NoSymbol)
64534345a63Smrg    {
64634345a63Smrg        *sym_rtrn = sym;
64734345a63Smrg        return 1;
648f46a6179Smrg    }
64983e5f723Smrg    if (strlen(str) > 2 && str[0] == '0' && str[1] == 'x') {
65083e5f723Smrg        sym = strtoul(str, &tmp, 16);
65183e5f723Smrg        if (sym != ULONG_MAX && (!tmp || *tmp == '\0')) {
65283e5f723Smrg            *sym_rtrn = sym;
65383e5f723Smrg            return 1;
65483e5f723Smrg        }
65583e5f723Smrg    }
656f46a6179Smrg    return 0;
657f46a6179Smrg}
658f46a6179Smrg
659f46a6179SmrgIncludeStmt *
66034345a63SmrgIncludeCreate(char *str, unsigned merge)
66134345a63Smrg{
66234345a63Smrg    IncludeStmt *incl, *first;
66334345a63Smrg    char *file, *map, *stmt, *tmp, *extra_data;
66434345a63Smrg    char nextop;
66534345a63Smrg    Bool haveSelf;
66634345a63Smrg
66734345a63Smrg    haveSelf = False;
66834345a63Smrg    incl = first = NULL;
66934345a63Smrg    file = map = NULL;
67034345a63Smrg    tmp = str;
67134345a63Smrg    stmt = uStringDup(str);
67234345a63Smrg    while ((tmp) && (*tmp))
67334345a63Smrg    {
67434345a63Smrg        if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
67534345a63Smrg        {
67634345a63Smrg            if ((file == NULL) && (map == NULL))
67734345a63Smrg            {
67834345a63Smrg                if (haveSelf)
67934345a63Smrg                    goto BAIL;
68034345a63Smrg                haveSelf = True;
68134345a63Smrg            }
68234345a63Smrg            if (first == NULL)
68334345a63Smrg                first = incl = uTypedAlloc(IncludeStmt);
68434345a63Smrg            else
68534345a63Smrg            {
68634345a63Smrg                incl->next = uTypedAlloc(IncludeStmt);
68734345a63Smrg                incl = incl->next;
68834345a63Smrg            }
68934345a63Smrg            if (incl)
69034345a63Smrg            {
69134345a63Smrg                incl->common.stmtType = StmtInclude;
69234345a63Smrg                incl->common.next = NULL;
69334345a63Smrg                incl->merge = merge;
69434345a63Smrg                incl->stmt = NULL;
69534345a63Smrg                incl->file = file;
69634345a63Smrg                incl->map = map;
69734345a63Smrg                incl->modifier = extra_data;
69834345a63Smrg                incl->path = NULL;
69934345a63Smrg                incl->next = NULL;
70034345a63Smrg            }
70134345a63Smrg            else
70234345a63Smrg            {
70334345a63Smrg                WSGO("Allocation failure in IncludeCreate\n");
70434345a63Smrg                ACTION("Using only part of the include\n");
70534345a63Smrg                break;
70634345a63Smrg            }
70734345a63Smrg            if (nextop == '|')
70834345a63Smrg                merge = MergeAugment;
70934345a63Smrg            else
71034345a63Smrg                merge = MergeOverride;
71134345a63Smrg        }
71234345a63Smrg        else
71334345a63Smrg        {
71434345a63Smrg            goto BAIL;
71534345a63Smrg        }
71634345a63Smrg    }
71734345a63Smrg    if (first)
71834345a63Smrg        first->stmt = stmt;
71934345a63Smrg    else if (stmt)
72034345a63Smrg        uFree(stmt);
721f46a6179Smrg    return first;
72234345a63Smrg  BAIL:
72334345a63Smrg    ERROR1("Illegal include statement \"%s\"\n", stmt);
724f46a6179Smrg    ACTION("Ignored\n");
72534345a63Smrg    while (first)
72634345a63Smrg    {
72734345a63Smrg        incl = first->next;
72834345a63Smrg        if (first->file)
72934345a63Smrg            uFree(first->file);
73034345a63Smrg        if (first->map)
73134345a63Smrg            uFree(first->map);
73234345a63Smrg        if (first->modifier)
73334345a63Smrg            uFree(first->modifier);
73434345a63Smrg        if (first->path)
73534345a63Smrg            uFree(first->path);
73634345a63Smrg        first->file = first->map = first->path = NULL;
73734345a63Smrg        uFree(first);
73834345a63Smrg        first = incl;
739f46a6179Smrg    }
740f46a6179Smrg    if (stmt)
74134345a63Smrg        uFree(stmt);
742f46a6179Smrg    return NULL;
743f46a6179Smrg}
744f46a6179Smrg
745f46a6179Smrg#ifdef DEBUG
746f46a6179Smrgvoid
74734345a63SmrgPrintStmtAddrs(ParseCommon * stmt)
748f46a6179Smrg{
7491d8c7986Smrg    fprintf(stderr, "%p", stmt);
75034345a63Smrg    if (stmt)
75134345a63Smrg    {
75234345a63Smrg        do
75334345a63Smrg        {
7541d8c7986Smrg            fprintf(stderr, "->%p", stmt->next);
75534345a63Smrg            stmt = stmt->next;
75634345a63Smrg        }
75734345a63Smrg        while (stmt);
758f46a6179Smrg    }
75934345a63Smrg    fprintf(stderr, "\n");
760f46a6179Smrg}
761f46a6179Smrg#endif
762f46a6179Smrg
763f46a6179Smrgstatic void
76434345a63SmrgCheckDefaultMap(XkbFile * maps)
76534345a63Smrg{
76634345a63Smrg    XkbFile *dflt, *tmp;
76734345a63Smrg
76834345a63Smrg    dflt = NULL;
76934345a63Smrg    for (tmp = maps, dflt = NULL; tmp != NULL;
77034345a63Smrg         tmp = (XkbFile *) tmp->common.next)
77134345a63Smrg    {
77234345a63Smrg        if (tmp->flags & XkbLC_Default)
77334345a63Smrg        {
77434345a63Smrg            if (dflt == NULL)
77534345a63Smrg                dflt = tmp;
77634345a63Smrg            else
77734345a63Smrg            {
77834345a63Smrg                if (warningLevel > 2)
77934345a63Smrg                {
78034345a63Smrg                    WARN1("Multiple default components in %s\n",
78134345a63Smrg                          (scanFile ? scanFile : "(unknown)"));
78234345a63Smrg                    ACTION2("Using %s, ignoring %s\n",
78334345a63Smrg                            (dflt->name ? dflt->name : "(first)"),
78434345a63Smrg                            (tmp->name ? tmp->name : "(subsequent)"));
78534345a63Smrg                }
78634345a63Smrg                tmp->flags &= (~XkbLC_Default);
78734345a63Smrg            }
78834345a63Smrg        }
789f46a6179Smrg    }
790f46a6179Smrg    return;
791f46a6179Smrg}
792f46a6179Smrg
793f46a6179Smrgint
79434345a63SmrgXKBParseFile(FILE * file, XkbFile ** pRtrn)
79534345a63Smrg{
79634345a63Smrg    if (file)
79734345a63Smrg    {
798c82dfdfbSmrg        scan_set_file(file);
79934345a63Smrg        rtrnValue = NULL;
80034345a63Smrg        if (yyparse() == 0)
80134345a63Smrg        {
80234345a63Smrg            *pRtrn = rtrnValue;
80334345a63Smrg            CheckDefaultMap(rtrnValue);
80434345a63Smrg            rtrnValue = NULL;
80534345a63Smrg            return 1;
80634345a63Smrg        }
80734345a63Smrg        *pRtrn = NULL;
80834345a63Smrg        return 0;
80934345a63Smrg    }
81034345a63Smrg    *pRtrn = NULL;
811f46a6179Smrg    return 1;
812f46a6179Smrg}
813f46a6179Smrg
814f46a6179SmrgXkbFile *
81534345a63SmrgCreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
81634345a63Smrg{
81734345a63Smrg    XkbFile *file;
81834345a63Smrg    static int fileID;
81934345a63Smrg
82034345a63Smrg    file = uTypedAlloc(XkbFile);
82134345a63Smrg    if (file)
82234345a63Smrg    {
82334345a63Smrg        XkbEnsureSafeMapName(name);
82434345a63Smrg        bzero(file, sizeof(XkbFile));
82534345a63Smrg        file->type = type;
82634345a63Smrg        file->topName = uStringDup(name);
82734345a63Smrg        file->name = name;
82834345a63Smrg        file->defs = defs;
82934345a63Smrg        file->id = fileID++;
83034345a63Smrg        file->compiled = False;
83134345a63Smrg        file->flags = flags;
832f46a6179Smrg    }
833f46a6179Smrg    return file;
834f46a6179Smrg}
835f46a6179Smrg
83634345a63Smrgunsigned
83734345a63SmrgStmtSetMerge(ParseCommon * stmt, unsigned merge)
838f46a6179Smrg{
83934345a63Smrg    if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
84034345a63Smrg    {
84134345a63Smrg        yyerror("illegal use of 'alternate' merge mode");
84234345a63Smrg        merge = MergeDefault;
843f46a6179Smrg    }
844f46a6179Smrg    return merge;
845f46a6179Smrg}
846