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