upload tizen2.0 source
[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(const char *sym_str, 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         if (LookupKeysym(sym_str, &def->sym) == 0)
233             def->ignore = True;
234         else
235             def->ignore = False;
236         def->match = match;
237     }
238     else
239     {
240         FATAL("Couldn't allocate interp definition in parser\n");
241         /* NOTREACHED */
242     }
243     return def;
244 }
245
246 KeyTypeDef *
247 KeyTypeCreate(Atom name, VarDef * body)
248 {
249     KeyTypeDef *def;
250
251     def = uTypedAlloc(KeyTypeDef);
252     if (def)
253     {
254         def->common.stmtType = StmtKeyTypeDef;
255         def->common.next = NULL;
256         def->merge = MergeDefault;
257         def->name = name;
258         def->body = body;
259     }
260     else
261     {
262         FATAL("Couldn't allocate key type definition in parser\n");
263         /* NOTREACHED */
264     }
265     return def;
266 }
267
268 SymbolsDef *
269 SymbolsCreate(char *keyName, ExprDef * symbols)
270 {
271     SymbolsDef *def;
272
273     def = uTypedAlloc(SymbolsDef);
274     if (def)
275     {
276         def->common.stmtType = StmtSymbolsDef;
277         def->common.next = NULL;
278         def->merge = MergeDefault;
279         bzero(def->keyName, 5);
280         strncpy(def->keyName, keyName, 4);
281         def->symbols = symbols;
282     }
283     else
284     {
285         FATAL("Couldn't allocate symbols definition in parser\n");
286         /* NOTREACHED */
287     }
288     return def;
289 }
290
291 GroupCompatDef *
292 GroupCompatCreate(int group, ExprDef * val)
293 {
294     GroupCompatDef *def;
295
296     def = uTypedAlloc(GroupCompatDef);
297     if (def)
298     {
299         def->common.stmtType = StmtGroupCompatDef;
300         def->common.next = NULL;
301         def->merge = MergeDefault;
302         def->group = group;
303         def->def = val;
304     }
305     else
306     {
307         FATAL("Couldn't allocate group compat definition in parser\n");
308         /* NOTREACHED */
309     }
310     return def;
311 }
312
313 ModMapDef *
314 ModMapCreate(Atom modifier, ExprDef * keys)
315 {
316     ModMapDef *def;
317
318     def = uTypedAlloc(ModMapDef);
319     if (def)
320     {
321         def->common.stmtType = StmtModMapDef;
322         def->common.next = NULL;
323         def->merge = MergeDefault;
324         def->modifier = modifier;
325         def->keys = keys;
326     }
327     else
328     {
329         FATAL("Couldn't allocate mod mask definition in parser\n");
330         /* NOTREACHED */
331     }
332     return def;
333 }
334
335 IndicatorMapDef *
336 IndicatorMapCreate(Atom name, VarDef * body)
337 {
338     IndicatorMapDef *def;
339
340     def = uTypedAlloc(IndicatorMapDef);
341     if (def)
342     {
343         def->common.stmtType = StmtIndicatorMapDef;
344         def->common.next = NULL;
345         def->merge = MergeDefault;
346         def->name = name;
347         def->body = body;
348     }
349     else
350     {
351         FATAL("Couldn't allocate indicator map definition in parser\n");
352         /* NOTREACHED */
353     }
354     return def;
355 }
356
357 IndicatorNameDef *
358 IndicatorNameCreate(int ndx, ExprDef * name, Bool virtual)
359 {
360     IndicatorNameDef *def;
361
362     def = uTypedAlloc(IndicatorNameDef);
363     if (def)
364     {
365         def->common.stmtType = StmtIndicatorNameDef;
366         def->common.next = NULL;
367         def->merge = MergeDefault;
368         def->ndx = ndx;
369         def->name = name;
370         def->virtual = virtual;
371     }
372     else
373     {
374         FATAL("Couldn't allocate indicator index definition in parser\n");
375         /* NOTREACHED */
376     }
377     return def;
378 }
379
380 ExprDef *
381 ActionCreate(Atom name, ExprDef * args)
382 {
383     ExprDef *act;
384
385     act = uTypedAlloc(ExprDef);
386     if (act)
387     {
388         act->common.stmtType = StmtExpr;
389         act->common.next = NULL;
390         act->op = ExprActionDecl;
391         act->value.action.name = name;
392         act->value.action.args = args;
393         return act;
394     }
395     FATAL("Couldn't allocate ActionDef in parser\n");
396     return NULL;
397 }
398
399 ExprDef *
400 CreateKeysymList(char *sym)
401 {
402     ExprDef *def;
403
404     def = ExprCreate(ExprKeysymList, TypeSymbols);
405     if (def)
406     {
407         def->value.list.nSyms = 1;
408         def->value.list.szSyms = 4;
409         def->value.list.syms = uTypedCalloc(4, char *);
410         if (def->value.list.syms != NULL)
411         {
412             def->value.list.syms[0] = sym;
413             return def;
414         }
415     }
416     FATAL("Couldn't allocate expression for keysym list in parser\n");
417     return NULL;
418 }
419
420 ShapeDef *
421 ShapeDeclCreate(Atom name, OutlineDef * outlines)
422 {
423     ShapeDef *shape;
424     OutlineDef *ol;
425
426     shape = uTypedAlloc(ShapeDef);
427     if (shape != NULL)
428     {
429         bzero(shape, sizeof(ShapeDef));
430         shape->common.stmtType = StmtShapeDef;
431         shape->common.next = NULL;
432         shape->merge = MergeDefault;
433         shape->name = name;
434         shape->nOutlines = 0;
435         shape->outlines = outlines;
436         for (ol = outlines; ol != NULL; ol = (OutlineDef *) ol->common.next)
437         {
438             if (ol->nPoints > 0)
439                 shape->nOutlines++;
440         }
441     }
442     return shape;
443 }
444
445 OutlineDef *
446 OutlineCreate(Atom field, ExprDef * points)
447 {
448     OutlineDef *outline;
449     ExprDef *pt;
450
451     outline = uTypedAlloc(OutlineDef);
452     if (outline != NULL)
453     {
454         bzero(outline, sizeof(OutlineDef));
455         outline->common.stmtType = StmtOutlineDef;
456         outline->common.next = NULL;
457         outline->field = field;
458         outline->nPoints = 0;
459         if (points->op == ExprCoord)
460         {
461             for (pt = points; pt != NULL; pt = (ExprDef *) pt->common.next)
462             {
463                 outline->nPoints++;
464             }
465         }
466         outline->points = points;
467     }
468     return outline;
469 }
470
471 KeyDef *
472 KeyDeclCreate(char *name, ExprDef * expr)
473 {
474     KeyDef *key;
475
476     key = uTypedAlloc(KeyDef);
477     if (key != NULL)
478     {
479         bzero(key, sizeof(KeyDef));
480         key->common.stmtType = StmtKeyDef;
481         key->common.next = NULL;
482         if (name)
483             key->name = name;
484         else
485             key->expr = expr;
486     }
487     return key;
488 }
489
490 KeyDef *
491 KeyDeclMerge(KeyDef * into, KeyDef * from)
492 {
493     into->expr =
494         (ExprDef *) AppendStmt(&into->expr->common, &from->expr->common);
495     from->expr = NULL;
496     uFree(from);
497     return into;
498 }
499
500 RowDef *
501 RowDeclCreate(KeyDef * keys)
502 {
503     RowDef *row;
504     KeyDef *key;
505
506     row = uTypedAlloc(RowDef);
507     if (row != NULL)
508     {
509         bzero(row, sizeof(RowDef));
510         row->common.stmtType = StmtRowDef;
511         row->common.next = NULL;
512         row->nKeys = 0;
513         row->keys = keys;
514         for (key = keys; key != NULL; key = (KeyDef *) key->common.next)
515         {
516             if (key->common.stmtType == StmtKeyDef)
517                 row->nKeys++;
518         }
519     }
520     return row;
521 }
522
523 SectionDef *
524 SectionDeclCreate(Atom name, RowDef * rows)
525 {
526     SectionDef *section;
527     RowDef *row;
528
529     section = uTypedAlloc(SectionDef);
530     if (section != NULL)
531     {
532         bzero(section, sizeof(SectionDef));
533         section->common.stmtType = StmtSectionDef;
534         section->common.next = NULL;
535         section->name = name;
536         section->nRows = 0;
537         section->rows = rows;
538         for (row = rows; row != NULL; row = (RowDef *) row->common.next)
539         {
540             if (row->common.stmtType == StmtRowDef)
541                 section->nRows++;
542         }
543     }
544     return section;
545 }
546
547 OverlayKeyDef *
548 OverlayKeyCreate(char *under, char *over)
549 {
550     OverlayKeyDef *key;
551
552     key = uTypedAlloc(OverlayKeyDef);
553     if (key != NULL)
554     {
555         bzero(key, sizeof(OverlayKeyDef));
556         key->common.stmtType = StmtOverlayKeyDef;
557         strncpy(key->over, over, XkbKeyNameLength);
558         strncpy(key->under, under, XkbKeyNameLength);
559         if (over)
560             uFree(over);
561         if (under)
562             uFree(under);
563     }
564     return key;
565 }
566
567 OverlayDef *
568 OverlayDeclCreate(Atom name, OverlayKeyDef * keys)
569 {
570     OverlayDef *ol;
571     OverlayKeyDef *key;
572
573     ol = uTypedAlloc(OverlayDef);
574     if (ol != NULL)
575     {
576         bzero(ol, sizeof(OverlayDef));
577         ol->common.stmtType = StmtOverlayDef;
578         ol->name = name;
579         ol->keys = keys;
580         for (key = keys; key != NULL;
581              key = (OverlayKeyDef *) key->common.next)
582         {
583             ol->nKeys++;
584         }
585     }
586     return ol;
587 }
588
589 DoodadDef *
590 DoodadCreate(unsigned type, Atom name, VarDef * body)
591 {
592     DoodadDef *doodad;
593
594     doodad = uTypedAlloc(DoodadDef);
595     if (doodad != NULL)
596     {
597         bzero(doodad, sizeof(DoodadDef));
598         doodad->common.stmtType = StmtDoodadDef;
599         doodad->common.next = NULL;
600         doodad->type = type;
601         doodad->name = name;
602         doodad->body = body;
603     }
604     return doodad;
605 }
606
607 ExprDef *
608 AppendKeysymList(ExprDef * list, char *sym)
609 {
610     if (list->value.list.nSyms >= list->value.list.szSyms)
611     {
612         list->value.list.szSyms *= 2;
613         list->value.list.syms = uTypedRecalloc(list->value.list.syms,
614                                                list->value.list.nSyms,
615                                                list->value.list.szSyms,
616                                                char *);
617         if (list->value.list.syms == NULL)
618         {
619             FATAL("Couldn't resize list of symbols for append\n");
620             return NULL;
621         }
622     }
623     list->value.list.syms[list->value.list.nSyms++] = sym;
624     return list;
625 }
626
627 int
628 LookupKeysym(const char *str, KeySym * sym_rtrn)
629 {
630     KeySym sym;
631     char *tmp;
632
633     if ((!str) || (uStrCaseCmp(str, "any") == 0)
634         || (uStrCaseCmp(str, "nosymbol") == 0))
635     {
636         *sym_rtrn = NoSymbol;
637         return 1;
638     }
639     else if ((uStrCaseCmp(str, "none") == 0)
640              || (uStrCaseCmp(str, "voidsymbol") == 0))
641     {
642         *sym_rtrn = XK_VoidSymbol;
643         return 1;
644     }
645     sym = XStringToKeysym(str);
646     if (sym != NoSymbol)
647     {
648         *sym_rtrn = sym;
649         return 1;
650     }
651     if (strlen(str) > 2 && str[0] == '0' && str[1] == 'x') {
652         sym = strtoul(str, &tmp, 16);
653         if (sym != ULONG_MAX && (!tmp || *tmp == '\0')) {
654             *sym_rtrn = sym;
655             return 1;
656         }
657     }
658     return 0;
659 }
660
661 IncludeStmt *
662 IncludeCreate(char *str, unsigned merge)
663 {
664     IncludeStmt *incl, *first;
665     char *file, *map, *stmt, *tmp, *extra_data;
666     char nextop;
667     Bool haveSelf;
668
669     haveSelf = False;
670     incl = first = NULL;
671     file = map = NULL;
672     tmp = str;
673     stmt = uStringDup(str);
674     while ((tmp) && (*tmp))
675     {
676         if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
677         {
678             if ((file == NULL) && (map == NULL))
679             {
680                 if (haveSelf)
681                     goto BAIL;
682                 haveSelf = True;
683             }
684             if (first == NULL)
685                 first = incl = uTypedAlloc(IncludeStmt);
686             else
687             {
688                 incl->next = uTypedAlloc(IncludeStmt);
689                 incl = incl->next;
690             }
691             if (incl)
692             {
693                 incl->common.stmtType = StmtInclude;
694                 incl->common.next = NULL;
695                 incl->merge = merge;
696                 incl->stmt = NULL;
697                 incl->file = file;
698                 incl->map = map;
699                 incl->modifier = extra_data;
700                 incl->path = NULL;
701                 incl->next = NULL;
702             }
703             else
704             {
705                 WSGO("Allocation failure in IncludeCreate\n");
706                 ACTION("Using only part of the include\n");
707                 break;
708             }
709             if (nextop == '|')
710                 merge = MergeAugment;
711             else
712                 merge = MergeOverride;
713         }
714         else
715         {
716             goto BAIL;
717         }
718     }
719     if (first)
720         first->stmt = stmt;
721     else if (stmt)
722         uFree(stmt);
723     return first;
724   BAIL:
725     ERROR1("Illegal include statement \"%s\"\n", stmt);
726     ACTION("Ignored\n");
727     while (first)
728     {
729         incl = first->next;
730         if (first->file)
731             uFree(first->file);
732         if (first->map)
733             uFree(first->map);
734         if (first->modifier)
735             uFree(first->modifier);
736         if (first->path)
737             uFree(first->path);
738         first->file = first->map = first->path = NULL;
739         uFree(first);
740         first = incl;
741     }
742     if (stmt)
743         uFree(stmt);
744     return NULL;
745 }
746
747 #ifdef DEBUG
748 void
749 PrintStmtAddrs(ParseCommon * stmt)
750 {
751     fprintf(stderr, "%p", stmt);
752     if (stmt)
753     {
754         do
755         {
756             fprintf(stderr, "->%p", stmt->next);
757             stmt = stmt->next;
758         }
759         while (stmt);
760     }
761     fprintf(stderr, "\n");
762 }
763 #endif
764
765 static void
766 CheckDefaultMap(XkbFile * maps)
767 {
768     XkbFile *dflt, *tmp;
769
770     dflt = NULL;
771     for (tmp = maps, dflt = NULL; tmp != NULL;
772          tmp = (XkbFile *) tmp->common.next)
773     {
774         if (tmp->flags & XkbLC_Default)
775         {
776             if (dflt == NULL)
777                 dflt = tmp;
778             else
779             {
780                 if (warningLevel > 2)
781                 {
782                     WARN1("Multiple default components in %s\n",
783                           (scanFile ? scanFile : "(unknown)"));
784                     ACTION2("Using %s, ignoring %s\n",
785                             (dflt->name ? dflt->name : "(first)"),
786                             (tmp->name ? tmp->name : "(subsequent)"));
787                 }
788                 tmp->flags &= (~XkbLC_Default);
789             }
790         }
791     }
792     return;
793 }
794
795 int
796 XKBParseFile(FILE * file, XkbFile ** pRtrn)
797 {
798     if (file)
799     {
800         yyin = file;
801         rtrnValue = NULL;
802         if (yyparse() == 0)
803         {
804             *pRtrn = rtrnValue;
805             CheckDefaultMap(rtrnValue);
806             rtrnValue = NULL;
807             return 1;
808         }
809         *pRtrn = NULL;
810         return 0;
811     }
812     *pRtrn = NULL;
813     return 1;
814 }
815
816 XkbFile *
817 CreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
818 {
819     XkbFile *file;
820     static int fileID;
821
822     file = uTypedAlloc(XkbFile);
823     if (file)
824     {
825         XkbEnsureSafeMapName(name);
826         bzero(file, sizeof(XkbFile));
827         file->type = type;
828         file->topName = uStringDup(name);
829         file->name = name;
830         file->defs = defs;
831         file->id = fileID++;
832         file->compiled = False;
833         file->flags = flags;
834     }
835     return file;
836 }
837
838 unsigned
839 StmtSetMerge(ParseCommon * stmt, unsigned merge)
840 {
841     if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
842     {
843         yyerror("illegal use of 'alternate' merge mode");
844         merge = MergeDefault;
845     }
846     return merge;
847 }