parseutils.c revision bfe6082c
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
9bfe6082cSmrg documentation, and that the name of Silicon Graphics not be
10bfe6082cSmrg used in advertising or publicity pertaining to distribution
11f46a6179Smrg of the software without specific prior written permission.
12bfe6082cSmrg 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.
15bfe6082cSmrg
16bfe6082cSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17bfe6082cSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19bfe6082cSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20bfe6082cSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21bfe6082cSmrg 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>
3283e5f723Smrg#include <limits.h>
3383e5f723Smrg#include <stdlib.h>
34f46a6179Smrg
3534345a63SmrgXkbFile *rtrnValue;
36f46a6179Smrg
37f46a6179SmrgParseCommon *
3834345a63SmrgAppendStmt(ParseCommon * to, ParseCommon * append)
39f46a6179Smrg{
4034345a63Smrg    ParseCommon *start = to;
41f46a6179Smrg
4234345a63Smrg    if (append == NULL)
4334345a63Smrg        return to;
4434345a63Smrg    while ((to != NULL) && (to->next != NULL))
4534345a63Smrg    {
4634345a63Smrg        to = to->next;
47f46a6179Smrg    }
4834345a63Smrg    if (to)
4934345a63Smrg    {
5034345a63Smrg        to->next = append;
5134345a63Smrg        return start;
52f46a6179Smrg    }
53f46a6179Smrg    return append;
54f46a6179Smrg}
55f46a6179Smrg
56f46a6179SmrgExprDef *
5734345a63SmrgExprCreate(unsigned op, unsigned type)
5834345a63Smrg{
5934345a63Smrg    ExprDef *expr;
6034345a63Smrg    expr = uTypedAlloc(ExprDef);
6134345a63Smrg    if (expr)
6234345a63Smrg    {
6334345a63Smrg        expr->common.stmtType = StmtExpr;
6434345a63Smrg        expr->common.next = NULL;
6534345a63Smrg        expr->op = op;
6634345a63Smrg        expr->type = type;
6734345a63Smrg    }
6834345a63Smrg    else
6934345a63Smrg    {
7034345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
7134345a63Smrg        /* NOTREACHED */
72f46a6179Smrg    }
73f46a6179Smrg    return expr;
74f46a6179Smrg}
75f46a6179Smrg
76f46a6179SmrgExprDef *
7734345a63SmrgExprCreateUnary(unsigned op, unsigned type, ExprDef * child)
7834345a63Smrg{
7934345a63Smrg    ExprDef *expr;
8034345a63Smrg    expr = uTypedAlloc(ExprDef);
8134345a63Smrg    if (expr)
8234345a63Smrg    {
8334345a63Smrg        expr->common.stmtType = StmtExpr;
8434345a63Smrg        expr->common.next = NULL;
8534345a63Smrg        expr->op = op;
8634345a63Smrg        expr->type = type;
8734345a63Smrg        expr->value.child = child;
8834345a63Smrg    }
8934345a63Smrg    else
9034345a63Smrg    {
9134345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
9234345a63Smrg        /* NOTREACHED */
93f46a6179Smrg    }
94f46a6179Smrg    return expr;
95f46a6179Smrg}
96f46a6179Smrg
97f46a6179SmrgExprDef *
9834345a63SmrgExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
9934345a63Smrg{
10034345a63Smrg    ExprDef *expr;
10134345a63Smrg    expr = uTypedAlloc(ExprDef);
10234345a63Smrg    if (expr)
10334345a63Smrg    {
10434345a63Smrg        expr->common.stmtType = StmtExpr;
10534345a63Smrg        expr->common.next = NULL;
10634345a63Smrg        expr->op = op;
10734345a63Smrg        if ((op == OpAssign) || (left->type == TypeUnknown))
10834345a63Smrg            expr->type = right->type;
10934345a63Smrg        else if ((left->type == right->type) || (right->type == TypeUnknown))
11034345a63Smrg            expr->type = left->type;
11134345a63Smrg        else
11234345a63Smrg            expr->type = TypeUnknown;
11334345a63Smrg        expr->value.binary.left = left;
11434345a63Smrg        expr->value.binary.right = right;
11534345a63Smrg    }
11634345a63Smrg    else
11734345a63Smrg    {
11834345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
11934345a63Smrg        /* NOTREACHED */
120f46a6179Smrg    }
121f46a6179Smrg    return expr;
122f46a6179Smrg}
123f46a6179Smrg
124f46a6179SmrgKeycodeDef *
12534345a63SmrgKeycodeCreate(char *name, ExprDef * value)
126f46a6179Smrg{
12734345a63Smrg    KeycodeDef *def;
128f46a6179Smrg
12934345a63Smrg    def = uTypedAlloc(KeycodeDef);
13034345a63Smrg    if (def)
13134345a63Smrg    {
13234345a63Smrg        def->common.stmtType = StmtKeycodeDef;
13334345a63Smrg        def->common.next = NULL;
13434345a63Smrg        strncpy(def->name, name, XkbKeyNameLength);
13534345a63Smrg        def->name[XkbKeyNameLength] = '\0';
13634345a63Smrg        def->value = value;
137f46a6179Smrg    }
13834345a63Smrg    else
13934345a63Smrg    {
14034345a63Smrg        FATAL("Couldn't allocate key name definition in parser\n");
14134345a63Smrg        /* NOTREACHED */
142f46a6179Smrg    }
143f46a6179Smrg    return def;
144f46a6179Smrg}
145f46a6179Smrg
146f46a6179SmrgKeyAliasDef *
14734345a63SmrgKeyAliasCreate(char *alias, char *real)
148f46a6179Smrg{
14934345a63Smrg    KeyAliasDef *def;
150f46a6179Smrg
15134345a63Smrg    def = uTypedAlloc(KeyAliasDef);
15234345a63Smrg    if (def)
15334345a63Smrg    {
15434345a63Smrg        def->common.stmtType = StmtKeyAliasDef;
15534345a63Smrg        def->common.next = NULL;
15634345a63Smrg        strncpy(def->alias, alias, XkbKeyNameLength);
15734345a63Smrg        def->alias[XkbKeyNameLength] = '\0';
15834345a63Smrg        strncpy(def->real, real, XkbKeyNameLength);
15934345a63Smrg        def->real[XkbKeyNameLength] = '\0';
160f46a6179Smrg    }
16134345a63Smrg    else
16234345a63Smrg    {
16334345a63Smrg        FATAL("Couldn't allocate key alias definition in parser\n");
16434345a63Smrg        /* NOTREACHED */
165f46a6179Smrg    }
166f46a6179Smrg    return def;
167f46a6179Smrg}
168f46a6179Smrg
169f46a6179SmrgVModDef *
17034345a63SmrgVModCreate(Atom name, ExprDef * value)
17134345a63Smrg{
17234345a63Smrg    VModDef *def;
17334345a63Smrg    def = uTypedAlloc(VModDef);
17434345a63Smrg    if (def)
17534345a63Smrg    {
17634345a63Smrg        def->common.stmtType = StmtVModDef;
17734345a63Smrg        def->common.next = NULL;
17834345a63Smrg        def->name = name;
17934345a63Smrg        def->value = value;
18034345a63Smrg    }
18134345a63Smrg    else
18234345a63Smrg    {
18334345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
18434345a63Smrg        /* NOTREACHED */
185f46a6179Smrg    }
186f46a6179Smrg    return def;
187f46a6179Smrg}
188f46a6179Smrg
189f46a6179SmrgVarDef *
19034345a63SmrgVarCreate(ExprDef * name, ExprDef * value)
19134345a63Smrg{
19234345a63Smrg    VarDef *def;
19334345a63Smrg    def = uTypedAlloc(VarDef);
19434345a63Smrg    if (def)
19534345a63Smrg    {
19634345a63Smrg        def->common.stmtType = StmtVarDef;
19734345a63Smrg        def->common.next = NULL;
19834345a63Smrg        def->name = name;
19934345a63Smrg        def->value = value;
20034345a63Smrg    }
20134345a63Smrg    else
20234345a63Smrg    {
20334345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
20434345a63Smrg        /* NOTREACHED */
205f46a6179Smrg    }
206f46a6179Smrg    return def;
207f46a6179Smrg}
208f46a6179Smrg
209f46a6179SmrgVarDef *
21034345a63SmrgBoolVarCreate(Atom nameToken, unsigned set)
211f46a6179Smrg{
21234345a63Smrg    ExprDef *name, *value;
213f46a6179Smrg
21434345a63Smrg    name = ExprCreate(ExprIdent, TypeUnknown);
21534345a63Smrg    name->value.str = nameToken;
21634345a63Smrg    value = ExprCreate(ExprValue, TypeBoolean);
21734345a63Smrg    value->value.uval = set;
21834345a63Smrg    return VarCreate(name, value);
219f46a6179Smrg}
220f46a6179Smrg
221f46a6179SmrgInterpDef *
222690143ccSmrgInterpCreate(const char *sym_str, ExprDef * match)
223f46a6179Smrg{
22434345a63Smrg    InterpDef *def;
225f46a6179Smrg
22634345a63Smrg    def = uTypedAlloc(InterpDef);
22734345a63Smrg    if (def)
22834345a63Smrg    {
22934345a63Smrg        def->common.stmtType = StmtInterpDef;
23034345a63Smrg        def->common.next = NULL;
231690143ccSmrg        if (LookupKeysym(sym_str, &def->sym) == 0)
232690143ccSmrg            def->ignore = True;
233690143ccSmrg        else
234690143ccSmrg            def->ignore = False;
23534345a63Smrg        def->match = match;
236f46a6179Smrg    }
23734345a63Smrg    else
23834345a63Smrg    {
23934345a63Smrg        FATAL("Couldn't allocate interp definition in parser\n");
24034345a63Smrg        /* NOTREACHED */
241f46a6179Smrg    }
242f46a6179Smrg    return def;
243f46a6179Smrg}
244f46a6179Smrg
245f46a6179SmrgKeyTypeDef *
24634345a63SmrgKeyTypeCreate(Atom name, VarDef * body)
247f46a6179Smrg{
24834345a63Smrg    KeyTypeDef *def;
249f46a6179Smrg
25034345a63Smrg    def = uTypedAlloc(KeyTypeDef);
25134345a63Smrg    if (def)
25234345a63Smrg    {
25334345a63Smrg        def->common.stmtType = StmtKeyTypeDef;
25434345a63Smrg        def->common.next = NULL;
25534345a63Smrg        def->merge = MergeDefault;
25634345a63Smrg        def->name = name;
25734345a63Smrg        def->body = body;
258f46a6179Smrg    }
25934345a63Smrg    else
26034345a63Smrg    {
26134345a63Smrg        FATAL("Couldn't allocate key type definition in parser\n");
26234345a63Smrg        /* NOTREACHED */
263f46a6179Smrg    }
264f46a6179Smrg    return def;
265f46a6179Smrg}
266f46a6179Smrg
267f46a6179SmrgSymbolsDef *
26834345a63SmrgSymbolsCreate(char *keyName, ExprDef * symbols)
269f46a6179Smrg{
27034345a63Smrg    SymbolsDef *def;
271f46a6179Smrg
27234345a63Smrg    def = uTypedAlloc(SymbolsDef);
27334345a63Smrg    if (def)
27434345a63Smrg    {
27534345a63Smrg        def->common.stmtType = StmtSymbolsDef;
27634345a63Smrg        def->common.next = NULL;
27734345a63Smrg        def->merge = MergeDefault;
27834345a63Smrg        bzero(def->keyName, 5);
27934345a63Smrg        strncpy(def->keyName, keyName, 4);
28034345a63Smrg        def->symbols = symbols;
281f46a6179Smrg    }
28234345a63Smrg    else
28334345a63Smrg    {
28434345a63Smrg        FATAL("Couldn't allocate symbols definition in parser\n");
28534345a63Smrg        /* NOTREACHED */
286f46a6179Smrg    }
287f46a6179Smrg    return def;
288f46a6179Smrg}
289f46a6179Smrg
290f46a6179SmrgGroupCompatDef *
29134345a63SmrgGroupCompatCreate(int group, ExprDef * val)
292f46a6179Smrg{
29334345a63Smrg    GroupCompatDef *def;
294f46a6179Smrg
29534345a63Smrg    def = uTypedAlloc(GroupCompatDef);
29634345a63Smrg    if (def)
29734345a63Smrg    {
29834345a63Smrg        def->common.stmtType = StmtGroupCompatDef;
29934345a63Smrg        def->common.next = NULL;
30034345a63Smrg        def->merge = MergeDefault;
30134345a63Smrg        def->group = group;
30234345a63Smrg        def->def = val;
303f46a6179Smrg    }
30434345a63Smrg    else
30534345a63Smrg    {
30634345a63Smrg        FATAL("Couldn't allocate group compat definition in parser\n");
30734345a63Smrg        /* NOTREACHED */
308f46a6179Smrg    }
309f46a6179Smrg    return def;
310f46a6179Smrg}
311f46a6179Smrg
312f46a6179SmrgModMapDef *
31334345a63SmrgModMapCreate(Atom modifier, ExprDef * keys)
314f46a6179Smrg{
31534345a63Smrg    ModMapDef *def;
316f46a6179Smrg
31734345a63Smrg    def = uTypedAlloc(ModMapDef);
31834345a63Smrg    if (def)
31934345a63Smrg    {
32034345a63Smrg        def->common.stmtType = StmtModMapDef;
32134345a63Smrg        def->common.next = NULL;
32234345a63Smrg        def->merge = MergeDefault;
32334345a63Smrg        def->modifier = modifier;
32434345a63Smrg        def->keys = keys;
325f46a6179Smrg    }
32634345a63Smrg    else
32734345a63Smrg    {
32834345a63Smrg        FATAL("Couldn't allocate mod mask definition in parser\n");
32934345a63Smrg        /* NOTREACHED */
330f46a6179Smrg    }
331f46a6179Smrg    return def;
332f46a6179Smrg}
333f46a6179Smrg
334f46a6179SmrgIndicatorMapDef *
33534345a63SmrgIndicatorMapCreate(Atom name, VarDef * body)
336f46a6179Smrg{
33734345a63Smrg    IndicatorMapDef *def;
338f46a6179Smrg
33934345a63Smrg    def = uTypedAlloc(IndicatorMapDef);
34034345a63Smrg    if (def)
34134345a63Smrg    {
34234345a63Smrg        def->common.stmtType = StmtIndicatorMapDef;
34334345a63Smrg        def->common.next = NULL;
34434345a63Smrg        def->merge = MergeDefault;
34534345a63Smrg        def->name = name;
34634345a63Smrg        def->body = body;
347f46a6179Smrg    }
34834345a63Smrg    else
34934345a63Smrg    {
35034345a63Smrg        FATAL("Couldn't allocate indicator map definition in parser\n");
35134345a63Smrg        /* NOTREACHED */
352f46a6179Smrg    }
353f46a6179Smrg    return def;
354f46a6179Smrg}
355f46a6179Smrg
356f46a6179SmrgIndicatorNameDef *
35734345a63SmrgIndicatorNameCreate(int ndx, ExprDef * name, Bool virtual)
358f46a6179Smrg{
35934345a63Smrg    IndicatorNameDef *def;
360f46a6179Smrg
36134345a63Smrg    def = uTypedAlloc(IndicatorNameDef);
36234345a63Smrg    if (def)
36334345a63Smrg    {
36434345a63Smrg        def->common.stmtType = StmtIndicatorNameDef;
36534345a63Smrg        def->common.next = NULL;
36634345a63Smrg        def->merge = MergeDefault;
36734345a63Smrg        def->ndx = ndx;
36834345a63Smrg        def->name = name;
36934345a63Smrg        def->virtual = virtual;
370f46a6179Smrg    }
37134345a63Smrg    else
37234345a63Smrg    {
37334345a63Smrg        FATAL("Couldn't allocate indicator index definition in parser\n");
37434345a63Smrg        /* NOTREACHED */
375f46a6179Smrg    }
376f46a6179Smrg    return def;
377f46a6179Smrg}
378f46a6179Smrg
379f46a6179SmrgExprDef *
38034345a63SmrgActionCreate(Atom name, ExprDef * args)
381f46a6179Smrg{
38234345a63Smrg    ExprDef *act;
383f46a6179Smrg
38434345a63Smrg    act = uTypedAlloc(ExprDef);
38534345a63Smrg    if (act)
38634345a63Smrg    {
38734345a63Smrg        act->common.stmtType = StmtExpr;
38834345a63Smrg        act->common.next = NULL;
38934345a63Smrg        act->op = ExprActionDecl;
39034345a63Smrg        act->value.action.name = name;
39134345a63Smrg        act->value.action.args = args;
39234345a63Smrg        return act;
393f46a6179Smrg    }
394f46a6179Smrg    FATAL("Couldn't allocate ActionDef in parser\n");
395f46a6179Smrg    return NULL;
396f46a6179Smrg}
397f46a6179Smrg
398f46a6179SmrgExprDef *
39983e5f723SmrgCreateKeysymList(char *sym)
400f46a6179Smrg{
40134345a63Smrg    ExprDef *def;
402f46a6179Smrg
40334345a63Smrg    def = ExprCreate(ExprKeysymList, TypeSymbols);
40434345a63Smrg    if (def)
40534345a63Smrg    {
40634345a63Smrg        def->value.list.nSyms = 1;
40783e5f723Smrg        def->value.list.szSyms = 4;
40883e5f723Smrg        def->value.list.syms = uTypedCalloc(4, char *);
40934345a63Smrg        if (def->value.list.syms != NULL)
41034345a63Smrg        {
41134345a63Smrg            def->value.list.syms[0] = sym;
41234345a63Smrg            return def;
41334345a63Smrg        }
414f46a6179Smrg    }
415f46a6179Smrg    FATAL("Couldn't allocate expression for keysym list in parser\n");
416f46a6179Smrg    return NULL;
417f46a6179Smrg}
418f46a6179Smrg
419f46a6179SmrgShapeDef *
42034345a63SmrgShapeDeclCreate(Atom name, OutlineDef * outlines)
42134345a63Smrg{
42234345a63Smrg    ShapeDef *shape;
42334345a63Smrg    OutlineDef *ol;
42434345a63Smrg
42534345a63Smrg    shape = uTypedAlloc(ShapeDef);
42634345a63Smrg    if (shape != NULL)
42734345a63Smrg    {
42834345a63Smrg        bzero(shape, sizeof(ShapeDef));
42934345a63Smrg        shape->common.stmtType = StmtShapeDef;
43034345a63Smrg        shape->common.next = NULL;
43134345a63Smrg        shape->merge = MergeDefault;
43234345a63Smrg        shape->name = name;
43334345a63Smrg        shape->nOutlines = 0;
43434345a63Smrg        shape->outlines = outlines;
43534345a63Smrg        for (ol = outlines; ol != NULL; ol = (OutlineDef *) ol->common.next)
43634345a63Smrg        {
43734345a63Smrg            if (ol->nPoints > 0)
43834345a63Smrg                shape->nOutlines++;
43934345a63Smrg        }
440f46a6179Smrg    }
441f46a6179Smrg    return shape;
442f46a6179Smrg}
443f46a6179Smrg
444f46a6179SmrgOutlineDef *
44534345a63SmrgOutlineCreate(Atom field, ExprDef * points)
44634345a63Smrg{
44734345a63Smrg    OutlineDef *outline;
44834345a63Smrg    ExprDef *pt;
44934345a63Smrg
45034345a63Smrg    outline = uTypedAlloc(OutlineDef);
45134345a63Smrg    if (outline != NULL)
45234345a63Smrg    {
45334345a63Smrg        bzero(outline, sizeof(OutlineDef));
45434345a63Smrg        outline->common.stmtType = StmtOutlineDef;
45534345a63Smrg        outline->common.next = NULL;
45634345a63Smrg        outline->field = field;
45734345a63Smrg        outline->nPoints = 0;
45834345a63Smrg        if (points->op == ExprCoord)
45934345a63Smrg        {
46034345a63Smrg            for (pt = points; pt != NULL; pt = (ExprDef *) pt->common.next)
46134345a63Smrg            {
46234345a63Smrg                outline->nPoints++;
46334345a63Smrg            }
46434345a63Smrg        }
46534345a63Smrg        outline->points = points;
466f46a6179Smrg    }
467f46a6179Smrg    return outline;
468f46a6179Smrg}
469f46a6179Smrg
470f46a6179SmrgKeyDef *
47134345a63SmrgKeyDeclCreate(char *name, ExprDef * expr)
472f46a6179Smrg{
47334345a63Smrg    KeyDef *key;
474f46a6179Smrg
47534345a63Smrg    key = uTypedAlloc(KeyDef);
47634345a63Smrg    if (key != NULL)
47734345a63Smrg    {
47834345a63Smrg        bzero(key, sizeof(KeyDef));
47934345a63Smrg        key->common.stmtType = StmtKeyDef;
48034345a63Smrg        key->common.next = NULL;
48134345a63Smrg        if (name)
48234345a63Smrg            key->name = name;
48334345a63Smrg        else
48434345a63Smrg            key->expr = expr;
485f46a6179Smrg    }
486f46a6179Smrg    return key;
487f46a6179Smrg}
488f46a6179Smrg
489f46a6179SmrgKeyDef *
49034345a63SmrgKeyDeclMerge(KeyDef * into, KeyDef * from)
491f46a6179Smrg{
49234345a63Smrg    into->expr =
49334345a63Smrg        (ExprDef *) AppendStmt(&into->expr->common, &from->expr->common);
49434345a63Smrg    from->expr = NULL;
495f46a6179Smrg    uFree(from);
496f46a6179Smrg    return into;
497f46a6179Smrg}
498f46a6179Smrg
499f46a6179SmrgRowDef *
50034345a63SmrgRowDeclCreate(KeyDef * keys)
50134345a63Smrg{
50234345a63Smrg    RowDef *row;
50334345a63Smrg    KeyDef *key;
50434345a63Smrg
50534345a63Smrg    row = uTypedAlloc(RowDef);
50634345a63Smrg    if (row != NULL)
50734345a63Smrg    {
50834345a63Smrg        bzero(row, sizeof(RowDef));
50934345a63Smrg        row->common.stmtType = StmtRowDef;
51034345a63Smrg        row->common.next = NULL;
51134345a63Smrg        row->nKeys = 0;
51234345a63Smrg        row->keys = keys;
51334345a63Smrg        for (key = keys; key != NULL; key = (KeyDef *) key->common.next)
51434345a63Smrg        {
51534345a63Smrg            if (key->common.stmtType == StmtKeyDef)
51634345a63Smrg                row->nKeys++;
51734345a63Smrg        }
518f46a6179Smrg    }
519f46a6179Smrg    return row;
520f46a6179Smrg}
521f46a6179Smrg
522f46a6179SmrgSectionDef *
52334345a63SmrgSectionDeclCreate(Atom name, RowDef * rows)
52434345a63Smrg{
52534345a63Smrg    SectionDef *section;
52634345a63Smrg    RowDef *row;
52734345a63Smrg
52834345a63Smrg    section = uTypedAlloc(SectionDef);
52934345a63Smrg    if (section != NULL)
53034345a63Smrg    {
53134345a63Smrg        bzero(section, sizeof(SectionDef));
53234345a63Smrg        section->common.stmtType = StmtSectionDef;
53334345a63Smrg        section->common.next = NULL;
53434345a63Smrg        section->name = name;
53534345a63Smrg        section->nRows = 0;
53634345a63Smrg        section->rows = rows;
53734345a63Smrg        for (row = rows; row != NULL; row = (RowDef *) row->common.next)
53834345a63Smrg        {
53934345a63Smrg            if (row->common.stmtType == StmtRowDef)
54034345a63Smrg                section->nRows++;
54134345a63Smrg        }
542f46a6179Smrg    }
543f46a6179Smrg    return section;
544f46a6179Smrg}
545f46a6179Smrg
546f46a6179SmrgOverlayKeyDef *
54734345a63SmrgOverlayKeyCreate(char *under, char *over)
54834345a63Smrg{
54934345a63Smrg    OverlayKeyDef *key;
55034345a63Smrg
55134345a63Smrg    key = uTypedAlloc(OverlayKeyDef);
55234345a63Smrg    if (key != NULL)
55334345a63Smrg    {
55434345a63Smrg        bzero(key, sizeof(OverlayKeyDef));
55534345a63Smrg        key->common.stmtType = StmtOverlayKeyDef;
55634345a63Smrg        strncpy(key->over, over, XkbKeyNameLength);
55734345a63Smrg        strncpy(key->under, under, XkbKeyNameLength);
558c82dfdfbSmrg        uFree(over);
559c82dfdfbSmrg        uFree(under);
560f46a6179Smrg    }
561f46a6179Smrg    return key;
562f46a6179Smrg}
563f46a6179Smrg
564f46a6179SmrgOverlayDef *
56534345a63SmrgOverlayDeclCreate(Atom name, OverlayKeyDef * keys)
56634345a63Smrg{
56734345a63Smrg    OverlayDef *ol;
56834345a63Smrg    OverlayKeyDef *key;
56934345a63Smrg
57034345a63Smrg    ol = uTypedAlloc(OverlayDef);
57134345a63Smrg    if (ol != NULL)
57234345a63Smrg    {
57334345a63Smrg        bzero(ol, sizeof(OverlayDef));
57434345a63Smrg        ol->common.stmtType = StmtOverlayDef;
57534345a63Smrg        ol->name = name;
57634345a63Smrg        ol->keys = keys;
57734345a63Smrg        for (key = keys; key != NULL;
57834345a63Smrg             key = (OverlayKeyDef *) key->common.next)
57934345a63Smrg        {
58034345a63Smrg            ol->nKeys++;
58134345a63Smrg        }
582f46a6179Smrg    }
583f46a6179Smrg    return ol;
584f46a6179Smrg}
585f46a6179Smrg
586f46a6179SmrgDoodadDef *
58734345a63SmrgDoodadCreate(unsigned type, Atom name, VarDef * body)
588f46a6179Smrg{
58934345a63Smrg    DoodadDef *doodad;
590f46a6179Smrg
59134345a63Smrg    doodad = uTypedAlloc(DoodadDef);
59234345a63Smrg    if (doodad != NULL)
59334345a63Smrg    {
59434345a63Smrg        bzero(doodad, sizeof(DoodadDef));
59534345a63Smrg        doodad->common.stmtType = StmtDoodadDef;
59634345a63Smrg        doodad->common.next = NULL;
59734345a63Smrg        doodad->type = type;
59834345a63Smrg        doodad->name = name;
59934345a63Smrg        doodad->body = body;
600f46a6179Smrg    }
601f46a6179Smrg    return doodad;
602f46a6179Smrg}
603f46a6179Smrg
604f46a6179SmrgExprDef *
60583e5f723SmrgAppendKeysymList(ExprDef * list, char *sym)
60634345a63Smrg{
60734345a63Smrg    if (list->value.list.nSyms >= list->value.list.szSyms)
60834345a63Smrg    {
60934345a63Smrg        list->value.list.szSyms *= 2;
61034345a63Smrg        list->value.list.syms = uTypedRecalloc(list->value.list.syms,
61134345a63Smrg                                               list->value.list.nSyms,
61234345a63Smrg                                               list->value.list.szSyms,
61383e5f723Smrg                                               char *);
61434345a63Smrg        if (list->value.list.syms == NULL)
61534345a63Smrg        {
61634345a63Smrg            FATAL("Couldn't resize list of symbols for append\n");
61734345a63Smrg            return NULL;
61834345a63Smrg        }
61934345a63Smrg    }
62034345a63Smrg    list->value.list.syms[list->value.list.nSyms++] = sym;
621f46a6179Smrg    return list;
622f46a6179Smrg}
623f46a6179Smrg
624f46a6179Smrgint
625690143ccSmrgLookupKeysym(const char *str, KeySym * sym_rtrn)
626f46a6179Smrg{
62734345a63Smrg    KeySym sym;
62883e5f723Smrg    char *tmp;
629f46a6179Smrg
63034345a63Smrg    if ((!str) || (uStrCaseCmp(str, "any") == 0)
63134345a63Smrg        || (uStrCaseCmp(str, "nosymbol") == 0))
63234345a63Smrg    {
63334345a63Smrg        *sym_rtrn = NoSymbol;
63434345a63Smrg        return 1;
635f46a6179Smrg    }
63634345a63Smrg    else if ((uStrCaseCmp(str, "none") == 0)
63734345a63Smrg             || (uStrCaseCmp(str, "voidsymbol") == 0))
63834345a63Smrg    {
63934345a63Smrg        *sym_rtrn = XK_VoidSymbol;
64034345a63Smrg        return 1;
641f46a6179Smrg    }
64234345a63Smrg    sym = XStringToKeysym(str);
64334345a63Smrg    if (sym != NoSymbol)
64434345a63Smrg    {
64534345a63Smrg        *sym_rtrn = sym;
64634345a63Smrg        return 1;
647f46a6179Smrg    }
64883e5f723Smrg    if (strlen(str) > 2 && str[0] == '0' && str[1] == 'x') {
64983e5f723Smrg        sym = strtoul(str, &tmp, 16);
65083e5f723Smrg        if (sym != ULONG_MAX && (!tmp || *tmp == '\0')) {
65183e5f723Smrg            *sym_rtrn = sym;
65283e5f723Smrg            return 1;
65383e5f723Smrg        }
65483e5f723Smrg    }
655f46a6179Smrg    return 0;
656f46a6179Smrg}
657f46a6179Smrg
658f46a6179SmrgIncludeStmt *
65934345a63SmrgIncludeCreate(char *str, unsigned merge)
66034345a63Smrg{
66134345a63Smrg    IncludeStmt *incl, *first;
66234345a63Smrg    char *file, *map, *stmt, *tmp, *extra_data;
66334345a63Smrg    char nextop;
66434345a63Smrg    Bool haveSelf;
66534345a63Smrg
66634345a63Smrg    haveSelf = False;
66734345a63Smrg    incl = first = NULL;
66834345a63Smrg    file = map = NULL;
66934345a63Smrg    tmp = str;
67034345a63Smrg    stmt = uStringDup(str);
67134345a63Smrg    while ((tmp) && (*tmp))
67234345a63Smrg    {
67334345a63Smrg        if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
67434345a63Smrg        {
67534345a63Smrg            if ((file == NULL) && (map == NULL))
67634345a63Smrg            {
67734345a63Smrg                if (haveSelf)
67834345a63Smrg                    goto BAIL;
67934345a63Smrg                haveSelf = True;
68034345a63Smrg            }
68134345a63Smrg            if (first == NULL)
68234345a63Smrg                first = incl = uTypedAlloc(IncludeStmt);
68334345a63Smrg            else
68434345a63Smrg            {
68534345a63Smrg                incl->next = uTypedAlloc(IncludeStmt);
68634345a63Smrg                incl = incl->next;
68734345a63Smrg            }
68834345a63Smrg            if (incl)
68934345a63Smrg            {
69034345a63Smrg                incl->common.stmtType = StmtInclude;
69134345a63Smrg                incl->common.next = NULL;
69234345a63Smrg                incl->merge = merge;
69334345a63Smrg                incl->stmt = NULL;
69434345a63Smrg                incl->file = file;
69534345a63Smrg                incl->map = map;
69634345a63Smrg                incl->modifier = extra_data;
69734345a63Smrg                incl->path = NULL;
69834345a63Smrg                incl->next = NULL;
69934345a63Smrg            }
70034345a63Smrg            else
70134345a63Smrg            {
70234345a63Smrg                WSGO("Allocation failure in IncludeCreate\n");
70334345a63Smrg                ACTION("Using only part of the include\n");
70434345a63Smrg                break;
70534345a63Smrg            }
70634345a63Smrg            if (nextop == '|')
70734345a63Smrg                merge = MergeAugment;
70834345a63Smrg            else
70934345a63Smrg                merge = MergeOverride;
71034345a63Smrg        }
71134345a63Smrg        else
71234345a63Smrg        {
71334345a63Smrg            goto BAIL;
71434345a63Smrg        }
71534345a63Smrg    }
71634345a63Smrg    if (first)
71734345a63Smrg        first->stmt = stmt;
71834345a63Smrg    else if (stmt)
71934345a63Smrg        uFree(stmt);
720f46a6179Smrg    return first;
72134345a63Smrg  BAIL:
722bfe6082cSmrg    ERROR("Illegal include statement \"%s\"\n", stmt);
723f46a6179Smrg    ACTION("Ignored\n");
72434345a63Smrg    while (first)
72534345a63Smrg    {
72634345a63Smrg        incl = first->next;
72734345a63Smrg        if (first->file)
72834345a63Smrg            uFree(first->file);
72934345a63Smrg        if (first->map)
73034345a63Smrg            uFree(first->map);
73134345a63Smrg        if (first->modifier)
73234345a63Smrg            uFree(first->modifier);
73334345a63Smrg        if (first->path)
73434345a63Smrg            uFree(first->path);
73534345a63Smrg        first->file = first->map = first->path = NULL;
73634345a63Smrg        uFree(first);
73734345a63Smrg        first = incl;
738f46a6179Smrg    }
739f46a6179Smrg    if (stmt)
74034345a63Smrg        uFree(stmt);
741f46a6179Smrg    return NULL;
742f46a6179Smrg}
743f46a6179Smrg
744f46a6179Smrg#ifdef DEBUG
745f46a6179Smrgvoid
74634345a63SmrgPrintStmtAddrs(ParseCommon * stmt)
747f46a6179Smrg{
7481d8c7986Smrg    fprintf(stderr, "%p", stmt);
74934345a63Smrg    if (stmt)
75034345a63Smrg    {
75134345a63Smrg        do
75234345a63Smrg        {
7531d8c7986Smrg            fprintf(stderr, "->%p", stmt->next);
75434345a63Smrg            stmt = stmt->next;
75534345a63Smrg        }
75634345a63Smrg        while (stmt);
757f46a6179Smrg    }
75834345a63Smrg    fprintf(stderr, "\n");
759f46a6179Smrg}
760f46a6179Smrg#endif
761f46a6179Smrg
762f46a6179Smrgstatic void
76334345a63SmrgCheckDefaultMap(XkbFile * maps)
76434345a63Smrg{
76534345a63Smrg    XkbFile *dflt, *tmp;
76634345a63Smrg
76734345a63Smrg    dflt = NULL;
76834345a63Smrg    for (tmp = maps, dflt = NULL; tmp != NULL;
76934345a63Smrg         tmp = (XkbFile *) tmp->common.next)
77034345a63Smrg    {
77134345a63Smrg        if (tmp->flags & XkbLC_Default)
77234345a63Smrg        {
77334345a63Smrg            if (dflt == NULL)
77434345a63Smrg                dflt = tmp;
77534345a63Smrg            else
77634345a63Smrg            {
77734345a63Smrg                if (warningLevel > 2)
77834345a63Smrg                {
779bfe6082cSmrg                    WARN("Multiple default components in %s\n",
78034345a63Smrg                          (scanFile ? scanFile : "(unknown)"));
781bfe6082cSmrg                    ACTION("Using %s, ignoring %s\n",
78234345a63Smrg                            (dflt->name ? dflt->name : "(first)"),
78334345a63Smrg                            (tmp->name ? tmp->name : "(subsequent)"));
78434345a63Smrg                }
78534345a63Smrg                tmp->flags &= (~XkbLC_Default);
78634345a63Smrg            }
78734345a63Smrg        }
788f46a6179Smrg    }
789f46a6179Smrg    return;
790f46a6179Smrg}
791f46a6179Smrg
792f46a6179Smrgint
79334345a63SmrgXKBParseFile(FILE * file, XkbFile ** pRtrn)
79434345a63Smrg{
79534345a63Smrg    if (file)
79634345a63Smrg    {
797c82dfdfbSmrg        scan_set_file(file);
79834345a63Smrg        rtrnValue = NULL;
79934345a63Smrg        if (yyparse() == 0)
80034345a63Smrg        {
80134345a63Smrg            *pRtrn = rtrnValue;
80234345a63Smrg            CheckDefaultMap(rtrnValue);
80334345a63Smrg            rtrnValue = NULL;
80434345a63Smrg            return 1;
80534345a63Smrg        }
80634345a63Smrg        *pRtrn = NULL;
80734345a63Smrg        return 0;
80834345a63Smrg    }
80934345a63Smrg    *pRtrn = NULL;
810f46a6179Smrg    return 1;
811f46a6179Smrg}
812f46a6179Smrg
813f46a6179SmrgXkbFile *
81434345a63SmrgCreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
81534345a63Smrg{
81634345a63Smrg    XkbFile *file;
81734345a63Smrg    static int fileID;
81834345a63Smrg
81934345a63Smrg    file = uTypedAlloc(XkbFile);
82034345a63Smrg    if (file)
82134345a63Smrg    {
82234345a63Smrg        XkbEnsureSafeMapName(name);
82334345a63Smrg        bzero(file, sizeof(XkbFile));
82434345a63Smrg        file->type = type;
82534345a63Smrg        file->topName = uStringDup(name);
82634345a63Smrg        file->name = name;
82734345a63Smrg        file->defs = defs;
82834345a63Smrg        file->id = fileID++;
82934345a63Smrg        file->compiled = False;
83034345a63Smrg        file->flags = flags;
831f46a6179Smrg    }
832f46a6179Smrg    return file;
833f46a6179Smrg}
834f46a6179Smrg
83534345a63Smrgunsigned
83634345a63SmrgStmtSetMerge(ParseCommon * stmt, unsigned merge)
837f46a6179Smrg{
83834345a63Smrg    if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
83934345a63Smrg    {
84034345a63Smrg        yyerror("illegal use of 'alternate' merge mode");
84134345a63Smrg        merge = MergeDefault;
842f46a6179Smrg    }
843f46a6179Smrg    return merge;
844f46a6179Smrg}
845