parseutils.c revision 6930ead5
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;
606930ead5Smrg    expr = malloc(sizeof(ExprDef));
6134345a63Smrg    if (expr)
6234345a63Smrg    {
636930ead5Smrg        *expr = (ExprDef) {
646930ead5Smrg            .common.stmtType = StmtExpr,
656930ead5Smrg            .common.next = NULL,
666930ead5Smrg            .op = op,
676930ead5Smrg            .type = type
686930ead5Smrg        };
6934345a63Smrg    }
7034345a63Smrg    else
7134345a63Smrg    {
7234345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
7334345a63Smrg        /* NOTREACHED */
74f46a6179Smrg    }
75f46a6179Smrg    return expr;
76f46a6179Smrg}
77f46a6179Smrg
78f46a6179SmrgExprDef *
7934345a63SmrgExprCreateUnary(unsigned op, unsigned type, ExprDef * child)
8034345a63Smrg{
8134345a63Smrg    ExprDef *expr;
826930ead5Smrg    expr = malloc(sizeof(ExprDef));
8334345a63Smrg    if (expr)
8434345a63Smrg    {
856930ead5Smrg        *expr = (ExprDef) {
866930ead5Smrg            .common.stmtType = StmtExpr,
876930ead5Smrg            .common.next = NULL,
886930ead5Smrg            .op = op,
896930ead5Smrg            .type = type,
906930ead5Smrg            .value.child = child
916930ead5Smrg        };
9234345a63Smrg    }
9334345a63Smrg    else
9434345a63Smrg    {
9534345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
9634345a63Smrg        /* NOTREACHED */
97f46a6179Smrg    }
98f46a6179Smrg    return expr;
99f46a6179Smrg}
100f46a6179Smrg
101f46a6179SmrgExprDef *
10234345a63SmrgExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
10334345a63Smrg{
10434345a63Smrg    ExprDef *expr;
1056930ead5Smrg    expr = malloc(sizeof(ExprDef));
10634345a63Smrg    if (expr)
10734345a63Smrg    {
1086930ead5Smrg        *expr = (ExprDef) {
1096930ead5Smrg            .common.stmtType = StmtExpr,
1106930ead5Smrg            .common.next = NULL,
1116930ead5Smrg            .op = op,
1126930ead5Smrg            .type = TypeUnknown,
1136930ead5Smrg            .value.binary.left = left,
1146930ead5Smrg            .value.binary.right = right
1156930ead5Smrg        };
1166930ead5Smrg
11734345a63Smrg        if ((op == OpAssign) || (left->type == TypeUnknown))
11834345a63Smrg            expr->type = right->type;
11934345a63Smrg        else if ((left->type == right->type) || (right->type == TypeUnknown))
12034345a63Smrg            expr->type = left->type;
12134345a63Smrg    }
12234345a63Smrg    else
12334345a63Smrg    {
12434345a63Smrg        FATAL("Couldn't allocate expression in parser\n");
12534345a63Smrg        /* NOTREACHED */
126f46a6179Smrg    }
127f46a6179Smrg    return expr;
128f46a6179Smrg}
129f46a6179Smrg
130f46a6179SmrgKeycodeDef *
1316930ead5SmrgKeycodeCreate(const char *name, ExprDef *value)
132f46a6179Smrg{
13334345a63Smrg    KeycodeDef *def;
134f46a6179Smrg
1356930ead5Smrg    def = malloc(sizeof(KeycodeDef));
13634345a63Smrg    if (def)
13734345a63Smrg    {
1386930ead5Smrg        *def = (KeycodeDef) {
1396930ead5Smrg            .common.stmtType = StmtKeycodeDef,
1406930ead5Smrg            .common.next = NULL,
1416930ead5Smrg            .value = value
1426930ead5Smrg        };
14334345a63Smrg        strncpy(def->name, name, XkbKeyNameLength);
14434345a63Smrg        def->name[XkbKeyNameLength] = '\0';
145f46a6179Smrg    }
14634345a63Smrg    else
14734345a63Smrg    {
14834345a63Smrg        FATAL("Couldn't allocate key name definition in parser\n");
14934345a63Smrg        /* NOTREACHED */
150f46a6179Smrg    }
151f46a6179Smrg    return def;
152f46a6179Smrg}
153f46a6179Smrg
154f46a6179SmrgKeyAliasDef *
1556930ead5SmrgKeyAliasCreate(const char *alias, const char *real)
156f46a6179Smrg{
15734345a63Smrg    KeyAliasDef *def;
158f46a6179Smrg
1596930ead5Smrg    def = malloc(sizeof(KeyAliasDef));
16034345a63Smrg    if (def)
16134345a63Smrg    {
1626930ead5Smrg        *def = (KeyAliasDef) {
1636930ead5Smrg            .common.stmtType = StmtKeyAliasDef,
1646930ead5Smrg            .common.next = NULL,
1656930ead5Smrg        };
16634345a63Smrg        strncpy(def->alias, alias, XkbKeyNameLength);
16734345a63Smrg        def->alias[XkbKeyNameLength] = '\0';
16834345a63Smrg        strncpy(def->real, real, XkbKeyNameLength);
16934345a63Smrg        def->real[XkbKeyNameLength] = '\0';
170f46a6179Smrg    }
17134345a63Smrg    else
17234345a63Smrg    {
17334345a63Smrg        FATAL("Couldn't allocate key alias definition in parser\n");
17434345a63Smrg        /* NOTREACHED */
175f46a6179Smrg    }
176f46a6179Smrg    return def;
177f46a6179Smrg}
178f46a6179Smrg
179f46a6179SmrgVModDef *
18034345a63SmrgVModCreate(Atom name, ExprDef * value)
18134345a63Smrg{
18234345a63Smrg    VModDef *def;
1836930ead5Smrg    def = malloc(sizeof(VModDef));
18434345a63Smrg    if (def)
18534345a63Smrg    {
1866930ead5Smrg        *def = (VModDef) {
1876930ead5Smrg            .common.stmtType = StmtVModDef,
1886930ead5Smrg            .common.next = NULL,
1896930ead5Smrg            .name = name,
1906930ead5Smrg            .value = value
1916930ead5Smrg        };
19234345a63Smrg    }
19334345a63Smrg    else
19434345a63Smrg    {
19534345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
19634345a63Smrg        /* NOTREACHED */
197f46a6179Smrg    }
198f46a6179Smrg    return def;
199f46a6179Smrg}
200f46a6179Smrg
201f46a6179SmrgVarDef *
20234345a63SmrgVarCreate(ExprDef * name, ExprDef * value)
20334345a63Smrg{
20434345a63Smrg    VarDef *def;
2056930ead5Smrg    def = malloc(sizeof(VarDef));
20634345a63Smrg    if (def)
20734345a63Smrg    {
2086930ead5Smrg        *def = (VarDef) {
2096930ead5Smrg            .common.stmtType = StmtVarDef,
2106930ead5Smrg            .common.next = NULL,
2116930ead5Smrg            .name = name,
2126930ead5Smrg            .value = value
2136930ead5Smrg        };
21434345a63Smrg    }
21534345a63Smrg    else
21634345a63Smrg    {
21734345a63Smrg        FATAL("Couldn't allocate variable definition in parser\n");
21834345a63Smrg        /* NOTREACHED */
219f46a6179Smrg    }
220f46a6179Smrg    return def;
221f46a6179Smrg}
222f46a6179Smrg
223f46a6179SmrgVarDef *
22434345a63SmrgBoolVarCreate(Atom nameToken, unsigned set)
225f46a6179Smrg{
22634345a63Smrg    ExprDef *name, *value;
227f46a6179Smrg
22834345a63Smrg    name = ExprCreate(ExprIdent, TypeUnknown);
22934345a63Smrg    name->value.str = nameToken;
23034345a63Smrg    value = ExprCreate(ExprValue, TypeBoolean);
23134345a63Smrg    value->value.uval = set;
23234345a63Smrg    return VarCreate(name, value);
233f46a6179Smrg}
234f46a6179Smrg
235f46a6179SmrgInterpDef *
236690143ccSmrgInterpCreate(const char *sym_str, ExprDef * match)
237f46a6179Smrg{
23834345a63Smrg    InterpDef *def;
239f46a6179Smrg
2406930ead5Smrg    def = malloc(sizeof(InterpDef));
24134345a63Smrg    if (def)
24234345a63Smrg    {
2436930ead5Smrg        *def = (InterpDef) {
2446930ead5Smrg            .common.stmtType = StmtInterpDef,
2456930ead5Smrg            .common.next = NULL,
2466930ead5Smrg            .match = match
2476930ead5Smrg        };
248690143ccSmrg        if (LookupKeysym(sym_str, &def->sym) == 0)
249690143ccSmrg            def->ignore = True;
250690143ccSmrg        else
251690143ccSmrg            def->ignore = False;
252f46a6179Smrg    }
25334345a63Smrg    else
25434345a63Smrg    {
25534345a63Smrg        FATAL("Couldn't allocate interp definition in parser\n");
25634345a63Smrg        /* NOTREACHED */
257f46a6179Smrg    }
258f46a6179Smrg    return def;
259f46a6179Smrg}
260f46a6179Smrg
261f46a6179SmrgKeyTypeDef *
26234345a63SmrgKeyTypeCreate(Atom name, VarDef * body)
263f46a6179Smrg{
26434345a63Smrg    KeyTypeDef *def;
265f46a6179Smrg
2666930ead5Smrg    def = malloc(sizeof(KeyTypeDef));
26734345a63Smrg    if (def)
26834345a63Smrg    {
2696930ead5Smrg        *def = (KeyTypeDef) {
2706930ead5Smrg            .common.stmtType = StmtKeyTypeDef,
2716930ead5Smrg            .common.next = NULL,
2726930ead5Smrg            .merge = MergeDefault,
2736930ead5Smrg            .name = name,
2746930ead5Smrg            .body = body
2756930ead5Smrg        };
276f46a6179Smrg    }
27734345a63Smrg    else
27834345a63Smrg    {
27934345a63Smrg        FATAL("Couldn't allocate key type definition in parser\n");
28034345a63Smrg        /* NOTREACHED */
281f46a6179Smrg    }
282f46a6179Smrg    return def;
283f46a6179Smrg}
284f46a6179Smrg
285f46a6179SmrgSymbolsDef *
28634345a63SmrgSymbolsCreate(char *keyName, ExprDef * symbols)
287f46a6179Smrg{
28834345a63Smrg    SymbolsDef *def;
289f46a6179Smrg
2906930ead5Smrg    def = malloc(sizeof(SymbolsDef));
29134345a63Smrg    if (def)
29234345a63Smrg    {
2936930ead5Smrg        *def = (SymbolsDef) {
2946930ead5Smrg            .common.stmtType = StmtSymbolsDef,
2956930ead5Smrg            .common.next = NULL,
2966930ead5Smrg            .merge = MergeDefault,
2976930ead5Smrg            .symbols = symbols
2986930ead5Smrg        };
29934345a63Smrg        strncpy(def->keyName, keyName, 4);
3006930ead5Smrg        def->keyName[4] = 0;
301f46a6179Smrg    }
30234345a63Smrg    else
30334345a63Smrg    {
30434345a63Smrg        FATAL("Couldn't allocate symbols definition in parser\n");
30534345a63Smrg        /* NOTREACHED */
306f46a6179Smrg    }
307f46a6179Smrg    return def;
308f46a6179Smrg}
309f46a6179Smrg
310f46a6179SmrgGroupCompatDef *
31134345a63SmrgGroupCompatCreate(int group, ExprDef * val)
312f46a6179Smrg{
31334345a63Smrg    GroupCompatDef *def;
314f46a6179Smrg
3156930ead5Smrg    def = malloc(sizeof(GroupCompatDef));
31634345a63Smrg    if (def)
31734345a63Smrg    {
3186930ead5Smrg        *def = (GroupCompatDef) {
3196930ead5Smrg            .common.stmtType = StmtGroupCompatDef,
3206930ead5Smrg            .common.next = NULL,
3216930ead5Smrg            .merge = MergeDefault,
3226930ead5Smrg            .group = group,
3236930ead5Smrg            .def = val
3246930ead5Smrg        };
325f46a6179Smrg    }
32634345a63Smrg    else
32734345a63Smrg    {
32834345a63Smrg        FATAL("Couldn't allocate group compat definition in parser\n");
32934345a63Smrg        /* NOTREACHED */
330f46a6179Smrg    }
331f46a6179Smrg    return def;
332f46a6179Smrg}
333f46a6179Smrg
334f46a6179SmrgModMapDef *
33534345a63SmrgModMapCreate(Atom modifier, ExprDef * keys)
336f46a6179Smrg{
33734345a63Smrg    ModMapDef *def;
338f46a6179Smrg
3396930ead5Smrg    def = malloc(sizeof(ModMapDef));
34034345a63Smrg    if (def)
34134345a63Smrg    {
3426930ead5Smrg        *def = (ModMapDef) {
3436930ead5Smrg            .common.stmtType = StmtModMapDef,
3446930ead5Smrg            .common.next = NULL,
3456930ead5Smrg            .merge = MergeDefault,
3466930ead5Smrg            .modifier = modifier,
3476930ead5Smrg            .keys = keys
3486930ead5Smrg        };
349f46a6179Smrg    }
35034345a63Smrg    else
35134345a63Smrg    {
35234345a63Smrg        FATAL("Couldn't allocate mod mask definition in parser\n");
35334345a63Smrg        /* NOTREACHED */
354f46a6179Smrg    }
355f46a6179Smrg    return def;
356f46a6179Smrg}
357f46a6179Smrg
358f46a6179SmrgIndicatorMapDef *
35934345a63SmrgIndicatorMapCreate(Atom name, VarDef * body)
360f46a6179Smrg{
36134345a63Smrg    IndicatorMapDef *def;
362f46a6179Smrg
3636930ead5Smrg    def = malloc(sizeof(IndicatorMapDef));
36434345a63Smrg    if (def)
36534345a63Smrg    {
3666930ead5Smrg        *def = (IndicatorMapDef) {
3676930ead5Smrg            .common.stmtType = StmtIndicatorMapDef,
3686930ead5Smrg            .common.next = NULL,
3696930ead5Smrg            .merge = MergeDefault,
3706930ead5Smrg            .name = name,
3716930ead5Smrg            .body = body
3726930ead5Smrg        };
373f46a6179Smrg    }
37434345a63Smrg    else
37534345a63Smrg    {
37634345a63Smrg        FATAL("Couldn't allocate indicator map definition in parser\n");
37734345a63Smrg        /* NOTREACHED */
378f46a6179Smrg    }
379f46a6179Smrg    return def;
380f46a6179Smrg}
381f46a6179Smrg
382f46a6179SmrgIndicatorNameDef *
38334345a63SmrgIndicatorNameCreate(int ndx, ExprDef * name, Bool virtual)
384f46a6179Smrg{
38534345a63Smrg    IndicatorNameDef *def;
386f46a6179Smrg
3876930ead5Smrg    def = malloc(sizeof(IndicatorNameDef));
38834345a63Smrg    if (def)
38934345a63Smrg    {
3906930ead5Smrg        *def = (IndicatorNameDef) {
3916930ead5Smrg            .common.stmtType = StmtIndicatorNameDef,
3926930ead5Smrg            .common.next = NULL,
3936930ead5Smrg            .merge = MergeDefault,
3946930ead5Smrg            .ndx = ndx,
3956930ead5Smrg            .name = name,
3966930ead5Smrg            .virtual = virtual
3976930ead5Smrg        };
398f46a6179Smrg    }
39934345a63Smrg    else
40034345a63Smrg    {
40134345a63Smrg        FATAL("Couldn't allocate indicator index definition in parser\n");
40234345a63Smrg        /* NOTREACHED */
403f46a6179Smrg    }
404f46a6179Smrg    return def;
405f46a6179Smrg}
406f46a6179Smrg
407f46a6179SmrgExprDef *
40834345a63SmrgActionCreate(Atom name, ExprDef * args)
409f46a6179Smrg{
41034345a63Smrg    ExprDef *act;
411f46a6179Smrg
4126930ead5Smrg    act = malloc(sizeof(ExprDef));
41334345a63Smrg    if (act)
41434345a63Smrg    {
4156930ead5Smrg        *act = (ExprDef) {
4166930ead5Smrg            .common.stmtType = StmtExpr,
4176930ead5Smrg            .common.next = NULL,
4186930ead5Smrg            .op = ExprActionDecl,
4196930ead5Smrg            .value.action.name = name,
4206930ead5Smrg            .value.action.args = args
4216930ead5Smrg        };
42234345a63Smrg        return act;
423f46a6179Smrg    }
424f46a6179Smrg    FATAL("Couldn't allocate ActionDef in parser\n");
425f46a6179Smrg    return NULL;
426f46a6179Smrg}
427f46a6179Smrg
428f46a6179SmrgExprDef *
42983e5f723SmrgCreateKeysymList(char *sym)
430f46a6179Smrg{
43134345a63Smrg    ExprDef *def;
432f46a6179Smrg
43334345a63Smrg    def = ExprCreate(ExprKeysymList, TypeSymbols);
43434345a63Smrg    if (def)
43534345a63Smrg    {
43634345a63Smrg        def->value.list.nSyms = 1;
43783e5f723Smrg        def->value.list.szSyms = 4;
4386930ead5Smrg        def->value.list.syms = calloc(4, sizeof(char *));
43934345a63Smrg        if (def->value.list.syms != NULL)
44034345a63Smrg        {
44134345a63Smrg            def->value.list.syms[0] = sym;
44234345a63Smrg            return def;
44334345a63Smrg        }
444f46a6179Smrg    }
445f46a6179Smrg    FATAL("Couldn't allocate expression for keysym list in parser\n");
446f46a6179Smrg    return NULL;
447f46a6179Smrg}
448f46a6179Smrg
449f46a6179SmrgShapeDef *
45034345a63SmrgShapeDeclCreate(Atom name, OutlineDef * outlines)
45134345a63Smrg{
45234345a63Smrg    ShapeDef *shape;
45334345a63Smrg
4546930ead5Smrg    shape = calloc(1, sizeof(ShapeDef));
45534345a63Smrg    if (shape != NULL)
45634345a63Smrg    {
4576930ead5Smrg        *shape = (ShapeDef) {
4586930ead5Smrg            .common.stmtType = StmtShapeDef,
4596930ead5Smrg            .common.next = NULL,
4606930ead5Smrg            .merge = MergeDefault,
4616930ead5Smrg            .name = name,
4626930ead5Smrg            .nOutlines = 0,
4636930ead5Smrg            .outlines = outlines
4646930ead5Smrg        };
4656930ead5Smrg        for (OutlineDef *ol = outlines; ol != NULL;
4666930ead5Smrg             ol = (OutlineDef *) ol->common.next)
46734345a63Smrg        {
46834345a63Smrg            if (ol->nPoints > 0)
46934345a63Smrg                shape->nOutlines++;
47034345a63Smrg        }
471f46a6179Smrg    }
472f46a6179Smrg    return shape;
473f46a6179Smrg}
474f46a6179Smrg
475f46a6179SmrgOutlineDef *
47634345a63SmrgOutlineCreate(Atom field, ExprDef * points)
47734345a63Smrg{
47834345a63Smrg    OutlineDef *outline;
47934345a63Smrg
4806930ead5Smrg    outline = calloc(1, sizeof(OutlineDef));
48134345a63Smrg    if (outline != NULL)
48234345a63Smrg    {
4836930ead5Smrg        *outline = (OutlineDef) {
4846930ead5Smrg            .common.stmtType = StmtOutlineDef,
4856930ead5Smrg            .common.next = NULL,
4866930ead5Smrg            .field = field,
4876930ead5Smrg            .nPoints = 0,
4886930ead5Smrg            .points = points
4896930ead5Smrg        };
49034345a63Smrg        if (points->op == ExprCoord)
49134345a63Smrg        {
4926930ead5Smrg            for (ExprDef *pt = points; pt != NULL;
4936930ead5Smrg                 pt = (ExprDef *) pt->common.next)
49434345a63Smrg            {
49534345a63Smrg                outline->nPoints++;
49634345a63Smrg            }
49734345a63Smrg        }
498f46a6179Smrg    }
499f46a6179Smrg    return outline;
500f46a6179Smrg}
501f46a6179Smrg
502f46a6179SmrgKeyDef *
50334345a63SmrgKeyDeclCreate(char *name, ExprDef * expr)
504f46a6179Smrg{
50534345a63Smrg    KeyDef *key;
506f46a6179Smrg
5076930ead5Smrg    key = calloc(1, sizeof(KeyDef));
50834345a63Smrg    if (key != NULL)
50934345a63Smrg    {
5106930ead5Smrg        *key = (KeyDef) {
5116930ead5Smrg            .common.stmtType = StmtKeyDef,
5126930ead5Smrg            .common.next = NULL,
5136930ead5Smrg        };
51434345a63Smrg        if (name)
51534345a63Smrg            key->name = name;
51634345a63Smrg        else
51734345a63Smrg            key->expr = expr;
518f46a6179Smrg    }
519f46a6179Smrg    return key;
520f46a6179Smrg}
521f46a6179Smrg
5226930ead5Smrg#if 0
523f46a6179SmrgKeyDef *
52434345a63SmrgKeyDeclMerge(KeyDef * into, KeyDef * from)
525f46a6179Smrg{
52634345a63Smrg    into->expr =
52734345a63Smrg        (ExprDef *) AppendStmt(&into->expr->common, &from->expr->common);
52834345a63Smrg    from->expr = NULL;
5296930ead5Smrg    free(from);
530f46a6179Smrg    return into;
531f46a6179Smrg}
5326930ead5Smrg#endif
533f46a6179Smrg
534f46a6179SmrgRowDef *
53534345a63SmrgRowDeclCreate(KeyDef * keys)
53634345a63Smrg{
53734345a63Smrg    RowDef *row;
53834345a63Smrg
5396930ead5Smrg    row = calloc(1, sizeof(RowDef));
54034345a63Smrg    if (row != NULL)
54134345a63Smrg    {
5426930ead5Smrg        *row = (RowDef) {
5436930ead5Smrg            .common.stmtType = StmtRowDef,
5446930ead5Smrg            .common.next = NULL,
5456930ead5Smrg            .nKeys = 0,
5466930ead5Smrg            .keys = keys
5476930ead5Smrg        };
5486930ead5Smrg        for (KeyDef *key = keys; key != NULL; key = (KeyDef *) key->common.next)
54934345a63Smrg        {
55034345a63Smrg            if (key->common.stmtType == StmtKeyDef)
55134345a63Smrg                row->nKeys++;
55234345a63Smrg        }
553f46a6179Smrg    }
554f46a6179Smrg    return row;
555f46a6179Smrg}
556f46a6179Smrg
557f46a6179SmrgSectionDef *
55834345a63SmrgSectionDeclCreate(Atom name, RowDef * rows)
55934345a63Smrg{
56034345a63Smrg    SectionDef *section;
56134345a63Smrg
5626930ead5Smrg    section = calloc(1, sizeof(SectionDef));
56334345a63Smrg    if (section != NULL)
56434345a63Smrg    {
5656930ead5Smrg        *section = (SectionDef) {
5666930ead5Smrg            .common.stmtType = StmtSectionDef,
5676930ead5Smrg            .common.next = NULL,
5686930ead5Smrg            .name = name,
5696930ead5Smrg            .nRows = 0,
5706930ead5Smrg            .rows = rows
5716930ead5Smrg        };
5726930ead5Smrg        for (RowDef *row = rows; row != NULL; row = (RowDef *) row->common.next)
57334345a63Smrg        {
57434345a63Smrg            if (row->common.stmtType == StmtRowDef)
57534345a63Smrg                section->nRows++;
57634345a63Smrg        }
577f46a6179Smrg    }
578f46a6179Smrg    return section;
579f46a6179Smrg}
580f46a6179Smrg
581f46a6179SmrgOverlayKeyDef *
58234345a63SmrgOverlayKeyCreate(char *under, char *over)
58334345a63Smrg{
58434345a63Smrg    OverlayKeyDef *key;
58534345a63Smrg
5866930ead5Smrg    key = calloc(1, sizeof(OverlayKeyDef));
58734345a63Smrg    if (key != NULL)
58834345a63Smrg    {
5896930ead5Smrg        *key = (OverlayKeyDef) {
5906930ead5Smrg            .common.stmtType = StmtOverlayKeyDef
5916930ead5Smrg        };
59234345a63Smrg        strncpy(key->over, over, XkbKeyNameLength);
59334345a63Smrg        strncpy(key->under, under, XkbKeyNameLength);
5946930ead5Smrg        free(over);
5956930ead5Smrg        free(under);
596f46a6179Smrg    }
597f46a6179Smrg    return key;
598f46a6179Smrg}
599f46a6179Smrg
600f46a6179SmrgOverlayDef *
60134345a63SmrgOverlayDeclCreate(Atom name, OverlayKeyDef * keys)
60234345a63Smrg{
60334345a63Smrg    OverlayDef *ol;
60434345a63Smrg
6056930ead5Smrg    ol = calloc(1, sizeof(OverlayDef));
60634345a63Smrg    if (ol != NULL)
60734345a63Smrg    {
6086930ead5Smrg        *ol = (OverlayDef) {
6096930ead5Smrg            .common.stmtType = StmtOverlayDef,
6106930ead5Smrg            .name = name,
6116930ead5Smrg            .keys = keys
6126930ead5Smrg        };
6136930ead5Smrg        for (OverlayKeyDef *key = keys; key != NULL;
61434345a63Smrg             key = (OverlayKeyDef *) key->common.next)
61534345a63Smrg        {
61634345a63Smrg            ol->nKeys++;
61734345a63Smrg        }
618f46a6179Smrg    }
619f46a6179Smrg    return ol;
620f46a6179Smrg}
621f46a6179Smrg
622f46a6179SmrgDoodadDef *
62334345a63SmrgDoodadCreate(unsigned type, Atom name, VarDef * body)
624f46a6179Smrg{
62534345a63Smrg    DoodadDef *doodad;
626f46a6179Smrg
6276930ead5Smrg    doodad = calloc(1, sizeof(DoodadDef));
62834345a63Smrg    if (doodad != NULL)
62934345a63Smrg    {
6306930ead5Smrg        *doodad = (DoodadDef) {
6316930ead5Smrg            .common.stmtType = StmtDoodadDef,
6326930ead5Smrg            .common.next = NULL,
6336930ead5Smrg            .type = type,
6346930ead5Smrg            .name = name,
6356930ead5Smrg            .body = body
6366930ead5Smrg        };
637f46a6179Smrg    }
638f46a6179Smrg    return doodad;
639f46a6179Smrg}
640f46a6179Smrg
641f46a6179SmrgExprDef *
64283e5f723SmrgAppendKeysymList(ExprDef * list, char *sym)
64334345a63Smrg{
64434345a63Smrg    if (list->value.list.nSyms >= list->value.list.szSyms)
64534345a63Smrg    {
64634345a63Smrg        list->value.list.szSyms *= 2;
6476930ead5Smrg        list->value.list.syms = recallocarray(list->value.list.syms,
6486930ead5Smrg                                              list->value.list.nSyms,
6496930ead5Smrg                                              list->value.list.szSyms,
6506930ead5Smrg                                              sizeof(char *));
65134345a63Smrg        if (list->value.list.syms == NULL)
65234345a63Smrg        {
65334345a63Smrg            FATAL("Couldn't resize list of symbols for append\n");
65434345a63Smrg            return NULL;
65534345a63Smrg        }
65634345a63Smrg    }
65734345a63Smrg    list->value.list.syms[list->value.list.nSyms++] = sym;
658f46a6179Smrg    return list;
659f46a6179Smrg}
660f46a6179Smrg
661f46a6179Smrgint
662690143ccSmrgLookupKeysym(const char *str, KeySym * sym_rtrn)
663f46a6179Smrg{
66434345a63Smrg    KeySym sym;
665f46a6179Smrg
66634345a63Smrg    if ((!str) || (uStrCaseCmp(str, "any") == 0)
66734345a63Smrg        || (uStrCaseCmp(str, "nosymbol") == 0))
66834345a63Smrg    {
66934345a63Smrg        *sym_rtrn = NoSymbol;
67034345a63Smrg        return 1;
671f46a6179Smrg    }
67234345a63Smrg    else if ((uStrCaseCmp(str, "none") == 0)
67334345a63Smrg             || (uStrCaseCmp(str, "voidsymbol") == 0))
67434345a63Smrg    {
67534345a63Smrg        *sym_rtrn = XK_VoidSymbol;
67634345a63Smrg        return 1;
677f46a6179Smrg    }
67834345a63Smrg    sym = XStringToKeysym(str);
67934345a63Smrg    if (sym != NoSymbol)
68034345a63Smrg    {
68134345a63Smrg        *sym_rtrn = sym;
68234345a63Smrg        return 1;
683f46a6179Smrg    }
68483e5f723Smrg    if (strlen(str) > 2 && str[0] == '0' && str[1] == 'x') {
6856930ead5Smrg        char *tmp;
6866930ead5Smrg
68783e5f723Smrg        sym = strtoul(str, &tmp, 16);
68883e5f723Smrg        if (sym != ULONG_MAX && (!tmp || *tmp == '\0')) {
68983e5f723Smrg            *sym_rtrn = sym;
69083e5f723Smrg            return 1;
69183e5f723Smrg        }
69283e5f723Smrg    }
693f46a6179Smrg    return 0;
694f46a6179Smrg}
695f46a6179Smrg
696f46a6179SmrgIncludeStmt *
69734345a63SmrgIncludeCreate(char *str, unsigned merge)
69834345a63Smrg{
69934345a63Smrg    IncludeStmt *incl, *first;
70034345a63Smrg    char *file, *map, *stmt, *tmp, *extra_data;
70134345a63Smrg    char nextop;
70234345a63Smrg    Bool haveSelf;
70334345a63Smrg
70434345a63Smrg    haveSelf = False;
70534345a63Smrg    incl = first = NULL;
70634345a63Smrg    file = map = NULL;
70734345a63Smrg    tmp = str;
70834345a63Smrg    stmt = uStringDup(str);
70934345a63Smrg    while ((tmp) && (*tmp))
71034345a63Smrg    {
71134345a63Smrg        if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
71234345a63Smrg        {
71334345a63Smrg            if ((file == NULL) && (map == NULL))
71434345a63Smrg            {
71534345a63Smrg                if (haveSelf)
71634345a63Smrg                    goto BAIL;
71734345a63Smrg                haveSelf = True;
71834345a63Smrg            }
71934345a63Smrg            if (first == NULL)
7206930ead5Smrg                first = incl = malloc(sizeof(IncludeStmt));
72134345a63Smrg            else
72234345a63Smrg            {
7236930ead5Smrg                incl->next = malloc(sizeof(IncludeStmt));
72434345a63Smrg                incl = incl->next;
72534345a63Smrg            }
72634345a63Smrg            if (incl)
72734345a63Smrg            {
7286930ead5Smrg                *incl = (IncludeStmt) {
7296930ead5Smrg                    .common.stmtType = StmtInclude,
7306930ead5Smrg                    .common.next = NULL,
7316930ead5Smrg                    .merge = merge,
7326930ead5Smrg                    .stmt = NULL,
7336930ead5Smrg                    .file = file,
7346930ead5Smrg                    .map = map,
7356930ead5Smrg                    .modifier = extra_data,
7366930ead5Smrg                    .path = NULL,
7376930ead5Smrg                    .next = NULL
7386930ead5Smrg                };
73934345a63Smrg            }
74034345a63Smrg            else
74134345a63Smrg            {
74234345a63Smrg                WSGO("Allocation failure in IncludeCreate\n");
74334345a63Smrg                ACTION("Using only part of the include\n");
74434345a63Smrg                break;
74534345a63Smrg            }
74634345a63Smrg            if (nextop == '|')
74734345a63Smrg                merge = MergeAugment;
74834345a63Smrg            else
74934345a63Smrg                merge = MergeOverride;
75034345a63Smrg        }
75134345a63Smrg        else
75234345a63Smrg        {
75334345a63Smrg            goto BAIL;
75434345a63Smrg        }
75534345a63Smrg    }
75634345a63Smrg    if (first)
75734345a63Smrg        first->stmt = stmt;
75834345a63Smrg    else if (stmt)
7596930ead5Smrg        free(stmt);
760f46a6179Smrg    return first;
76134345a63Smrg  BAIL:
762bfe6082cSmrg    ERROR("Illegal include statement \"%s\"\n", stmt);
763f46a6179Smrg    ACTION("Ignored\n");
76434345a63Smrg    while (first)
76534345a63Smrg    {
76634345a63Smrg        incl = first->next;
7676930ead5Smrg        free(first->file);
7686930ead5Smrg        free(first->map);
7696930ead5Smrg        free(first->modifier);
7706930ead5Smrg        free(first->path);
7716930ead5Smrg        first->file = first->map = first->modifier = first->path = NULL;
7726930ead5Smrg        free(first);
77334345a63Smrg        first = incl;
774f46a6179Smrg    }
775f46a6179Smrg    if (stmt)
7766930ead5Smrg        free(stmt);
777f46a6179Smrg    return NULL;
778f46a6179Smrg}
779f46a6179Smrg
780f46a6179Smrg#ifdef DEBUG
781f46a6179Smrgvoid
78234345a63SmrgPrintStmtAddrs(ParseCommon * stmt)
783f46a6179Smrg{
7841d8c7986Smrg    fprintf(stderr, "%p", stmt);
78534345a63Smrg    if (stmt)
78634345a63Smrg    {
78734345a63Smrg        do
78834345a63Smrg        {
7891d8c7986Smrg            fprintf(stderr, "->%p", stmt->next);
79034345a63Smrg            stmt = stmt->next;
79134345a63Smrg        }
79234345a63Smrg        while (stmt);
793f46a6179Smrg    }
79434345a63Smrg    fprintf(stderr, "\n");
795f46a6179Smrg}
796f46a6179Smrg#endif
797f46a6179Smrg
798f46a6179Smrgstatic void
79934345a63SmrgCheckDefaultMap(XkbFile * maps)
80034345a63Smrg{
8016930ead5Smrg    XkbFile *dflt = NULL;
80234345a63Smrg
8036930ead5Smrg    for (XkbFile *tmp = maps; tmp != NULL;
80434345a63Smrg         tmp = (XkbFile *) tmp->common.next)
80534345a63Smrg    {
80634345a63Smrg        if (tmp->flags & XkbLC_Default)
80734345a63Smrg        {
80834345a63Smrg            if (dflt == NULL)
80934345a63Smrg                dflt = tmp;
81034345a63Smrg            else
81134345a63Smrg            {
81234345a63Smrg                if (warningLevel > 2)
81334345a63Smrg                {
814bfe6082cSmrg                    WARN("Multiple default components in %s\n",
81534345a63Smrg                          (scanFile ? scanFile : "(unknown)"));
816bfe6082cSmrg                    ACTION("Using %s, ignoring %s\n",
81734345a63Smrg                            (dflt->name ? dflt->name : "(first)"),
81834345a63Smrg                            (tmp->name ? tmp->name : "(subsequent)"));
81934345a63Smrg                }
82034345a63Smrg                tmp->flags &= (~XkbLC_Default);
82134345a63Smrg            }
82234345a63Smrg        }
823f46a6179Smrg    }
824f46a6179Smrg    return;
825f46a6179Smrg}
826f46a6179Smrg
827f46a6179Smrgint
82834345a63SmrgXKBParseFile(FILE * file, XkbFile ** pRtrn)
82934345a63Smrg{
83034345a63Smrg    if (file)
83134345a63Smrg    {
832c82dfdfbSmrg        scan_set_file(file);
83334345a63Smrg        rtrnValue = NULL;
83434345a63Smrg        if (yyparse() == 0)
83534345a63Smrg        {
83634345a63Smrg            *pRtrn = rtrnValue;
83734345a63Smrg            CheckDefaultMap(rtrnValue);
83834345a63Smrg            rtrnValue = NULL;
83934345a63Smrg            return 1;
84034345a63Smrg        }
84134345a63Smrg        *pRtrn = NULL;
84234345a63Smrg        return 0;
84334345a63Smrg    }
84434345a63Smrg    *pRtrn = NULL;
845f46a6179Smrg    return 1;
846f46a6179Smrg}
847f46a6179Smrg
848f46a6179SmrgXkbFile *
84934345a63SmrgCreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
85034345a63Smrg{
85134345a63Smrg    XkbFile *file;
85234345a63Smrg    static int fileID;
85334345a63Smrg
8546930ead5Smrg    file = calloc(1, sizeof(XkbFile));
85534345a63Smrg    if (file)
85634345a63Smrg    {
85734345a63Smrg        XkbEnsureSafeMapName(name);
8586930ead5Smrg        *file = (XkbFile) {
8596930ead5Smrg            .type = type,
8606930ead5Smrg            .topName = uStringDup(name),
8616930ead5Smrg            .name = name,
8626930ead5Smrg            .defs = defs,
8636930ead5Smrg            .id = fileID++,
8646930ead5Smrg            .compiled = False,
8656930ead5Smrg            .flags = flags
8666930ead5Smrg        };
867f46a6179Smrg    }
868f46a6179Smrg    return file;
869f46a6179Smrg}
870f46a6179Smrg
87134345a63Smrgunsigned
87234345a63SmrgStmtSetMerge(ParseCommon * stmt, unsigned merge)
873f46a6179Smrg{
87434345a63Smrg    if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
87534345a63Smrg    {
87634345a63Smrg        yyerror("illegal use of 'alternate' merge mode");
87734345a63Smrg        merge = MergeDefault;
878f46a6179Smrg    }
879f46a6179Smrg    return merge;
880f46a6179Smrg}
881