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