upload tizen2.0 source
[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     const int nMaxBuffSize = 1024;
610     int isFloat = 0;
611     char buf[nMaxBuffSize];
612     int nInBuf = 0;
613
614     buf[0] = ch;
615     nInBuf = 1;
616     while (((ch = scanchar()) != EOF)
617            && (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x')))
618            && nInBuf < (nMaxBuffSize - 1))
619     {
620         buf[nInBuf++] = ch;
621     }
622     if ((ch == '.') && (nInBuf < (nMaxBuffSize - 1)))
623     {
624         isFloat = 1;
625         buf[nInBuf++] = ch;
626         while (((ch = scanchar()) != EOF) && (isxdigit(ch))
627                && nInBuf < (nMaxBuffSize - 1))
628         {
629             buf[nInBuf++] = ch;
630         }
631     }
632     buf[nInBuf++] = '\0';
633     if ((ch != EOF) && (!isspace(ch)))
634         unscanchar(ch);
635
636     if (isFloat)
637     {
638         float tmp;
639         if (sscanf(buf, "%g", &tmp) == 1)
640         {
641             scanInt = tmp * XkbGeomPtsPerMM;
642             return FLOAT;
643         }
644     }
645     else if (sscanf(buf, "%i", &scanInt) == 1)
646         return INTEGER;
647     fprintf(stderr, "Malformed number %s\n", buf);
648     return ERROR_TOK;
649 }
650
651 int
652 yylex(void)
653 {
654     int ch;
655     int rtrn;
656
657     do
658     {
659         ch = scanchar();
660         if (ch == '\n')
661         {
662             lineNum++;
663         }
664         else if (ch == '#')
665         {                       /* handle shell style '#' comments */
666             do
667             {
668                 ch = scanchar();
669             }
670             while ((ch != '\n') && (ch != EOF));
671             lineNum++;
672         }
673         else if (ch == '/')
674         {                       /* handle C++ style double-/ comments */
675             int newch = scanchar();
676             if (newch == '/')
677             {
678                 do
679                 {
680                     ch = scanchar();
681                 }
682                 while ((ch != '\n') && (ch != EOF));
683                 lineNum++;
684             }
685             else if (newch != EOF)
686             {
687                 unscanchar(newch);
688             }
689         }
690     }
691     while ((ch != EOF) && (isspace(ch)));
692     if (ch == '=')
693         rtrn = EQUALS;
694     else if (ch == '+')
695         rtrn = PLUS;
696     else if (ch == '-')
697         rtrn = MINUS;
698     else if (ch == '/')
699         rtrn = DIVIDE;
700     else if (ch == '*')
701         rtrn = TIMES;
702     else if (ch == '{')
703         rtrn = OBRACE;
704     else if (ch == '}')
705         rtrn = CBRACE;
706     else if (ch == '(')
707         rtrn = OPAREN;
708     else if (ch == ')')
709         rtrn = CPAREN;
710     else if (ch == '[')
711         rtrn = OBRACKET;
712     else if (ch == ']')
713         rtrn = CBRACKET;
714     else if (ch == '.')
715         rtrn = DOT;
716     else if (ch == ',')
717         rtrn = COMMA;
718     else if (ch == ';')
719         rtrn = SEMI;
720     else if (ch == '!')
721         rtrn = EXCLAM;
722     else if (ch == '~')
723         rtrn = INVERT;
724     else if (ch == '"')
725         rtrn = yyGetString();
726     else if (ch == '<')
727         rtrn = yyGetKeyName();
728     else if (isalpha(ch) || (ch == '_'))
729         rtrn = yyGetIdent(ch);
730     else if (isdigit(ch))
731         rtrn = yyGetNumber(ch);
732     else if (ch == EOF)
733         rtrn = END_OF_FILE;
734     else
735     {
736 #ifdef DEBUG
737         if (debugFlags)
738             fprintf(stderr,
739                     "Unexpected character %c (%d) in input stream\n", ch, ch);
740 #endif
741         rtrn = ERROR_TOK;
742     }
743 #ifdef DEBUG
744     if (debugFlags & 0x2)
745         fprintf(stderr, "scan: %s\n", tokText(rtrn));
746 #endif
747     return rtrn;
748 }