997b5f5c0526fb46abf1d3aa06209e445a06a53c
[profile/ivi/libxkbcommon.git] / src / xkbcomp / xkbscan.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 <stdio.h>
28 #include <ctype.h>
29 #include <X11/Xos.h>
30
31 #include "tokens.h"
32 #define DEBUG_VAR       scanDebug
33 #include "utils.h"
34 #include "parseutils.h"
35
36 unsigned int scanDebug;
37
38 FILE *yyin = NULL;
39
40 static char scanFileBuf[1024] = {0};
41 char *scanFile = scanFileBuf;
42 int lineNum = 0;
43
44 int scanInt;
45
46 char *scanStr = NULL;
47 static int scanStrLine = 0;
48
49 #define BUFSIZE 512
50 static int nInBuf = 0;
51 static char buf[BUFSIZE];
52
53 #ifdef DEBUG
54 static char *
55 tokText(int tok)
56 {
57     static char buf[32];
58
59     switch (tok)
60     {
61     case END_OF_FILE:
62         snprintf(buf, sizeof(buf), "END_OF_FILE");
63         break;
64     case ERROR_TOK:
65         snprintf(buf, sizeof(buf), "ERROR");
66         break;
67
68     case XKB_KEYMAP:
69         snprintf(buf, sizeof(buf), "XKB_KEYMAP");
70         break;
71     case XKB_KEYCODES:
72         snprintf(buf, sizeof(buf), "XKB_KEYCODES");
73         break;
74     case XKB_TYPES:
75         snprintf(buf, sizeof(buf), "XKB_TYPES");
76         break;
77     case XKB_SYMBOLS:
78         snprintf(buf, sizeof(buf), "XKB_SYMBOLS");
79         break;
80     case XKB_COMPATMAP:
81         snprintf(buf, sizeof(buf), "XKB_COMPATMAP");
82         break;
83     case XKB_GEOMETRY:
84         snprintf(buf, sizeof(buf), "XKB_GEOMETRY");
85         break;
86     case XKB_SEMANTICS:
87         snprintf(buf, sizeof(buf), "XKB_SEMANTICS");
88         break;
89     case XKB_LAYOUT:
90         snprintf(buf, sizeof(buf), "XKB_LAYOUT");
91         break;
92
93     case INCLUDE:
94         snprintf(buf, sizeof(buf), "INCLUDE");
95         break;
96     case OVERRIDE:
97         snprintf(buf, sizeof(buf), "OVERRIDE");
98         break;
99     case AUGMENT:
100         snprintf(buf, sizeof(buf), "AUGMENT");
101         break;
102     case REPLACE:
103         snprintf(buf, sizeof(buf), "REPLACE");
104         break;
105     case ALTERNATE:
106         snprintf(buf, sizeof(buf), "ALTERNATE");
107         break;
108
109     case VIRTUAL_MODS:
110         snprintf(buf, sizeof(buf), "VIRTUAL_MODS");
111         break;
112     case TYPE:
113         snprintf(buf, sizeof(buf), "TYPE");
114         break;
115     case INTERPRET:
116         snprintf(buf, sizeof(buf), "INTERPRET");
117         break;
118     case ACTION_TOK:
119         snprintf(buf, sizeof(buf), "ACTION");
120         break;
121     case KEY:
122         snprintf(buf, sizeof(buf), "KEY");
123         break;
124     case ALIAS:
125         snprintf(buf, sizeof(buf), "ALIAS");
126         break;
127     case GROUP:
128         snprintf(buf, sizeof(buf), "GROUP");
129         break;
130     case MODIFIER_MAP:
131         snprintf(buf, sizeof(buf), "MODIFIER_MAP");
132         break;
133     case INDICATOR:
134         snprintf(buf, sizeof(buf), "INDICATOR");
135         break;
136     case SHAPE:
137         snprintf(buf, sizeof(buf), "SHAPE");
138         break;
139     case KEYS:
140         snprintf(buf, sizeof(buf), "KEYS");
141         break;
142     case ROW:
143         snprintf(buf, sizeof(buf), "ROW");
144         break;
145     case SECTION:
146         snprintf(buf, sizeof(buf), "SECTION");
147         break;
148     case OVERLAY:
149         snprintf(buf, sizeof(buf), "OVERLAY");
150         break;
151     case TEXT:
152         snprintf(buf, sizeof(buf), "TEXT");
153         break;
154     case OUTLINE:
155         snprintf(buf, sizeof(buf), "OUTLINE");
156         break;
157     case SOLID:
158         snprintf(buf, sizeof(buf), "SOLID");
159         break;
160     case LOGO:
161         snprintf(buf, sizeof(buf), "LOGO");
162         break;
163     case VIRTUAL:
164         snprintf(buf, sizeof(buf), "VIRTUAL");
165         break;
166
167     case EQUALS:
168         snprintf(buf, sizeof(buf), "EQUALS");
169         break;
170     case PLUS:
171         snprintf(buf, sizeof(buf), "PLUS");
172         break;
173     case MINUS:
174         snprintf(buf, sizeof(buf), "MINUS");
175         break;
176     case DIVIDE:
177         snprintf(buf, sizeof(buf), "DIVIDE");
178         break;
179     case TIMES:
180         snprintf(buf, sizeof(buf), "TIMES");
181         break;
182     case OBRACE:
183         snprintf(buf, sizeof(buf), "OBRACE");
184         break;
185     case CBRACE:
186         snprintf(buf, sizeof(buf), "CBRACE");
187         break;
188     case OPAREN:
189         snprintf(buf, sizeof(buf), "OPAREN");
190         break;
191     case CPAREN:
192         snprintf(buf, sizeof(buf), "CPAREN");
193         break;
194     case OBRACKET:
195         snprintf(buf, sizeof(buf), "OBRACKET");
196         break;
197     case CBRACKET:
198         snprintf(buf, sizeof(buf), "CBRACKET");
199         break;
200     case DOT:
201         snprintf(buf, sizeof(buf), "DOT");
202         break;
203     case COMMA:
204         snprintf(buf, sizeof(buf), "COMMA");
205         break;
206     case SEMI:
207         snprintf(buf, sizeof(buf), "SEMI");
208         break;
209     case EXCLAM:
210         snprintf(buf, sizeof(buf), "EXCLAM");
211         break;
212     case INVERT:
213         snprintf(buf, sizeof(buf), "INVERT");
214         break;
215
216     case STRING:
217         snprintf(buf, sizeof(buf), "STRING (%s)", scanStr);
218         break;
219     case INTEGER:
220         snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt);
221         break;
222     case FLOAT:
223         snprintf(buf, sizeof(buf), "FLOAT (%d.%d)",
224                 scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM);
225         break;
226     case IDENT:
227         snprintf(buf, sizeof(buf), "IDENT (%s)", scanStr);
228         break;
229     case KEYNAME:
230         snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanStr);
231         break;
232
233     case PARTIAL:
234         snprintf(buf, sizeof(buf), "PARTIAL");
235         break;
236     case DEFAULT:
237         snprintf(buf, sizeof(buf), "DEFAULT");
238         break;
239     case HIDDEN:
240         snprintf(buf, sizeof(buf), "HIDDEN");
241         break;
242
243     case ALPHANUMERIC_KEYS:
244         snprintf(buf, sizeof(buf), "ALPHANUMERIC_KEYS");
245         break;
246     case MODIFIER_KEYS:
247         snprintf(buf, sizeof(buf), "MODIFIER_KEYS");
248         break;
249     case KEYPAD_KEYS:
250         snprintf(buf, sizeof(buf), "KEYPAD_KEYS");
251         break;
252     case FUNCTION_KEYS:
253         snprintf(buf, sizeof(buf), "FUNCTION_KEYS");
254         break;
255     case ALTERNATE_GROUP:
256         snprintf(buf, sizeof(buf), "ALTERNATE_GROUP");
257         break;
258
259     default:
260         snprintf(buf, sizeof(buf), "UNKNOWN");
261         break;
262     }
263     return buf;
264 }
265 #endif
266
267 int
268 setScanState(char *file, int line)
269 {
270     if (file != NULL)
271         strncpy(scanFile, file, 1024);
272     if (line >= 0)
273         lineNum = line;
274     return 1;
275 }
276
277 static int
278 yyGetString(void)
279 {
280     int ch;
281
282     nInBuf = 0;
283     while (((ch = getc(yyin)) != EOF) && (ch != '"'))
284     {
285         if (ch == '\\')
286         {
287             if ((ch = getc(yyin)) != EOF)
288             {
289                 if (ch == 'n')
290                     ch = '\n';
291                 else if (ch == 't')
292                     ch = '\t';
293                 else if (ch == 'v')
294                     ch = '\v';
295                 else if (ch == 'b')
296                     ch = '\b';
297                 else if (ch == 'r')
298                     ch = '\r';
299                 else if (ch == 'f')
300                     ch = '\f';
301                 else if (ch == 'e')
302                     ch = '\033';
303                 else if (ch == '0')
304                 {
305                     int tmp, stop;
306                     ch = stop = 0;
307                     if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
308                         && (tmp != '8') && (tmp != '9'))
309                     {
310                         ch = (ch * 8) + (tmp - '0');
311                     }
312                     else
313                     {
314                         stop = 1;
315                         ungetc(tmp, yyin);
316                     }
317                     if (!stop)
318                     {
319                         if (((tmp = getc(yyin)) != EOF)
320                             && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
321                         {
322                             ch = (ch * 8) + (tmp - '0');
323                         }
324                         else
325                         {
326                             stop = 1;
327                             ungetc(tmp, yyin);
328                         }
329                     }
330                     if (!stop)
331                     {
332                         if (((tmp = getc(yyin)) != EOF)
333                             && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
334                         {
335                             ch = (ch * 8) + (tmp - '0');
336                         }
337                         else
338                         {
339                             stop = 1;
340                             ungetc(tmp, yyin);
341                         }
342                     }
343                 }
344             }
345             else
346                 return ERROR_TOK;
347         }
348         if (nInBuf < BUFSIZE - 1)
349             buf[nInBuf++] = ch;
350     }
351     if (ch == '"')
352     {
353         buf[nInBuf++] = '\0';
354         if (scanStr)
355             uFree(scanStr);
356         scanStr = (char *) uStringDup(buf);
357         scanStrLine = lineNum;
358         return STRING;
359     }
360     return ERROR_TOK;
361 }
362
363 static int
364 yyGetKeyName(void)
365 {
366     int ch;
367
368     nInBuf = 0;
369     while (((ch = getc(yyin)) != EOF) && (ch != '>'))
370     {
371         if (ch == '\\')
372         {
373             if ((ch = getc(yyin)) != EOF)
374             {
375                 if (ch == 'n')
376                     ch = '\n';
377                 else if (ch == 't')
378                     ch = '\t';
379                 else if (ch == 'v')
380                     ch = '\v';
381                 else if (ch == 'b')
382                     ch = '\b';
383                 else if (ch == 'r')
384                     ch = '\r';
385                 else if (ch == 'f')
386                     ch = '\f';
387                 else if (ch == 'e')
388                     ch = '\033';
389                 else if (ch == '0')
390                 {
391                     int tmp, stop;
392                     ch = stop = 0;
393                     if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
394                         && (tmp != '8') && (tmp != '9'))
395                     {
396                         ch = (ch * 8) + (tmp - '0');
397                     }
398                     else
399                     {
400                         stop = 1;
401                         ungetc(tmp, yyin);
402                     }
403                     if ((!stop) && ((tmp = getc(yyin)) != EOF)
404                         && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
405                     {
406                         ch = (ch * 8) + (tmp - '0');
407                     }
408                     else
409                     {
410                         stop = 1;
411                         ungetc(tmp, yyin);
412                     }
413                     if ((!stop) && ((tmp = getc(yyin)) != EOF)
414                         && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
415                     {
416                         ch = (ch * 8) + (tmp - '0');
417                     }
418                     else
419                     {
420                         stop = 1;
421                         ungetc(tmp, yyin);
422                     }
423                 }
424             }
425             else
426                 return ERROR_TOK;
427         }
428
429         if (nInBuf < BUFSIZE - 1)
430             buf[nInBuf++] = ch;
431     }
432     if ((ch == '>') && (nInBuf < 5))
433     {
434         buf[nInBuf++] = '\0';
435         if (scanStr)
436             uFree(scanStr);
437         scanStr = (char *) uStringDup(buf);
438         scanStrLine = lineNum;
439         return KEYNAME;
440     }
441     return ERROR_TOK;
442 }
443
444 static struct _Keyword
445 {
446     const char *keyword;
447     int token;
448 } keywords[] =
449 {
450     {
451     "xkb_keymap", XKB_KEYMAP},
452     {
453     "xkb_keycodes", XKB_KEYCODES},
454     {
455     "xkb_types", XKB_TYPES},
456     {
457     "xkb_symbols", XKB_SYMBOLS},
458     {
459     "xkb_compat", XKB_COMPATMAP},
460     {
461     "xkb_compat_map", XKB_COMPATMAP},
462     {
463     "xkb_compatibility", XKB_COMPATMAP},
464     {
465     "xkb_compatibility_map", XKB_COMPATMAP},
466     {
467     "xkb_geometry", XKB_GEOMETRY},
468     {
469     "xkb_semantics", XKB_SEMANTICS},
470     {
471     "xkb_layout", XKB_LAYOUT},
472     {
473     "include", INCLUDE},
474     {
475     "override", OVERRIDE},
476     {
477     "augment", AUGMENT},
478     {
479     "replace", REPLACE},
480     {
481     "alternate", ALTERNATE},
482     {
483     "partial", PARTIAL},
484     {
485     "default", DEFAULT},
486     {
487     "hidden", HIDDEN},
488     {
489     "virtual_modifiers", VIRTUAL_MODS},
490     {
491     "type", TYPE},
492     {
493     "interpret", INTERPRET},
494     {
495     "action", ACTION_TOK},
496     {
497     "key", KEY},
498     {
499     "alias", ALIAS},
500     {
501     "group", GROUP},
502     {
503     "modmap", MODIFIER_MAP},
504     {
505     "mod_map", MODIFIER_MAP},
506     {
507     "modifier_map", MODIFIER_MAP},
508     {
509     "indicator", INDICATOR},
510     {
511     "shape", SHAPE},
512     {
513     "row", ROW},
514     {
515     "keys", KEYS},
516     {
517     "section", SECTION},
518     {
519     "overlay", OVERLAY},
520     {
521     "text", TEXT},
522     {
523     "outline", OUTLINE},
524     {
525     "solid", SOLID},
526     {
527     "logo", LOGO},
528     {
529     "virtual", VIRTUAL},
530     {
531     "alphanumeric_keys", ALPHANUMERIC_KEYS},
532     {
533     "modifier_keys", MODIFIER_KEYS},
534     {
535     "keypad_keys", KEYPAD_KEYS},
536     {
537     "function_keys", FUNCTION_KEYS},
538     {
539     "alternate_group", ALTERNATE_GROUP}
540 };
541 static int numKeywords = sizeof(keywords) / sizeof(struct _Keyword);
542
543 static int
544 yyGetIdent(int first)
545 {
546     int ch, i, found;
547     int rtrn = IDENT;
548
549     buf[0] = first;
550     nInBuf = 1;
551     while (((ch = getc(yyin)) != EOF) && (isalnum(ch) || (ch == '_')))
552     {
553         if (nInBuf < BUFSIZE - 1)
554             buf[nInBuf++] = ch;
555     }
556     buf[nInBuf++] = '\0';
557     found = 0;
558
559     for (i = 0; (!found) && (i < numKeywords); i++)
560     {
561         if (uStrCaseCmp(buf, keywords[i].keyword) == 0)
562         {
563             rtrn = keywords[i].token;
564             found = 1;
565         }
566     }
567     if (!found)
568     {
569         if (scanStr)
570             uFree(scanStr);
571         scanStr = (char *) uStringDup(buf);
572         scanStrLine = lineNum;
573         rtrn = IDENT;
574     }
575
576     if ((ch != EOF) && (!isspace(ch)))
577         ungetc(ch, yyin);
578     else if (ch == '\n')
579         lineNum++;
580
581     return rtrn;
582 }
583
584 static int
585 yyGetNumber(int ch)
586 {
587     int isFloat = 0;
588
589     buf[0] = ch;
590     nInBuf = 1;
591     while (((ch = getc(yyin)) != EOF)
592            && (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x'))))
593     {
594         buf[nInBuf++] = ch;
595     }
596     if (ch == '.')
597     {
598         isFloat = 1;
599         buf[nInBuf++] = ch;
600         while (((ch = getc(yyin)) != EOF) && (isxdigit(ch)))
601         {
602             buf[nInBuf++] = ch;
603         }
604     }
605     buf[nInBuf++] = '\0';
606     if ((ch != EOF) && (!isspace(ch)))
607         ungetc(ch, yyin);
608
609     if (isFloat)
610     {
611         float tmp;
612         if (sscanf(buf, "%g", &tmp) == 1)
613         {
614             scanInt = tmp * XkbGeomPtsPerMM;
615             return FLOAT;
616         }
617     }
618     else if (sscanf(buf, "%i", &scanInt) == 1)
619         return INTEGER;
620     fprintf(stderr, "Malformed number %s\n", buf);
621     return ERROR_TOK;
622 }
623
624 int
625 yylex(void)
626 {
627     int ch;
628     int rtrn;
629
630     do
631     {
632         ch = getc(yyin);
633         if (ch == '\n')
634         {
635             lineNum++;
636         }
637         else if (ch == '#')
638         {                       /* handle shell style '#' comments */
639             do
640             {
641                 ch = getc(yyin);
642             }
643             while ((ch != '\n') && (ch != EOF));
644             lineNum++;
645         }
646         else if (ch == '/')
647         {                       /* handle C++ style double-/ comments */
648             int newch = getc(yyin);
649             if (newch == '/')
650             {
651                 do
652                 {
653                     ch = getc(yyin);
654                 }
655                 while ((ch != '\n') && (ch != EOF));
656                 lineNum++;
657             }
658             else if (newch != EOF)
659             {
660                 ungetc(newch, yyin);
661             }
662         }
663     }
664     while ((ch != EOF) && (isspace(ch)));
665     if (ch == '=')
666         rtrn = EQUALS;
667     else if (ch == '+')
668         rtrn = PLUS;
669     else if (ch == '-')
670         rtrn = MINUS;
671     else if (ch == '/')
672         rtrn = DIVIDE;
673     else if (ch == '*')
674         rtrn = TIMES;
675     else if (ch == '{')
676         rtrn = OBRACE;
677     else if (ch == '}')
678         rtrn = CBRACE;
679     else if (ch == '(')
680         rtrn = OPAREN;
681     else if (ch == ')')
682         rtrn = CPAREN;
683     else if (ch == '[')
684         rtrn = OBRACKET;
685     else if (ch == ']')
686         rtrn = CBRACKET;
687     else if (ch == '.')
688         rtrn = DOT;
689     else if (ch == ',')
690         rtrn = COMMA;
691     else if (ch == ';')
692         rtrn = SEMI;
693     else if (ch == '!')
694         rtrn = EXCLAM;
695     else if (ch == '~')
696         rtrn = INVERT;
697     else if (ch == '"')
698         rtrn = yyGetString();
699     else if (ch == '<')
700         rtrn = yyGetKeyName();
701     else if (isalpha(ch) || (ch == '_'))
702         rtrn = yyGetIdent(ch);
703     else if (isdigit(ch))
704         rtrn = yyGetNumber(ch);
705     else if (ch == EOF)
706         rtrn = END_OF_FILE;
707     else
708     {
709 #ifdef DEBUG
710         if (debugFlags)
711             fprintf(stderr,
712                     "Unexpected character %c (%d) in input stream\n", ch, ch);
713 #endif
714         rtrn = ERROR_TOK;
715     }
716 #ifdef DEBUG
717     if (debugFlags & 0x2)
718         fprintf(stderr, "scan: %s\n", tokText(rtrn));
719 #endif
720     return rtrn;
721 }