parseutils.c revision 34345a63
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>
33f46a6179Smrg
3434345a63SmrgXkbFile *rtrnValue;
35f46a6179Smrg
36f46a6179SmrgParseCommon *
3734345a63SmrgAppendStmt(ParseCommon * to, ParseCommon * append)
38f46a6179Smrg{
3934345a63Smrg    ParseCommon *start = to;
40f46a6179Smrg
4134345a63Smrg    if (append == NULL)
4234345a63Smrg        return to;
4334345a63Smrg    while ((to != NULL) && (to->next != NULL))
4434345a63Smrg    {
4534345a63Smrg        to = to->next;
46f46a6179Smrg    }
4734345a63Smrg    if (to)
4834345a63Smrg    {
4934345a63Smrg        to->next = append;
5034345a63Smrg        return start;
51f46a6179Smrg    }
52f46a6179Smrg    return append;
53f46a6179Smrg}
54f46a6179Smrg
55f46a6179SmrgExprDef *
5634345a63SmrgExprCreate(unsigned op, unsigned type)
5734345a63Smrg{
5834345a63Smrg    ExprDef *expr;
5934345a63Smrg    expr = uTypedAlloc(ExprDef);
6034345a63Smrg    if (expr)
6134345a63Smrg    {
6234345a63Smrg        expr->common.stmtType = StmtExpr;
6334345a63Smrg        expr->common.next = NULL;
6434345a63Smrg        expr->op = op;
6534345a63Smrg        expr->type = type;
6634345a63Smrg    }
6734345a63Smrg    else
6834345a63Smrg    {
6934345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
7034345a63Smrg        /* NOTREACHED */
71f46a6179Smrg    }
72f46a6179Smrg    return expr;
73f46a6179Smrg}
74f46a6179Smrg
75f46a6179SmrgExprDef *
7634345a63SmrgExprCreateUnary(unsigned op, unsigned type, ExprDef * child)
7734345a63Smrg{
7834345a63Smrg    ExprDef *expr;
7934345a63Smrg    expr = uTypedAlloc(ExprDef);
8034345a63Smrg    if (expr)
8134345a63Smrg    {
8234345a63Smrg        expr->common.stmtType = StmtExpr;
8334345a63Smrg        expr->common.next = NULL;
8434345a63Smrg        expr->op = op;
8534345a63Smrg        expr->type = type;
8634345a63Smrg        expr->value.child = child;
8734345a63Smrg    }
8834345a63Smrg    else
8934345a63Smrg    {
9034345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
9134345a63Smrg        /* NOTREACHED */
92f46a6179Smrg    }
93f46a6179Smrg    return expr;
94f46a6179Smrg}
95f46a6179Smrg
96f46a6179SmrgExprDef *
9734345a63SmrgExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
9834345a63Smrg{
9934345a63Smrg    ExprDef *expr;
10034345a63Smrg    expr = uTypedAlloc(ExprDef);
10134345a63Smrg    if (expr)
10234345a63Smrg    {
10334345a63Smrg        expr->common.stmtType = StmtExpr;
10434345a63Smrg        expr->common.next = NULL;
10534345a63Smrg        expr->op = op;
10634345a63Smrg        if ((op == OpAssign) || (left->type == TypeUnknown))
10734345a63Smrg            expr->type = right->type;
10834345a63Smrg        else if ((left->type == right->type) || (right->type == TypeUnknown))
10934345a63Smrg            expr->type = left->type;
11034345a63Smrg        else
11134345a63Smrg            expr->type = TypeUnknown;
11234345a63Smrg        expr->value.binary.left = left;
11334345a63Smrg        expr->value.binary.right = right;
11434345a63Smrg    }
11534345a63Smrg    else
11634345a63Smrg    {
11734345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
11834345a63Smrg        /* NOTREACHED */
119f46a6179Smrg    }
120f46a6179Smrg    return expr;
121f46a6179Smrg}
122f46a6179Smrg
123f46a6179SmrgKeycodeDef *
12434345a63SmrgKeycodeCreate(char *name, ExprDef * value)
125f46a6179Smrg{
12634345a63Smrg    KeycodeDef *def;
127f46a6179Smrg
12834345a63Smrg    def = uTypedAlloc(KeycodeDef);
12934345a63Smrg    if (def)
13034345a63Smrg    {
13134345a63Smrg        def->common.stmtType = StmtKeycodeDef;
13234345a63Smrg        def->common.next = NULL;
13334345a63Smrg        strncpy(def->name, name, XkbKeyNameLength);
13434345a63Smrg        def->name[XkbKeyNameLength] = '\0';
13534345a63Smrg        def->value = value;
136f46a6179Smrg    }
13734345a63Smrg    else
13834345a63Smrg    {
13934345a63Smrg        FATAL("Couldn't allocate key name definition in parser\n");
14034345a63Smrg        /* NOTREACHED */
141f46a6179Smrg    }
142f46a6179Smrg    return def;
143f46a6179Smrg}
144f46a6179Smrg
145f46a6179SmrgKeyAliasDef *
14634345a63SmrgKeyAliasCreate(char *alias, char *real)
147f46a6179Smrg{
14834345a63Smrg    KeyAliasDef *def;
149f46a6179Smrg
15034345a63Smrg    def = uTypedAlloc(KeyAliasDef);
15134345a63Smrg    if (def)
15234345a63Smrg    {
15334345a63Smrg        def->common.stmtType = StmtKeyAliasDef;
15434345a63Smrg        def->common.next = NULL;
15534345a63Smrg        strncpy(def->alias, alias, XkbKeyNameLength);
15634345a63Smrg        def->alias[XkbKeyNameLength] = '\0';
15734345a63Smrg        strncpy(def->real, real, XkbKeyNameLength);
15834345a63Smrg        def->real[XkbKeyNameLength] = '\0';
159f46a6179Smrg    }
16034345a63Smrg    else
16134345a63Smrg    {
16234345a63Smrg        FATAL("Couldn't allocate key alias definition in parser\n");
16334345a63Smrg        /* NOTREACHED */
164f46a6179Smrg    }
165f46a6179Smrg    return def;
166f46a6179Smrg}
167f46a6179Smrg
168f46a6179SmrgVModDef *
16934345a63SmrgVModCreate(Atom name, ExprDef * value)
17034345a63Smrg{
17134345a63Smrg    VModDef *def;
17234345a63Smrg    def = uTypedAlloc(VModDef);
17334345a63Smrg    if (def)
17434345a63Smrg    {
17534345a63Smrg        def->common.stmtType = StmtVModDef;
17634345a63Smrg        def->common.next = NULL;
17734345a63Smrg        def->name = name;
17834345a63Smrg        def->value = value;
17934345a63Smrg    }
18034345a63Smrg    else
18134345a63Smrg    {
18234345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
18334345a63Smrg        /* NOTREACHED */
184f46a6179Smrg    }
185f46a6179Smrg    return def;
186f46a6179Smrg}
187f46a6179Smrg
188f46a6179SmrgVarDef *
18934345a63SmrgVarCreate(ExprDef * name, ExprDef * value)
19034345a63Smrg{
19134345a63Smrg    VarDef *def;
19234345a63Smrg    def = uTypedAlloc(VarDef);
19334345a63Smrg    if (def)
19434345a63Smrg    {
19534345a63Smrg        def->common.stmtType = StmtVarDef;
19634345a63Smrg        def->common.next = NULL;
19734345a63Smrg        def->name = name;
19834345a63Smrg        def->value = value;
19934345a63Smrg    }
20034345a63Smrg    else
20134345a63Smrg    {
20234345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
20334345a63Smrg        /* NOTREACHED */
204f46a6179Smrg    }
205f46a6179Smrg    return def;
206f46a6179Smrg}
207f46a6179Smrg
208f46a6179SmrgVarDef *
20934345a63SmrgBoolVarCreate(Atom nameToken, unsigned set)
210f46a6179Smrg{
21134345a63Smrg    ExprDef *name, *value;
212f46a6179Smrg
21334345a63Smrg    name = ExprCreate(ExprIdent, TypeUnknown);
21434345a63Smrg    name->value.str = nameToken;
21534345a63Smrg    value = ExprCreate(ExprValue, TypeBoolean);
21634345a63Smrg    value->value.uval = set;
21734345a63Smrg    return VarCreate(name, value);
218f46a6179Smrg}
219f46a6179Smrg
220f46a6179SmrgInterpDef *
22134345a63SmrgInterpCreate(KeySym sym, ExprDef * match)
222f46a6179Smrg{
22334345a63Smrg    InterpDef *def;
224f46a6179Smrg
22534345a63Smrg    def = uTypedAlloc(InterpDef);
22634345a63Smrg    if (def)
22734345a63Smrg    {
22834345a63Smrg        def->common.stmtType = StmtInterpDef;
22934345a63Smrg        def->common.next = NULL;
23034345a63Smrg        def->sym = sym;
23134345a63Smrg        def->match = match;
232f46a6179Smrg    }
23334345a63Smrg    else
23434345a63Smrg    {
23534345a63Smrg        FATAL("Couldn't allocate interp definition in parser\n");
23634345a63Smrg        /* NOTREACHED */
237f46a6179Smrg    }
238f46a6179Smrg    return def;
239f46a6179Smrg}
240f46a6179Smrg
241f46a6179SmrgKeyTypeDef *
24234345a63SmrgKeyTypeCreate(Atom name, VarDef * body)
243f46a6179Smrg{
24434345a63Smrg    KeyTypeDef *def;
245f46a6179Smrg
24634345a63Smrg    def = uTypedAlloc(KeyTypeDef);
24734345a63Smrg    if (def)
24834345a63Smrg    {
24934345a63Smrg        def->common.stmtType = StmtKeyTypeDef;
25034345a63Smrg        def->common.next = NULL;
25134345a63Smrg        def->merge = MergeDefault;
25234345a63Smrg        def->name = name;
25334345a63Smrg        def->body = body;
254f46a6179Smrg    }
25534345a63Smrg    else
25634345a63Smrg    {
25734345a63Smrg        FATAL("Couldn't allocate key type definition in parser\n");
25834345a63Smrg        /* NOTREACHED */
259f46a6179Smrg    }
260f46a6179Smrg    return def;
261f46a6179Smrg}
262f46a6179Smrg
263f46a6179SmrgSymbolsDef *
26434345a63SmrgSymbolsCreate(char *keyName, ExprDef * symbols)
265f46a6179Smrg{
26634345a63Smrg    SymbolsDef *def;
267f46a6179Smrg
26834345a63Smrg    def = uTypedAlloc(SymbolsDef);
26934345a63Smrg    if (def)
27034345a63Smrg    {
27134345a63Smrg        def->common.stmtType = StmtSymbolsDef;
27234345a63Smrg        def->common.next = NULL;
27334345a63Smrg        def->merge = MergeDefault;
27434345a63Smrg        bzero(def->keyName, 5);
27534345a63Smrg        strncpy(def->keyName, keyName, 4);
27634345a63Smrg        def->symbols = symbols;
277f46a6179Smrg    }
27834345a63Smrg    else
27934345a63Smrg    {
28034345a63Smrg        FATAL("Couldn't allocate symbols definition in parser\n");
28134345a63Smrg        /* NOTREACHED */
282f46a6179Smrg    }
283f46a6179Smrg    return def;
284f46a6179Smrg}
285f46a6179Smrg
286f46a6179SmrgGroupCompatDef *
28734345a63SmrgGroupCompatCreate(int group, ExprDef * val)
288f46a6179Smrg{
28934345a63Smrg    GroupCompatDef *def;
290f46a6179Smrg
29134345a63Smrg    def = uTypedAlloc(GroupCompatDef);
29234345a63Smrg    if (def)
29334345a63Smrg    {
29434345a63Smrg        def->common.stmtType = StmtGroupCompatDef;
29534345a63Smrg        def->common.next = NULL;
29634345a63Smrg        def->merge = MergeDefault;
29734345a63Smrg        def->group = group;
29834345a63Smrg        def->def = val;
299f46a6179Smrg    }
30034345a63Smrg    else
30134345a63Smrg    {
30234345a63Smrg        FATAL("Couldn't allocate group compat definition in parser\n");
30334345a63Smrg        /* NOTREACHED */
304f46a6179Smrg    }
305f46a6179Smrg    return def;
306f46a6179Smrg}
307f46a6179Smrg
308f46a6179SmrgModMapDef *
30934345a63SmrgModMapCreate(Atom modifier, ExprDef * keys)
310f46a6179Smrg{
31134345a63Smrg    ModMapDef *def;
312f46a6179Smrg
31334345a63Smrg    def = uTypedAlloc(ModMapDef);
31434345a63Smrg    if (def)
31534345a63Smrg    {
31634345a63Smrg        def->common.stmtType = StmtModMapDef;
31734345a63Smrg        def->common.next = NULL;
31834345a63Smrg        def->merge = MergeDefault;
31934345a63Smrg        def->modifier = modifier;
32034345a63Smrg        def->keys = keys;
321f46a6179Smrg    }
32234345a63Smrg    else
32334345a63Smrg    {
32434345a63Smrg        FATAL("Couldn't allocate mod mask definition in parser\n");
32534345a63Smrg        /* NOTREACHED */
326f46a6179Smrg    }
327f46a6179Smrg    return def;
328f46a6179Smrg}
329f46a6179Smrg
330f46a6179SmrgIndicatorMapDef *
33134345a63SmrgIndicatorMapCreate(Atom name, VarDef * body)
332f46a6179Smrg{
33334345a63Smrg    IndicatorMapDef *def;
334f46a6179Smrg
33534345a63Smrg    def = uTypedAlloc(IndicatorMapDef);
33634345a63Smrg    if (def)
33734345a63Smrg    {
33834345a63Smrg        def->common.stmtType = StmtIndicatorMapDef;
33934345a63Smrg        def->common.next = NULL;
34034345a63Smrg        def->merge = MergeDefault;
34134345a63Smrg        def->name = name;
34234345a63Smrg        def->body = body;
343f46a6179Smrg    }
34434345a63Smrg    else
34534345a63Smrg    {
34634345a63Smrg        FATAL("Couldn't allocate indicator map definition in parser\n");
34734345a63Smrg        /* NOTREACHED */
348f46a6179Smrg    }
349f46a6179Smrg    return def;
350f46a6179Smrg}
351f46a6179Smrg
352f46a6179SmrgIndicatorNameDef *
35334345a63SmrgIndicatorNameCreate(int ndx, ExprDef * name, Bool virtual)
354f46a6179Smrg{
35534345a63Smrg    IndicatorNameDef *def;
356f46a6179Smrg
35734345a63Smrg    def = uTypedAlloc(IndicatorNameDef);
35834345a63Smrg    if (def)
35934345a63Smrg    {
36034345a63Smrg        def->common.stmtType = StmtIndicatorNameDef;
36134345a63Smrg        def->common.next = NULL;
36234345a63Smrg        def->merge = MergeDefault;
36334345a63Smrg        def->ndx = ndx;
36434345a63Smrg        def->name = name;
36534345a63Smrg        def->virtual = virtual;
366f46a6179Smrg    }
36734345a63Smrg    else
36834345a63Smrg    {
36934345a63Smrg        FATAL("Couldn't allocate indicator index definition in parser\n");
37034345a63Smrg        /* NOTREACHED */
371f46a6179Smrg    }
372f46a6179Smrg    return def;
373f46a6179Smrg}
374f46a6179Smrg
375f46a6179SmrgExprDef *
37634345a63SmrgActionCreate(Atom name, ExprDef * args)
377f46a6179Smrg{
37834345a63Smrg    ExprDef *act;
379f46a6179Smrg
38034345a63Smrg    act = uTypedAlloc(ExprDef);
38134345a63Smrg    if (act)
38234345a63Smrg    {
38334345a63Smrg        act->common.stmtType = StmtExpr;
38434345a63Smrg        act->common.next = NULL;
38534345a63Smrg        act->op = ExprActionDecl;
38634345a63Smrg        act->value.action.name = name;
38734345a63Smrg        act->value.action.args = args;
38834345a63Smrg        return act;
389f46a6179Smrg    }
390f46a6179Smrg    FATAL("Couldn't allocate ActionDef in parser\n");
391f46a6179Smrg    return NULL;
392f46a6179Smrg}
393f46a6179Smrg
394f46a6179SmrgExprDef *
395f46a6179SmrgCreateKeysymList(KeySym sym)
396f46a6179Smrg{
39734345a63Smrg    ExprDef *def;
398f46a6179Smrg
39934345a63Smrg    def = ExprCreate(ExprKeysymList, TypeSymbols);
40034345a63Smrg    if (def)
40134345a63Smrg    {
40234345a63Smrg        def->value.list.nSyms = 1;
40334345a63Smrg        def->value.list.szSyms = 2;
40434345a63Smrg        def->value.list.syms = uTypedCalloc(2, KeySym);
40534345a63Smrg        if (def->value.list.syms != NULL)
40634345a63Smrg        {
40734345a63Smrg            def->value.list.syms[0] = sym;
40834345a63Smrg            return def;
40934345a63Smrg        }
410f46a6179Smrg    }
411f46a6179Smrg    FATAL("Couldn't allocate expression for keysym list in parser\n");
412f46a6179Smrg    return NULL;
413f46a6179Smrg}
414f46a6179Smrg
415f46a6179SmrgShapeDef *
41634345a63SmrgShapeDeclCreate(Atom name, OutlineDef * outlines)
41734345a63Smrg{
41834345a63Smrg    ShapeDef *shape;
41934345a63Smrg    OutlineDef *ol;
42034345a63Smrg
42134345a63Smrg    shape = uTypedAlloc(ShapeDef);
42234345a63Smrg    if (shape != NULL)
42334345a63Smrg    {
42434345a63Smrg        bzero(shape, sizeof(ShapeDef));
42534345a63Smrg        shape->common.stmtType = StmtShapeDef;
42634345a63Smrg        shape->common.next = NULL;
42734345a63Smrg        shape->merge = MergeDefault;
42834345a63Smrg        shape->name = name;
42934345a63Smrg        shape->nOutlines = 0;
43034345a63Smrg        shape->outlines = outlines;
43134345a63Smrg        for (ol = outlines; ol != NULL; ol = (OutlineDef *) ol->common.next)
43234345a63Smrg        {
43334345a63Smrg            if (ol->nPoints > 0)
43434345a63Smrg                shape->nOutlines++;
43534345a63Smrg        }
436f46a6179Smrg    }
437f46a6179Smrg    return shape;
438f46a6179Smrg}
439f46a6179Smrg
440f46a6179SmrgOutlineDef *
44134345a63SmrgOutlineCreate(Atom field, ExprDef * points)
44234345a63Smrg{
44334345a63Smrg    OutlineDef *outline;
44434345a63Smrg    ExprDef *pt;
44534345a63Smrg
44634345a63Smrg    outline = uTypedAlloc(OutlineDef);
44734345a63Smrg    if (outline != NULL)
44834345a63Smrg    {
44934345a63Smrg        bzero(outline, sizeof(OutlineDef));
45034345a63Smrg        outline->common.stmtType = StmtOutlineDef;
45134345a63Smrg        outline->common.next = NULL;
45234345a63Smrg        outline->field = field;
45334345a63Smrg        outline->nPoints = 0;
45434345a63Smrg        if (points->op == ExprCoord)
45534345a63Smrg        {
45634345a63Smrg            for (pt = points; pt != NULL; pt = (ExprDef *) pt->common.next)
45734345a63Smrg            {
45834345a63Smrg                outline->nPoints++;
45934345a63Smrg            }
46034345a63Smrg        }
46134345a63Smrg        outline->points = points;
462f46a6179Smrg    }
463f46a6179Smrg    return outline;
464f46a6179Smrg}
465f46a6179Smrg
466f46a6179SmrgKeyDef *
46734345a63SmrgKeyDeclCreate(char *name, ExprDef * expr)
468f46a6179Smrg{
46934345a63Smrg    KeyDef *key;
470f46a6179Smrg
47134345a63Smrg    key = uTypedAlloc(KeyDef);
47234345a63Smrg    if (key != NULL)
47334345a63Smrg    {
47434345a63Smrg        bzero(key, sizeof(KeyDef));
47534345a63Smrg        key->common.stmtType = StmtKeyDef;
47634345a63Smrg        key->common.next = NULL;
47734345a63Smrg        if (name)
47834345a63Smrg            key->name = name;
47934345a63Smrg        else
48034345a63Smrg            key->expr = expr;
481f46a6179Smrg    }
482f46a6179Smrg    return key;
483f46a6179Smrg}
484f46a6179Smrg
485f46a6179SmrgKeyDef *
48634345a63SmrgKeyDeclMerge(KeyDef * into, KeyDef * from)
487f46a6179Smrg{
48834345a63Smrg    into->expr =
48934345a63Smrg        (ExprDef *) AppendStmt(&into->expr->common, &from->expr->common);
49034345a63Smrg    from->expr = NULL;
491f46a6179Smrg    uFree(from);
492f46a6179Smrg    return into;
493f46a6179Smrg}
494f46a6179Smrg
495f46a6179SmrgRowDef *
49634345a63SmrgRowDeclCreate(KeyDef * keys)
49734345a63Smrg{
49834345a63Smrg    RowDef *row;
49934345a63Smrg    KeyDef *key;
50034345a63Smrg
50134345a63Smrg    row = uTypedAlloc(RowDef);
50234345a63Smrg    if (row != NULL)
50334345a63Smrg    {
50434345a63Smrg        bzero(row, sizeof(RowDef));
50534345a63Smrg        row->common.stmtType = StmtRowDef;
50634345a63Smrg        row->common.next = NULL;
50734345a63Smrg        row->nKeys = 0;
50834345a63Smrg        row->keys = keys;
50934345a63Smrg        for (key = keys; key != NULL; key = (KeyDef *) key->common.next)
51034345a63Smrg        {
51134345a63Smrg            if (key->common.stmtType == StmtKeyDef)
51234345a63Smrg                row->nKeys++;
51334345a63Smrg        }
514f46a6179Smrg    }
515f46a6179Smrg    return row;
516f46a6179Smrg}
517f46a6179Smrg
518f46a6179SmrgSectionDef *
51934345a63SmrgSectionDeclCreate(Atom name, RowDef * rows)
52034345a63Smrg{
52134345a63Smrg    SectionDef *section;
52234345a63Smrg    RowDef *row;
52334345a63Smrg
52434345a63Smrg    section = uTypedAlloc(SectionDef);
52534345a63Smrg    if (section != NULL)
52634345a63Smrg    {
52734345a63Smrg        bzero(section, sizeof(SectionDef));
52834345a63Smrg        section->common.stmtType = StmtSectionDef;
52934345a63Smrg        section->common.next = NULL;
53034345a63Smrg        section->name = name;
53134345a63Smrg        section->nRows = 0;
53234345a63Smrg        section->rows = rows;
53334345a63Smrg        for (row = rows; row != NULL; row = (RowDef *) row->common.next)
53434345a63Smrg        {
53534345a63Smrg            if (row->common.stmtType == StmtRowDef)
53634345a63Smrg                section->nRows++;
53734345a63Smrg        }
538f46a6179Smrg    }
539f46a6179Smrg    return section;
540f46a6179Smrg}
541f46a6179Smrg
542f46a6179SmrgOverlayKeyDef *
54334345a63SmrgOverlayKeyCreate(char *under, char *over)
54434345a63Smrg{
54534345a63Smrg    OverlayKeyDef *key;
54634345a63Smrg
54734345a63Smrg    key = uTypedAlloc(OverlayKeyDef);
54834345a63Smrg    if (key != NULL)
54934345a63Smrg    {
55034345a63Smrg        bzero(key, sizeof(OverlayKeyDef));
55134345a63Smrg        key->common.stmtType = StmtOverlayKeyDef;
55234345a63Smrg        strncpy(key->over, over, XkbKeyNameLength);
55334345a63Smrg        strncpy(key->under, under, XkbKeyNameLength);
55434345a63Smrg        if (over)
55534345a63Smrg            uFree(over);
55634345a63Smrg        if (under)
55734345a63Smrg            uFree(under);
558f46a6179Smrg    }
559f46a6179Smrg    return key;
560f46a6179Smrg}
561f46a6179Smrg
562f46a6179SmrgOverlayDef *
56334345a63SmrgOverlayDeclCreate(Atom name, OverlayKeyDef * keys)
56434345a63Smrg{
56534345a63Smrg    OverlayDef *ol;
56634345a63Smrg    OverlayKeyDef *key;
56734345a63Smrg
56834345a63Smrg    ol = uTypedAlloc(OverlayDef);
56934345a63Smrg    if (ol != NULL)
57034345a63Smrg    {
57134345a63Smrg        bzero(ol, sizeof(OverlayDef));
57234345a63Smrg        ol->common.stmtType = StmtOverlayDef;
57334345a63Smrg        ol->name = name;
57434345a63Smrg        ol->keys = keys;
57534345a63Smrg        for (key = keys; key != NULL;
57634345a63Smrg             key = (OverlayKeyDef *) key->common.next)
57734345a63Smrg        {
57834345a63Smrg            ol->nKeys++;
57934345a63Smrg        }
580f46a6179Smrg    }
581f46a6179Smrg    return ol;
582f46a6179Smrg}
583f46a6179Smrg
584f46a6179SmrgDoodadDef *
58534345a63SmrgDoodadCreate(unsigned type, Atom name, VarDef * body)
586f46a6179Smrg{
58734345a63Smrg    DoodadDef *doodad;
588f46a6179Smrg
58934345a63Smrg    doodad = uTypedAlloc(DoodadDef);
59034345a63Smrg    if (doodad != NULL)
59134345a63Smrg    {
59234345a63Smrg        bzero(doodad, sizeof(DoodadDef));
59334345a63Smrg        doodad->common.stmtType = StmtDoodadDef;
59434345a63Smrg        doodad->common.next = NULL;
59534345a63Smrg        doodad->type = type;
59634345a63Smrg        doodad->name = name;
59734345a63Smrg        doodad->body = body;
598f46a6179Smrg    }
599f46a6179Smrg    return doodad;
600f46a6179Smrg}
601f46a6179Smrg
602f46a6179SmrgExprDef *
60334345a63SmrgAppendKeysymList(ExprDef * list, KeySym sym)
60434345a63Smrg{
60534345a63Smrg    if (list->value.list.nSyms >= list->value.list.szSyms)
60634345a63Smrg    {
60734345a63Smrg        list->value.list.szSyms *= 2;
60834345a63Smrg        list->value.list.syms = uTypedRecalloc(list->value.list.syms,
60934345a63Smrg                                               list->value.list.nSyms,
61034345a63Smrg                                               list->value.list.szSyms,
61134345a63Smrg                                               KeySym);
61234345a63Smrg        if (list->value.list.syms == NULL)
61334345a63Smrg        {
61434345a63Smrg            FATAL("Couldn't resize list of symbols for append\n");
61534345a63Smrg            return NULL;
61634345a63Smrg        }
61734345a63Smrg    }
61834345a63Smrg    list->value.list.syms[list->value.list.nSyms++] = sym;
619f46a6179Smrg    return list;
620f46a6179Smrg}
621f46a6179Smrg
622f46a6179Smrgint
62334345a63SmrgLookupKeysym(char *str, KeySym * sym_rtrn)
624f46a6179Smrg{
62534345a63Smrg    KeySym sym;
626f46a6179Smrg
62734345a63Smrg    if ((!str) || (uStrCaseCmp(str, "any") == 0)
62834345a63Smrg        || (uStrCaseCmp(str, "nosymbol") == 0))
62934345a63Smrg    {
63034345a63Smrg        *sym_rtrn = NoSymbol;
63134345a63Smrg        return 1;
632f46a6179Smrg    }
63334345a63Smrg    else if ((uStrCaseCmp(str, "none") == 0)
63434345a63Smrg             || (uStrCaseCmp(str, "voidsymbol") == 0))
63534345a63Smrg    {
63634345a63Smrg        *sym_rtrn = XK_VoidSymbol;
63734345a63Smrg        return 1;
638f46a6179Smrg    }
63934345a63Smrg    sym = XStringToKeysym(str);
64034345a63Smrg    if (sym != NoSymbol)
64134345a63Smrg    {
64234345a63Smrg        *sym_rtrn = sym;
64334345a63Smrg        return 1;
644f46a6179Smrg    }
645f46a6179Smrg    return 0;
646f46a6179Smrg}
647f46a6179Smrg
648f46a6179SmrgIncludeStmt *
64934345a63SmrgIncludeCreate(char *str, unsigned merge)
65034345a63Smrg{
65134345a63Smrg    IncludeStmt *incl, *first;
65234345a63Smrg    char *file, *map, *stmt, *tmp, *extra_data;
65334345a63Smrg    char nextop;
65434345a63Smrg    Bool haveSelf;
65534345a63Smrg
65634345a63Smrg    haveSelf = False;
65734345a63Smrg    incl = first = NULL;
65834345a63Smrg    file = map = NULL;
65934345a63Smrg    tmp = str;
66034345a63Smrg    stmt = uStringDup(str);
66134345a63Smrg    while ((tmp) && (*tmp))
66234345a63Smrg    {
66334345a63Smrg        if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
66434345a63Smrg        {
66534345a63Smrg            if ((file == NULL) && (map == NULL))
66634345a63Smrg            {
66734345a63Smrg                if (haveSelf)
66834345a63Smrg                    goto BAIL;
66934345a63Smrg                haveSelf = True;
67034345a63Smrg            }
67134345a63Smrg            if (first == NULL)
67234345a63Smrg                first = incl = uTypedAlloc(IncludeStmt);
67334345a63Smrg            else
67434345a63Smrg            {
67534345a63Smrg                incl->next = uTypedAlloc(IncludeStmt);
67634345a63Smrg                incl = incl->next;
67734345a63Smrg            }
67834345a63Smrg            if (incl)
67934345a63Smrg            {
68034345a63Smrg                incl->common.stmtType = StmtInclude;
68134345a63Smrg                incl->common.next = NULL;
68234345a63Smrg                incl->merge = merge;
68334345a63Smrg                incl->stmt = NULL;
68434345a63Smrg                incl->file = file;
68534345a63Smrg                incl->map = map;
68634345a63Smrg                incl->modifier = extra_data;
68734345a63Smrg                incl->path = NULL;
68834345a63Smrg                incl->next = NULL;
68934345a63Smrg            }
69034345a63Smrg            else
69134345a63Smrg            {
69234345a63Smrg                WSGO("Allocation failure in IncludeCreate\n");
69334345a63Smrg                ACTION("Using only part of the include\n");
69434345a63Smrg                break;
69534345a63Smrg            }
69634345a63Smrg            if (nextop == '|')
69734345a63Smrg                merge = MergeAugment;
69834345a63Smrg            else
69934345a63Smrg                merge = MergeOverride;
70034345a63Smrg        }
70134345a63Smrg        else
70234345a63Smrg        {
70334345a63Smrg            goto BAIL;
70434345a63Smrg        }
70534345a63Smrg    }
70634345a63Smrg    if (first)
70734345a63Smrg        first->stmt = stmt;
70834345a63Smrg    else if (stmt)
70934345a63Smrg        uFree(stmt);
710f46a6179Smrg    return first;
71134345a63Smrg  BAIL:
71234345a63Smrg    ERROR1("Illegal include statement \"%s\"\n", stmt);
713f46a6179Smrg    ACTION("Ignored\n");
71434345a63Smrg    while (first)
71534345a63Smrg    {
71634345a63Smrg        incl = first->next;
71734345a63Smrg        if (first->file)
71834345a63Smrg            uFree(first->file);
71934345a63Smrg        if (first->map)
72034345a63Smrg            uFree(first->map);
72134345a63Smrg        if (first->modifier)
72234345a63Smrg            uFree(first->modifier);
72334345a63Smrg        if (first->path)
72434345a63Smrg            uFree(first->path);
72534345a63Smrg        first->file = first->map = first->path = NULL;
72634345a63Smrg        uFree(first);
72734345a63Smrg        first = incl;
728f46a6179Smrg    }
729f46a6179Smrg    if (stmt)
73034345a63Smrg        uFree(stmt);
731f46a6179Smrg    return NULL;
732f46a6179Smrg}
733f46a6179Smrg
734f46a6179Smrg#ifdef DEBUG
735f46a6179Smrgvoid
73634345a63SmrgPrintStmtAddrs(ParseCommon * stmt)
737f46a6179Smrg{
73834345a63Smrg    fprintf(stderr, "0x%x", stmt);
73934345a63Smrg    if (stmt)
74034345a63Smrg    {
74134345a63Smrg        do
74234345a63Smrg        {
74334345a63Smrg            fprintf(stderr, "->0x%x", stmt->next);
74434345a63Smrg            stmt = stmt->next;
74534345a63Smrg        }
74634345a63Smrg        while (stmt);
747f46a6179Smrg    }
74834345a63Smrg    fprintf(stderr, "\n");
749f46a6179Smrg}
750f46a6179Smrg#endif
751f46a6179Smrg
752f46a6179Smrgstatic void
75334345a63SmrgCheckDefaultMap(XkbFile * maps)
75434345a63Smrg{
75534345a63Smrg    XkbFile *dflt, *tmp;
75634345a63Smrg
75734345a63Smrg    dflt = NULL;
75834345a63Smrg    for (tmp = maps, dflt = NULL; tmp != NULL;
75934345a63Smrg         tmp = (XkbFile *) tmp->common.next)
76034345a63Smrg    {
76134345a63Smrg        if (tmp->flags & XkbLC_Default)
76234345a63Smrg        {
76334345a63Smrg            if (dflt == NULL)
76434345a63Smrg                dflt = tmp;
76534345a63Smrg            else
76634345a63Smrg            {
76734345a63Smrg                if (warningLevel > 2)
76834345a63Smrg                {
76934345a63Smrg                    WARN1("Multiple default components in %s\n",
77034345a63Smrg                          (scanFile ? scanFile : "(unknown)"));
77134345a63Smrg                    ACTION2("Using %s, ignoring %s\n",
77234345a63Smrg                            (dflt->name ? dflt->name : "(first)"),
77334345a63Smrg                            (tmp->name ? tmp->name : "(subsequent)"));
77434345a63Smrg                }
77534345a63Smrg                tmp->flags &= (~XkbLC_Default);
77634345a63Smrg            }
77734345a63Smrg        }
778f46a6179Smrg    }
779f46a6179Smrg    return;
780f46a6179Smrg}
781f46a6179Smrg
782f46a6179Smrgint
78334345a63SmrgXKBParseFile(FILE * file, XkbFile ** pRtrn)
78434345a63Smrg{
78534345a63Smrg    if (file)
78634345a63Smrg    {
78734345a63Smrg        yyin = file;
78834345a63Smrg        rtrnValue = NULL;
78934345a63Smrg        if (yyparse() == 0)
79034345a63Smrg        {
79134345a63Smrg            *pRtrn = rtrnValue;
79234345a63Smrg            CheckDefaultMap(rtrnValue);
79334345a63Smrg            rtrnValue = NULL;
79434345a63Smrg            return 1;
79534345a63Smrg        }
79634345a63Smrg        *pRtrn = NULL;
79734345a63Smrg        return 0;
79834345a63Smrg    }
79934345a63Smrg    *pRtrn = NULL;
800f46a6179Smrg    return 1;
801f46a6179Smrg}
802f46a6179Smrg
803f46a6179SmrgXkbFile *
80434345a63SmrgCreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
80534345a63Smrg{
80634345a63Smrg    XkbFile *file;
80734345a63Smrg    static int fileID;
80834345a63Smrg
80934345a63Smrg    file = uTypedAlloc(XkbFile);
81034345a63Smrg    if (file)
81134345a63Smrg    {
81234345a63Smrg        XkbEnsureSafeMapName(name);
81334345a63Smrg        bzero(file, sizeof(XkbFile));
81434345a63Smrg        file->type = type;
81534345a63Smrg        file->topName = uStringDup(name);
81634345a63Smrg        file->name = name;
81734345a63Smrg        file->defs = defs;
81834345a63Smrg        file->id = fileID++;
81934345a63Smrg        file->compiled = False;
82034345a63Smrg        file->flags = flags;
821f46a6179Smrg    }
822f46a6179Smrg    return file;
823f46a6179Smrg}
824f46a6179Smrg
82534345a63Smrgunsigned
82634345a63SmrgStmtSetMerge(ParseCommon * stmt, unsigned merge)
827f46a6179Smrg{
82834345a63Smrg    if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
82934345a63Smrg    {
83034345a63Smrg        yyerror("illegal use of 'alternate' merge mode");
83134345a63Smrg        merge = MergeDefault;
832f46a6179Smrg    }
833f46a6179Smrg    return merge;
834f46a6179Smrg}
835