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