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