parseutils.c revision f46a6179
1f46a6179Smrg/* $Xorg: parseutils.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */
2f46a6179Smrg/************************************************************
3f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4f46a6179Smrg
5f46a6179Smrg Permission to use, copy, modify, and distribute this
6f46a6179Smrg software and its documentation for any purpose and without
7f46a6179Smrg fee is hereby granted, provided that the above copyright
8f46a6179Smrg notice appear in all copies and that both that copyright
9f46a6179Smrg notice and this permission notice appear in supporting
10f46a6179Smrg documentation, and that the name of Silicon Graphics not be
11f46a6179Smrg used in advertising or publicity pertaining to distribution
12f46a6179Smrg of the software without specific prior written permission.
13f46a6179Smrg Silicon Graphics makes no representation about the suitability
14f46a6179Smrg of this software for any purpose. It is provided "as is"
15f46a6179Smrg without any express or implied warranty.
16f46a6179Smrg
17f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
24f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
25f46a6179Smrg
26f46a6179Smrg ********************************************************/
27f46a6179Smrg/* $XFree86$ */
28f46a6179Smrg
29f46a6179Smrg#define DEBUG_VAR_NOT_LOCAL
30f46a6179Smrg#define	DEBUG_VAR parseDebug
31f46a6179Smrg#include "parseutils.h"
32f46a6179Smrg#include "xkbpath.h"
33f46a6179Smrg#include <X11/keysym.h>
34f46a6179Smrg#include <X11/extensions/XKBgeom.h>
35f46a6179Smrg#include <X11/Xalloca.h>
36f46a6179Smrg
37f46a6179SmrgXkbFile	*rtrnValue;
38f46a6179Smrg
39f46a6179SmrgParseCommon *
40f46a6179SmrgAppendStmt(ParseCommon *to,ParseCommon *append)
41f46a6179Smrg{
42f46a6179SmrgParseCommon	*start= to;
43f46a6179Smrg
44f46a6179Smrg    if (append==NULL)
45f46a6179Smrg	return to;
46f46a6179Smrg    while ((to!=NULL) && (to->next!=NULL)) {
47f46a6179Smrg	to= to->next;
48f46a6179Smrg    }
49f46a6179Smrg    if (to) {
50f46a6179Smrg	to->next= append;
51f46a6179Smrg	return start;
52f46a6179Smrg    }
53f46a6179Smrg    return append;
54f46a6179Smrg}
55f46a6179Smrg
56f46a6179SmrgExprDef *
57f46a6179SmrgExprCreate(unsigned op,unsigned type)
58f46a6179Smrg{
59f46a6179SmrgExprDef *expr;
60f46a6179Smrg    expr= uTypedAlloc(ExprDef);
61f46a6179Smrg    if (expr) {
62f46a6179Smrg	expr->common.stmtType= StmtExpr;
63f46a6179Smrg	expr->common.next= NULL;
64f46a6179Smrg	expr->op= op;
65f46a6179Smrg	expr->type= type;
66f46a6179Smrg    }
67f46a6179Smrg    else {
68f46a6179Smrg	FATAL("Couldn't allocate expression in parser\n");
69f46a6179Smrg	/* NOTREACHED */
70f46a6179Smrg    }
71f46a6179Smrg    return expr;
72f46a6179Smrg}
73f46a6179Smrg
74f46a6179SmrgExprDef *
75f46a6179SmrgExprCreateUnary(unsigned op,unsigned type,ExprDef *child)
76f46a6179Smrg{
77f46a6179SmrgExprDef *expr;
78f46a6179Smrg    expr= uTypedAlloc(ExprDef);
79f46a6179Smrg    if (expr) {
80f46a6179Smrg	expr->common.stmtType= StmtExpr;
81f46a6179Smrg	expr->common.next= NULL;
82f46a6179Smrg	expr->op= op;
83f46a6179Smrg	expr->type= type;
84f46a6179Smrg	expr->value.child= child;
85f46a6179Smrg    }
86f46a6179Smrg    else {
87f46a6179Smrg	FATAL("Couldn't allocate expression in parser\n");
88f46a6179Smrg	/* NOTREACHED */
89f46a6179Smrg    }
90f46a6179Smrg    return expr;
91f46a6179Smrg}
92f46a6179Smrg
93f46a6179SmrgExprDef *
94f46a6179SmrgExprCreateBinary(unsigned op,ExprDef *left,ExprDef *right)
95f46a6179Smrg{
96f46a6179SmrgExprDef *expr;
97f46a6179Smrg    expr= uTypedAlloc(ExprDef);
98f46a6179Smrg    if (expr) {
99f46a6179Smrg	expr->common.stmtType= StmtExpr;
100f46a6179Smrg	expr->common.next= NULL;
101f46a6179Smrg	expr->op= op;
102f46a6179Smrg	if ((op==OpAssign)||(left->type==TypeUnknown))
103f46a6179Smrg	     expr->type= right->type;
104f46a6179Smrg	else if ((left->type==right->type)||(right->type==TypeUnknown))
105f46a6179Smrg	     expr->type= left->type;
106f46a6179Smrg	else expr->type= TypeUnknown;
107f46a6179Smrg	expr->value.binary.left= left;
108f46a6179Smrg	expr->value.binary.right= right;
109f46a6179Smrg    }
110f46a6179Smrg    else {
111f46a6179Smrg	FATAL("Couldn't allocate expression in parser\n");
112f46a6179Smrg	/* NOTREACHED */
113f46a6179Smrg    }
114f46a6179Smrg    return expr;
115f46a6179Smrg}
116f46a6179Smrg
117f46a6179SmrgKeycodeDef *
118f46a6179SmrgKeycodeCreate(char *name,ExprDef *value)
119f46a6179Smrg{
120f46a6179SmrgKeycodeDef *def;
121f46a6179Smrg
122f46a6179Smrg    def= uTypedAlloc(KeycodeDef);
123f46a6179Smrg    if (def) {
124f46a6179Smrg	def->common.stmtType= StmtKeycodeDef;
125f46a6179Smrg	def->common.next= NULL;
126f46a6179Smrg	strncpy(def->name,name,XkbKeyNameLength);
127f46a6179Smrg	def->name[XkbKeyNameLength]= '\0';
128f46a6179Smrg	def->value= value;
129f46a6179Smrg    }
130f46a6179Smrg    else {
131f46a6179Smrg	FATAL("Couldn't allocate key name definition in parser\n");
132f46a6179Smrg	/* NOTREACHED */
133f46a6179Smrg    }
134f46a6179Smrg    return def;
135f46a6179Smrg}
136f46a6179Smrg
137f46a6179SmrgKeyAliasDef *
138f46a6179SmrgKeyAliasCreate(char *alias,char *real)
139f46a6179Smrg{
140f46a6179SmrgKeyAliasDef *def;
141f46a6179Smrg
142f46a6179Smrg    def= uTypedAlloc(KeyAliasDef);
143f46a6179Smrg    if (def) {
144f46a6179Smrg	def->common.stmtType= StmtKeyAliasDef;
145f46a6179Smrg	def->common.next= NULL;
146f46a6179Smrg	strncpy(def->alias,alias,XkbKeyNameLength);
147f46a6179Smrg	def->alias[XkbKeyNameLength]= '\0';
148f46a6179Smrg	strncpy(def->real,real,XkbKeyNameLength);
149f46a6179Smrg	def->real[XkbKeyNameLength]= '\0';
150f46a6179Smrg    }
151f46a6179Smrg    else {
152f46a6179Smrg	FATAL("Couldn't allocate key alias definition in parser\n");
153f46a6179Smrg	/* NOTREACHED */
154f46a6179Smrg    }
155f46a6179Smrg    return def;
156f46a6179Smrg}
157f46a6179Smrg
158f46a6179SmrgVModDef *
159f46a6179SmrgVModCreate(Atom name,ExprDef *value)
160f46a6179Smrg{
161f46a6179SmrgVModDef *def;
162f46a6179Smrg    def= uTypedAlloc(VModDef);
163f46a6179Smrg    if (def) {
164f46a6179Smrg	def->common.stmtType= StmtVModDef;
165f46a6179Smrg	def->common.next= NULL;
166f46a6179Smrg	def->name= name;
167f46a6179Smrg	def->value= value;
168f46a6179Smrg    }
169f46a6179Smrg    else {
170f46a6179Smrg	FATAL("Couldn't allocate variable definition in parser\n");
171f46a6179Smrg	/* NOTREACHED */
172f46a6179Smrg    }
173f46a6179Smrg    return def;
174f46a6179Smrg}
175f46a6179Smrg
176f46a6179SmrgVarDef *
177f46a6179SmrgVarCreate(ExprDef *name,ExprDef *value)
178f46a6179Smrg{
179f46a6179SmrgVarDef *def;
180f46a6179Smrg    def= uTypedAlloc(VarDef);
181f46a6179Smrg    if (def) {
182f46a6179Smrg	def->common.stmtType= StmtVarDef;
183f46a6179Smrg	def->common.next= NULL;
184f46a6179Smrg	def->name= name;
185f46a6179Smrg	def->value= value;
186f46a6179Smrg    }
187f46a6179Smrg    else {
188f46a6179Smrg	FATAL("Couldn't allocate variable definition in parser\n");
189f46a6179Smrg	/* NOTREACHED */
190f46a6179Smrg    }
191f46a6179Smrg    return def;
192f46a6179Smrg}
193f46a6179Smrg
194f46a6179SmrgVarDef *
195f46a6179SmrgBoolVarCreate(Atom nameToken,unsigned set)
196f46a6179Smrg{
197f46a6179SmrgExprDef	*name,*value;
198f46a6179Smrg
199f46a6179Smrg    name= ExprCreate(ExprIdent,TypeUnknown);
200f46a6179Smrg    name->value.str= nameToken;
201f46a6179Smrg    value= ExprCreate(ExprValue,TypeBoolean);
202f46a6179Smrg    value->value.uval= set;
203f46a6179Smrg    return VarCreate(name,value);
204f46a6179Smrg}
205f46a6179Smrg
206f46a6179SmrgInterpDef *
207f46a6179SmrgInterpCreate(KeySym sym,ExprDef *match)
208f46a6179Smrg{
209f46a6179SmrgInterpDef *def;
210f46a6179Smrg
211f46a6179Smrg    def= uTypedAlloc(InterpDef);
212f46a6179Smrg    if (def) {
213f46a6179Smrg	def->common.stmtType= StmtInterpDef;
214f46a6179Smrg	def->common.next= NULL;
215f46a6179Smrg	def->sym= sym;
216f46a6179Smrg	def->match= match;
217f46a6179Smrg    }
218f46a6179Smrg    else {
219f46a6179Smrg	FATAL("Couldn't allocate interp definition in parser\n");
220f46a6179Smrg	/* NOTREACHED */
221f46a6179Smrg    }
222f46a6179Smrg    return def;
223f46a6179Smrg}
224f46a6179Smrg
225f46a6179SmrgKeyTypeDef *
226f46a6179SmrgKeyTypeCreate(Atom name,VarDef *body)
227f46a6179Smrg{
228f46a6179SmrgKeyTypeDef *def;
229f46a6179Smrg
230f46a6179Smrg    def= uTypedAlloc(KeyTypeDef);
231f46a6179Smrg    if (def) {
232f46a6179Smrg	def->common.stmtType= StmtKeyTypeDef;
233f46a6179Smrg	def->common.next= NULL;
234f46a6179Smrg	def->merge= MergeDefault;
235f46a6179Smrg	def->name= name;
236f46a6179Smrg	def->body= body;
237f46a6179Smrg    }
238f46a6179Smrg    else {
239f46a6179Smrg	FATAL("Couldn't allocate key type definition in parser\n");
240f46a6179Smrg	/* NOTREACHED */
241f46a6179Smrg    }
242f46a6179Smrg    return def;
243f46a6179Smrg}
244f46a6179Smrg
245f46a6179SmrgSymbolsDef *
246f46a6179SmrgSymbolsCreate(char *keyName,ExprDef *symbols)
247f46a6179Smrg{
248f46a6179SmrgSymbolsDef *def;
249f46a6179Smrg
250f46a6179Smrg    def= uTypedAlloc(SymbolsDef);
251f46a6179Smrg    if (def) {
252f46a6179Smrg	def->common.stmtType= StmtSymbolsDef;
253f46a6179Smrg	def->common.next= NULL;
254f46a6179Smrg	def->merge= MergeDefault;
255f46a6179Smrg	bzero(def->keyName,5);
256f46a6179Smrg	strncpy(def->keyName,keyName,4);
257f46a6179Smrg	def->symbols= symbols;
258f46a6179Smrg    }
259f46a6179Smrg    else {
260f46a6179Smrg	FATAL("Couldn't allocate symbols definition in parser\n");
261f46a6179Smrg	/* NOTREACHED */
262f46a6179Smrg    }
263f46a6179Smrg    return def;
264f46a6179Smrg}
265f46a6179Smrg
266f46a6179SmrgGroupCompatDef *
267f46a6179SmrgGroupCompatCreate(int group,ExprDef *val)
268f46a6179Smrg{
269f46a6179SmrgGroupCompatDef *def;
270f46a6179Smrg
271f46a6179Smrg    def= uTypedAlloc(GroupCompatDef);
272f46a6179Smrg    if (def) {
273f46a6179Smrg	def->common.stmtType= StmtGroupCompatDef;
274f46a6179Smrg	def->common.next= NULL;
275f46a6179Smrg	def->merge= MergeDefault;
276f46a6179Smrg	def->group= group;
277f46a6179Smrg	def->def= val;
278f46a6179Smrg    }
279f46a6179Smrg    else {
280f46a6179Smrg	FATAL("Couldn't allocate group compat definition in parser\n");
281f46a6179Smrg	/* NOTREACHED */
282f46a6179Smrg    }
283f46a6179Smrg    return def;
284f46a6179Smrg}
285f46a6179Smrg
286f46a6179SmrgModMapDef *
287f46a6179SmrgModMapCreate(Atom modifier,ExprDef *keys)
288f46a6179Smrg{
289f46a6179SmrgModMapDef *def;
290f46a6179Smrg
291f46a6179Smrg    def= uTypedAlloc(ModMapDef);
292f46a6179Smrg    if (def) {
293f46a6179Smrg	def->common.stmtType= StmtModMapDef;
294f46a6179Smrg	def->common.next= NULL;
295f46a6179Smrg	def->merge= MergeDefault;
296f46a6179Smrg	def->modifier= modifier;
297f46a6179Smrg	def->keys= keys;
298f46a6179Smrg    }
299f46a6179Smrg    else {
300f46a6179Smrg	FATAL("Couldn't allocate mod mask definition in parser\n");
301f46a6179Smrg	/* NOTREACHED */
302f46a6179Smrg    }
303f46a6179Smrg    return def;
304f46a6179Smrg}
305f46a6179Smrg
306f46a6179SmrgIndicatorMapDef *
307f46a6179SmrgIndicatorMapCreate(Atom name,VarDef *body)
308f46a6179Smrg{
309f46a6179SmrgIndicatorMapDef *def;
310f46a6179Smrg
311f46a6179Smrg    def= uTypedAlloc(IndicatorMapDef);
312f46a6179Smrg    if (def) {
313f46a6179Smrg	def->common.stmtType= StmtIndicatorMapDef;
314f46a6179Smrg	def->common.next= NULL;
315f46a6179Smrg	def->merge= MergeDefault;
316f46a6179Smrg	def->name= name;
317f46a6179Smrg	def->body= body;
318f46a6179Smrg    }
319f46a6179Smrg    else {
320f46a6179Smrg	FATAL("Couldn't allocate indicator map definition in parser\n");
321f46a6179Smrg	/* NOTREACHED */
322f46a6179Smrg    }
323f46a6179Smrg    return def;
324f46a6179Smrg}
325f46a6179Smrg
326f46a6179SmrgIndicatorNameDef *
327f46a6179SmrgIndicatorNameCreate(int	ndx,ExprDef *name,Bool virtual)
328f46a6179Smrg{
329f46a6179SmrgIndicatorNameDef *def;
330f46a6179Smrg
331f46a6179Smrg    def= uTypedAlloc(IndicatorNameDef);
332f46a6179Smrg    if (def) {
333f46a6179Smrg	def->common.stmtType= StmtIndicatorNameDef;
334f46a6179Smrg	def->common.next= NULL;
335f46a6179Smrg	def->merge= MergeDefault;
336f46a6179Smrg	def->ndx= ndx;
337f46a6179Smrg	def->name= name;
338f46a6179Smrg	def->virtual= virtual;
339f46a6179Smrg    }
340f46a6179Smrg    else {
341f46a6179Smrg	FATAL("Couldn't allocate indicator index definition in parser\n");
342f46a6179Smrg	/* NOTREACHED */
343f46a6179Smrg    }
344f46a6179Smrg    return def;
345f46a6179Smrg}
346f46a6179Smrg
347f46a6179SmrgExprDef *
348f46a6179SmrgActionCreate(Atom name,ExprDef *args)
349f46a6179Smrg{
350f46a6179SmrgExprDef *act;
351f46a6179Smrg
352f46a6179Smrg    act= uTypedAlloc(ExprDef);
353f46a6179Smrg    if (act) {
354f46a6179Smrg	act->common.stmtType= StmtExpr;
355f46a6179Smrg	act->common.next= NULL;
356f46a6179Smrg	act->op= ExprActionDecl;
357f46a6179Smrg	act->value.action.name= name;
358f46a6179Smrg        act->value.action.args= args;
359f46a6179Smrg	return act;
360f46a6179Smrg    }
361f46a6179Smrg    FATAL("Couldn't allocate ActionDef in parser\n");
362f46a6179Smrg    return NULL;
363f46a6179Smrg}
364f46a6179Smrg
365f46a6179SmrgExprDef *
366f46a6179SmrgCreateKeysymList(KeySym sym)
367f46a6179Smrg{
368f46a6179SmrgExprDef	 *def;
369f46a6179Smrg
370f46a6179Smrg    def= ExprCreate(ExprKeysymList,TypeSymbols);
371f46a6179Smrg    if (def) {
372f46a6179Smrg	def->value.list.nSyms= 1;
373f46a6179Smrg	def->value.list.szSyms= 2;
374f46a6179Smrg	def->value.list.syms= uTypedCalloc(2,KeySym);
375f46a6179Smrg	if (def->value.list.syms!=NULL) {
376f46a6179Smrg	    def->value.list.syms[0]= sym;
377f46a6179Smrg	    return def;
378f46a6179Smrg	}
379f46a6179Smrg    }
380f46a6179Smrg    FATAL("Couldn't allocate expression for keysym list in parser\n");
381f46a6179Smrg    return NULL;
382f46a6179Smrg}
383f46a6179Smrg
384f46a6179SmrgShapeDef *
385f46a6179SmrgShapeDeclCreate(Atom name,OutlineDef *outlines)
386f46a6179Smrg{
387f46a6179SmrgShapeDef *	shape;
388f46a6179SmrgOutlineDef *	ol;
389f46a6179Smrg
390f46a6179Smrg    shape= uTypedAlloc(ShapeDef);
391f46a6179Smrg    if (shape!=NULL) {
392f46a6179Smrg	bzero(shape,sizeof(ShapeDef));
393f46a6179Smrg	shape->common.stmtType=	StmtShapeDef;
394f46a6179Smrg	shape->common.next=	NULL;
395f46a6179Smrg	shape->merge=		MergeDefault;
396f46a6179Smrg	shape->name=		name;
397f46a6179Smrg	shape->nOutlines=	0;
398f46a6179Smrg	shape->outlines=	outlines;
399f46a6179Smrg	for (ol=outlines;ol!=NULL;ol= (OutlineDef *)ol->common.next) {
400f46a6179Smrg	    if (ol->nPoints>0)
401f46a6179Smrg		shape->nOutlines++;
402f46a6179Smrg	}
403f46a6179Smrg    }
404f46a6179Smrg    return shape;
405f46a6179Smrg}
406f46a6179Smrg
407f46a6179SmrgOutlineDef *
408f46a6179SmrgOutlineCreate(Atom field,ExprDef *points)
409f46a6179Smrg{
410f46a6179SmrgOutlineDef *	outline;
411f46a6179SmrgExprDef *	pt;
412f46a6179Smrg
413f46a6179Smrg    outline= uTypedAlloc(OutlineDef);
414f46a6179Smrg    if (outline!=NULL) {
415f46a6179Smrg	bzero(outline,sizeof(OutlineDef));
416f46a6179Smrg	outline->common.stmtType= 	StmtOutlineDef;
417f46a6179Smrg	outline->common.next=		NULL;
418f46a6179Smrg	outline->field=		field;
419f46a6179Smrg	outline->nPoints=	0;
420f46a6179Smrg	if (points->op==ExprCoord) {
421f46a6179Smrg	    for (pt=points;pt!=NULL;pt= (ExprDef *)pt->common.next) {
422f46a6179Smrg		outline->nPoints++;
423f46a6179Smrg	    }
424f46a6179Smrg	}
425f46a6179Smrg	outline->points= points;
426f46a6179Smrg    }
427f46a6179Smrg    return outline;
428f46a6179Smrg}
429f46a6179Smrg
430f46a6179SmrgKeyDef *
431f46a6179SmrgKeyDeclCreate(char *name,ExprDef *expr)
432f46a6179Smrg{
433f46a6179SmrgKeyDef *	key;
434f46a6179Smrg
435f46a6179Smrg    key= uTypedAlloc(KeyDef);
436f46a6179Smrg    if (key!=NULL) {
437f46a6179Smrg	bzero(key,sizeof(KeyDef));
438f46a6179Smrg	key->common.stmtType= StmtKeyDef;
439f46a6179Smrg	key->common.next= NULL;
440f46a6179Smrg	if (name)	key->name= name;
441f46a6179Smrg	else		key->expr= expr;
442f46a6179Smrg    }
443f46a6179Smrg    return key;
444f46a6179Smrg}
445f46a6179Smrg
446f46a6179SmrgKeyDef *
447f46a6179SmrgKeyDeclMerge(KeyDef *into,KeyDef *from)
448f46a6179Smrg{
449f46a6179Smrg    into->expr= (ExprDef *)AppendStmt(&into->expr->common,&from->expr->common);
450f46a6179Smrg    from->expr= NULL;
451f46a6179Smrg    uFree(from);
452f46a6179Smrg    return into;
453f46a6179Smrg}
454f46a6179Smrg
455f46a6179SmrgRowDef *
456f46a6179SmrgRowDeclCreate(KeyDef *	keys)
457f46a6179Smrg{
458f46a6179SmrgRowDef *	row;
459f46a6179SmrgKeyDef *	key;
460f46a6179Smrg
461f46a6179Smrg    row= uTypedAlloc(RowDef);
462f46a6179Smrg    if (row!=NULL) {
463f46a6179Smrg	bzero(row,sizeof(RowDef));
464f46a6179Smrg	row->common.stmtType= StmtRowDef;
465f46a6179Smrg	row->common.next= NULL;
466f46a6179Smrg	row->nKeys= 0;
467f46a6179Smrg	row->keys= keys;
468f46a6179Smrg	for (key=keys;key!=NULL;key=(KeyDef *)key->common.next) {
469f46a6179Smrg	    if (key->common.stmtType==StmtKeyDef)
470f46a6179Smrg		row->nKeys++;
471f46a6179Smrg	}
472f46a6179Smrg    }
473f46a6179Smrg    return row;
474f46a6179Smrg}
475f46a6179Smrg
476f46a6179SmrgSectionDef *
477f46a6179SmrgSectionDeclCreate(Atom name,RowDef *rows)
478f46a6179Smrg{
479f46a6179SmrgSectionDef *	section;
480f46a6179SmrgRowDef *	row;
481f46a6179Smrg
482f46a6179Smrg    section= uTypedAlloc(SectionDef);
483f46a6179Smrg    if (section!=NULL) {
484f46a6179Smrg	bzero(section,sizeof(SectionDef));
485f46a6179Smrg	section->common.stmtType= StmtSectionDef;
486f46a6179Smrg	section->common.next= NULL;
487f46a6179Smrg	section->name= name;
488f46a6179Smrg	section->nRows= 0;
489f46a6179Smrg	section->rows= rows;
490f46a6179Smrg	for (row=rows;row!=NULL;row=(RowDef *)row->common.next) {
491f46a6179Smrg	    if (row->common.stmtType==StmtRowDef)
492f46a6179Smrg		section->nRows++;
493f46a6179Smrg	}
494f46a6179Smrg    }
495f46a6179Smrg    return section;
496f46a6179Smrg}
497f46a6179Smrg
498f46a6179SmrgOverlayKeyDef *
499f46a6179SmrgOverlayKeyCreate(char *	under,char *over)
500f46a6179Smrg{
501f46a6179SmrgOverlayKeyDef *	key;
502f46a6179Smrg
503f46a6179Smrg    key= uTypedAlloc(OverlayKeyDef);
504f46a6179Smrg    if (key!=NULL) {
505f46a6179Smrg	bzero(key,sizeof(OverlayKeyDef));
506f46a6179Smrg	key->common.stmtType= StmtOverlayKeyDef;
507f46a6179Smrg	strncpy(key->over,over,XkbKeyNameLength);
508f46a6179Smrg	strncpy(key->under,under,XkbKeyNameLength);
509f46a6179Smrg	if (over)	uFree(over);
510f46a6179Smrg	if (under)	uFree(under);
511f46a6179Smrg    }
512f46a6179Smrg    return key;
513f46a6179Smrg}
514f46a6179Smrg
515f46a6179SmrgOverlayDef *
516f46a6179SmrgOverlayDeclCreate(Atom name,OverlayKeyDef *keys)
517f46a6179Smrg{
518f46a6179SmrgOverlayDef *	ol;
519f46a6179SmrgOverlayKeyDef *	key;
520f46a6179Smrg
521f46a6179Smrg    ol= uTypedAlloc(OverlayDef);
522f46a6179Smrg    if (ol!=NULL) {
523f46a6179Smrg	bzero(ol,sizeof(OverlayDef));
524f46a6179Smrg	ol->common.stmtType= 	StmtOverlayDef;
525f46a6179Smrg	ol->name=		name;
526f46a6179Smrg	ol->keys=		keys;
527f46a6179Smrg	for (key=keys;key!=NULL;key=(OverlayKeyDef *)key->common.next) {
528f46a6179Smrg	    ol->nKeys++;
529f46a6179Smrg	}
530f46a6179Smrg    }
531f46a6179Smrg    return ol;
532f46a6179Smrg}
533f46a6179Smrg
534f46a6179SmrgDoodadDef *
535f46a6179SmrgDoodadCreate(unsigned type,Atom name,VarDef *body)
536f46a6179Smrg{
537f46a6179SmrgDoodadDef *	doodad;
538f46a6179Smrg
539f46a6179Smrg    doodad= uTypedAlloc(DoodadDef);
540f46a6179Smrg    if (doodad!=NULL) {
541f46a6179Smrg	bzero(doodad,sizeof(DoodadDef));
542f46a6179Smrg	doodad->common.stmtType= StmtDoodadDef;
543f46a6179Smrg	doodad->common.next= NULL;
544f46a6179Smrg	doodad->type= type;
545f46a6179Smrg	doodad->name= name;
546f46a6179Smrg	doodad->body= body;
547f46a6179Smrg    }
548f46a6179Smrg    return doodad;
549f46a6179Smrg}
550f46a6179Smrg
551f46a6179SmrgExprDef *
552f46a6179SmrgAppendKeysymList(ExprDef *list,KeySym sym)
553f46a6179Smrg{
554f46a6179Smrg    if (list->value.list.nSyms>=list->value.list.szSyms) {
555f46a6179Smrg	list->value.list.szSyms*=2;
556f46a6179Smrg	list->value.list.syms= uTypedRecalloc(list->value.list.syms,
557f46a6179Smrg						list->value.list.nSyms,
558f46a6179Smrg						list->value.list.szSyms,
559f46a6179Smrg						KeySym);
560f46a6179Smrg	if (list->value.list.syms==NULL) {
561f46a6179Smrg	    FATAL("Couldn't resize list of symbols for append\n");
562f46a6179Smrg	    return NULL;
563f46a6179Smrg	}
564f46a6179Smrg    }
565f46a6179Smrg    list->value.list.syms[list->value.list.nSyms++]= sym;
566f46a6179Smrg    return list;
567f46a6179Smrg}
568f46a6179Smrg
569f46a6179Smrgint
570f46a6179SmrgLookupKeysym(char *str,KeySym *sym_rtrn)
571f46a6179Smrg{
572f46a6179SmrgKeySym sym;
573f46a6179Smrg
574f46a6179Smrg    if ((!str)||(uStrCaseCmp(str,"any")==0)||(uStrCaseCmp(str,"nosymbol")==0)) {
575f46a6179Smrg	*sym_rtrn= NoSymbol;
576f46a6179Smrg	return 1;
577f46a6179Smrg    }
578f46a6179Smrg    else if ((uStrCaseCmp(str,"none")==0)||(uStrCaseCmp(str,"voidsymbol")==0)) {
579f46a6179Smrg	*sym_rtrn= XK_VoidSymbol;
580f46a6179Smrg	return 1;
581f46a6179Smrg    }
582f46a6179Smrg    sym= XStringToKeysym(str);
583f46a6179Smrg    if (sym!=NoSymbol) {
584f46a6179Smrg	*sym_rtrn= sym;
585f46a6179Smrg	return 1;
586f46a6179Smrg    }
587f46a6179Smrg    return 0;
588f46a6179Smrg}
589f46a6179Smrg
590f46a6179SmrgIncludeStmt *
591f46a6179SmrgIncludeCreate(char *str,unsigned merge)
592f46a6179Smrg{
593f46a6179SmrgIncludeStmt *	incl,*first;
594f46a6179Smrgchar *		file,*map,*stmt,*tmp, *extra_data;
595f46a6179Smrgchar 		nextop;
596f46a6179SmrgBool		haveSelf;
597f46a6179Smrg
598f46a6179Smrg    haveSelf= False;
599f46a6179Smrg    incl= first= NULL;
600f46a6179Smrg    file= map= NULL;
601f46a6179Smrg    tmp= str;
602f46a6179Smrg    stmt= uStringDup(str);
603f46a6179Smrg    while ((tmp)&&(*tmp)) {
604f46a6179Smrg	if (XkbParseIncludeMap(&tmp,&file,&map,&nextop,&extra_data)) {
605f46a6179Smrg	    if ((file==NULL)&&(map==NULL)) {
606f46a6179Smrg		if (haveSelf)
607f46a6179Smrg		    goto BAIL;
608f46a6179Smrg		haveSelf= True;
609f46a6179Smrg	    }
610f46a6179Smrg	    if (first==NULL)
611f46a6179Smrg		first= incl= uTypedAlloc(IncludeStmt);
612f46a6179Smrg	    else {
613f46a6179Smrg		incl->next= uTypedAlloc(IncludeStmt);
614f46a6179Smrg		incl= incl->next;
615f46a6179Smrg	    }
616f46a6179Smrg	    if (incl) {
617f46a6179Smrg		incl->common.stmtType= StmtInclude;
618f46a6179Smrg		incl->common.next= NULL;
619f46a6179Smrg		incl->merge= merge;
620f46a6179Smrg		incl->stmt= NULL;
621f46a6179Smrg		incl->file= file;
622f46a6179Smrg		incl->map= map;
623f46a6179Smrg		incl->modifier= extra_data;
624f46a6179Smrg		incl->path= NULL;
625f46a6179Smrg		incl->next= NULL;
626f46a6179Smrg	    }
627f46a6179Smrg	    else {
628f46a6179Smrg		WSGO("Allocation failure in IncludeCreate\n");
629f46a6179Smrg		ACTION("Using only part of the include\n");
630f46a6179Smrg		break;
631f46a6179Smrg	    }
632f46a6179Smrg	    if (nextop=='|')	merge= MergeAugment;
633f46a6179Smrg	    else		merge= MergeOverride;
634f46a6179Smrg	}
635f46a6179Smrg	else {
636f46a6179Smrg	    goto BAIL;
637f46a6179Smrg	}
638f46a6179Smrg    }
639f46a6179Smrg    if (first)		first->stmt= stmt;
640f46a6179Smrg    else if (stmt)	uFree(stmt);
641f46a6179Smrg    return first;
642f46a6179SmrgBAIL:
643f46a6179Smrg    ERROR1("Illegal include statement \"%s\"\n",stmt);
644f46a6179Smrg    ACTION("Ignored\n");
645f46a6179Smrg    while (first) {
646f46a6179Smrg	incl= first->next;
647f46a6179Smrg	if (first->file) uFree(first->file);
648f46a6179Smrg	if (first->map) uFree(first->map);
649f46a6179Smrg	if (first->modifier) uFree(first->modifier);
650f46a6179Smrg	if (first->path) uFree(first->path);
651f46a6179Smrg	first->file= first->map= first->path= NULL;
652f46a6179Smrg	uFree(first);
653f46a6179Smrg	first= incl;
654f46a6179Smrg    }
655f46a6179Smrg    if (stmt)
656f46a6179Smrg	uFree(stmt);
657f46a6179Smrg    return NULL;
658f46a6179Smrg}
659f46a6179Smrg
660f46a6179Smrg#ifdef DEBUG
661f46a6179Smrgvoid
662f46a6179SmrgPrintStmtAddrs(ParseCommon *stmt)
663f46a6179Smrg{
664f46a6179Smrg    fprintf(stderr,"0x%x",stmt);
665f46a6179Smrg    if (stmt) {
666f46a6179Smrg	do {
667f46a6179Smrg	    fprintf(stderr,"->0x%x",stmt->next);
668f46a6179Smrg	    stmt= stmt->next;
669f46a6179Smrg	} while (stmt);
670f46a6179Smrg    }
671f46a6179Smrg    fprintf(stderr,"\n");
672f46a6179Smrg}
673f46a6179Smrg#endif
674f46a6179Smrg
675f46a6179Smrgstatic void
676f46a6179SmrgCheckDefaultMap(XkbFile	*maps)
677f46a6179Smrg{
678f46a6179SmrgXkbFile * dflt,*tmp;
679f46a6179Smrg
680f46a6179Smrg    dflt= NULL;
681f46a6179Smrg    for (tmp=maps,dflt=NULL;tmp!=NULL;tmp=(XkbFile *)tmp->common.next) {
682f46a6179Smrg	if (tmp->flags&XkbLC_Default) {
683f46a6179Smrg	    if (dflt==NULL)
684f46a6179Smrg		dflt= tmp;
685f46a6179Smrg	    else {
686f46a6179Smrg		if (warningLevel>2) {
687f46a6179Smrg		    WARN1("Multiple default components in %s\n",
688f46a6179Smrg					(scanFile?scanFile:"(unknown)"));
689f46a6179Smrg		    ACTION2("Using %s, ignoring %s\n",
690f46a6179Smrg					(dflt->name?dflt->name:"(first)"),
691f46a6179Smrg					(tmp->name?tmp->name:"(subsequent)"));
692f46a6179Smrg		}
693f46a6179Smrg		tmp->flags&= (~XkbLC_Default);
694f46a6179Smrg	    }
695f46a6179Smrg	}
696f46a6179Smrg    }
697f46a6179Smrg    return;
698f46a6179Smrg}
699f46a6179Smrg
700f46a6179Smrgint
701f46a6179SmrgXKBParseFile(FILE *file,XkbFile	**pRtrn)
702f46a6179Smrg{
703f46a6179Smrg    if (file) {
704f46a6179Smrg	yyin= file;
705f46a6179Smrg	rtrnValue= NULL;
706f46a6179Smrg	if (yyparse()==0) {
707f46a6179Smrg	    *pRtrn= rtrnValue;
708f46a6179Smrg	    CheckDefaultMap(rtrnValue);
709f46a6179Smrg	    rtrnValue= NULL;
710f46a6179Smrg	    return 1;
711f46a6179Smrg	}
712f46a6179Smrg	*pRtrn= NULL;
713f46a6179Smrg	return 0;
714f46a6179Smrg    }
715f46a6179Smrg    *pRtrn= NULL;
716f46a6179Smrg    return 1;
717f46a6179Smrg}
718f46a6179Smrg
719f46a6179SmrgXkbFile *
720f46a6179SmrgCreateXKBFile(int type,char *name,ParseCommon *defs,unsigned flags)
721f46a6179Smrg{
722f46a6179SmrgXkbFile *	file;
723f46a6179Smrgstatic int	fileID;
724f46a6179Smrg
725f46a6179Smrg    file= uTypedAlloc(XkbFile);
726f46a6179Smrg    if (file) {
727f46a6179Smrg	XkbEnsureSafeMapName(name);
728f46a6179Smrg	bzero(file,sizeof(XkbFile));
729f46a6179Smrg	file->type= type;
730f46a6179Smrg	file->topName= uStringDup(name);
731f46a6179Smrg	file->name= name;
732f46a6179Smrg	file->defs= defs;
733f46a6179Smrg	file->id= fileID++;
734f46a6179Smrg	file->compiled= False;
735f46a6179Smrg	file->flags= flags;
736f46a6179Smrg    }
737f46a6179Smrg    return file;
738f46a6179Smrg}
739f46a6179Smrg
740f46a6179Smrgunsigned
741f46a6179SmrgStmtSetMerge(ParseCommon *stmt,unsigned	merge)
742f46a6179Smrg{
743f46a6179Smrg    if ((merge==MergeAltForm) && (stmt->stmtType!=StmtKeycodeDef)) {
744f46a6179Smrg	yyerror("illegal use of 'alternate' merge mode");
745f46a6179Smrg	merge= MergeDefault;
746f46a6179Smrg    }
747f46a6179Smrg    return merge;
748f46a6179Smrg}
749