xkbevd should not try to build into a pure wayland platform.
[platform/upstream/xkbevd.git] / cfgscan.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 <stdlib.h>
29 #include <ctype.h>
30 #include <X11/Xos.h>
31 #include <X11/X.h>
32 #include <X11/extensions/XKB.h>
33
34 #include "tokens.h"
35 #include "xkbevd.h"
36
37 FILE    *yyin = NULL;
38
39 static char scanFileBuf[1024];
40 char *   scanFile= scanFileBuf;
41 int      lineNum=       0;
42
43 int      scanInt;
44 char    *scanIntStr;
45 int      scanIntClass;
46
47 char    *scanStr = NULL;
48 int      scanStrLine=   0;
49
50 #define BUFSIZE 512
51 static  int     nInBuf = 0;
52 static  char    buf[BUFSIZE];
53
54 #ifdef DEBUG
55
56 extern  unsigned debugFlags;
57
58 static char *
59 tokText(int tok)
60 {
61 static char buf[32];
62
63     switch (tok) {
64         case END_OF_FILE:       sprintf(buf, "END_OF_FILE");break;
65         case ERROR:             sprintf(buf, "ERROR");  break;
66
67         case BELL:              sprintf(buf, "BELL"); break;
68         case ACCESSX:           sprintf(buf, "ACCESSX"); break;
69         case MESSAGE:           sprintf(buf, "MESSAGE"); break;
70
71         case NONE:              sprintf(buf, "NONE"); break;
72         case IGNORE:            sprintf(buf, "IGNORE"); break;
73         case ECHO:              sprintf(buf, "ECHO"); break;
74         case PRINT_EV:          sprintf(buf, "PRINT_EV"); break;
75         case SHELL:             sprintf(buf, "SHELL"); break;
76         case SOUND:             sprintf(buf, "SOUND"); break;
77
78         case EQUALS:            sprintf(buf, "EQUALS"); break;
79         case PLUS:              sprintf(buf, "PLUS");   break;
80         case MINUS:             sprintf(buf, "MINUS");  break;
81         case DIVIDE:            sprintf(buf, "DIVIDE"); break;
82         case TIMES:             sprintf(buf, "TIMES");  break;
83         case OBRACE:            sprintf(buf, "OBRACE"); break;
84         case CBRACE:            sprintf(buf, "CBRACE"); break;
85         case OPAREN:            sprintf(buf, "OPAREN"); break;
86         case CPAREN:            sprintf(buf, "CPAREN"); break;
87         case OBRACKET:          sprintf(buf, "OBRACKET");break;
88         case CBRACKET:          sprintf(buf, "CBRACKET");break;
89         case DOT:               sprintf(buf, "DOT");    break;
90         case COMMA:             sprintf(buf, "COMMA");  break;
91         case SEMI:              sprintf(buf, "SEMI");   break;
92         case EXCLAM:            sprintf(buf, "EXCLAM"); break;
93         case INVERT:            sprintf(buf, "INVERT"); break;
94
95         case STRING:            sprintf(buf, "STRING (%s)",scanStr);    break;
96         case INTEGER:           sprintf(buf, "INTEGER (0x%x)",scanInt); break;
97         case FLOAT:             sprintf(buf, "FLOAT (%d.%d)",
98                                              scanInt/XkbGeomPtsPerMM,
99                                              scanInt%XkbGeomPtsPerMM);break;
100         case IDENT:             sprintf(buf, "IDENT (%s)",scanStr);     break;
101         case KEYNAME:           sprintf(buf, "KEYNAME (%s)",scanStr);   break;
102         default:                sprintf(buf, "UNKNOWN");        break;
103     }
104     return buf;
105 }
106 #endif
107
108 int
109 setScanState(const char *file, int line)
110 {
111     if (file!=NULL)
112         strncpy(scanFile,file,1024);
113     if (line>=0)
114         lineNum= line;
115     return 1;
116 }
117
118 static int
119 yyGetString(void)
120 {
121 int ch;
122
123     nInBuf = 0;
124     while ( ((ch=getc(yyin))!=EOF) && (ch!='"') ) {
125         if ( ch == '\\' ) {
126             if ((ch = getc(yyin))!=EOF) {
127                 if ( ch=='n' )          ch = '\n';
128                 else if ( ch == 't' )   ch = '\t';
129                 else if ( ch == 'v' )   ch = '\v';
130                 else if ( ch == 'b' )   ch = '\b';
131                 else if ( ch == 'r' )   ch = '\r';
132                 else if ( ch == 'f' )   ch = '\f';
133                 else if ( ch == 'e' )   ch = '\033';
134                 else if ( ch == '0' ) {
135                     int tmp,stop;
136                     ch = stop = 0;
137                     if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
138                                                 (tmp!='8') && (tmp!='9')) {
139                         ch= (ch*8)+(tmp-'0');
140                     }
141                     else {
142                         stop= 1;
143                         ungetc(tmp,yyin);
144                     }
145                     if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
146                                                 (tmp!='8') && (tmp!='9')) {
147                         ch= (ch*8)+(tmp-'0');
148                     }
149                     else {
150                         stop= 1;
151                         ungetc(tmp,yyin);
152                     }
153                     if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
154                                                 (tmp!='8') && (tmp!='9')) {
155                         ch= (ch*8)+(tmp-'0');
156                     }
157                     else {
158                         stop= 1;
159                         ungetc(tmp,yyin);
160                     }
161                 }
162             }
163             else return ERROR;
164         }
165
166         if ( nInBuf < BUFSIZE-1 )
167             buf[nInBuf++] = ch;
168     }
169     if ( ch == '"' ) {
170         buf[nInBuf++] = '\0';
171         if  ( scanStr )
172             free( scanStr );
173         scanStr = uStringDup(buf);
174         scanStrLine = lineNum;
175         return STRING;
176     }
177     return ERROR;
178 }
179
180 static int
181 yyGetKeyName(void)
182 {
183 int ch;
184
185     nInBuf = 0;
186     while ( ((ch=getc(yyin))!=EOF) && (ch!='>') ) {
187         if ( ch == '\\' ) {
188             if ((ch = getc(yyin))!=EOF) {
189                 if ( ch=='n' )          ch = '\n';
190                 else if ( ch == 't' )   ch = '\t';
191                 else if ( ch == 'v' )   ch = '\v';
192                 else if ( ch == 'b' )   ch = '\b';
193                 else if ( ch == 'r' )   ch = '\r';
194                 else if ( ch == 'f' )   ch = '\f';
195                 else if ( ch == 'e' )   ch = '\033';
196                 else if ( ch == '0' ) {
197                     int tmp,stop;
198                     ch = stop = 0;
199                     if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
200                                                 (tmp!='8') && (tmp!='9')) {
201                         ch= (ch*8)+(tmp-'0');
202                     }
203                     else {
204                         stop= 1;
205                         ungetc(tmp,yyin);
206                     }
207                     if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
208                                                 (tmp!='8') && (tmp!='9')) {
209                         ch= (ch*8)+(tmp-'0');
210                     }
211                     else {
212                         stop= 1;
213                         ungetc(tmp,yyin);
214                     }
215                     if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
216                                                 (tmp!='8') && (tmp!='9')) {
217                         ch= (ch*8)+(tmp-'0');
218                     }
219                     else {
220                         stop= 1;
221                         ungetc(tmp,yyin);
222                     }
223                 }
224             }
225             else return ERROR;
226         }
227
228         if ( nInBuf < BUFSIZE-1 )
229             buf[nInBuf++] = ch;
230     }
231     if (( ch == '>' )&&(nInBuf<5)) {
232         buf[nInBuf++] = '\0';
233         if  ( scanStr )
234             free( scanStr );
235         scanStr = uStringDup(buf);
236         scanStrLine = lineNum;
237         return KEYNAME;
238     }
239     return ERROR;
240 }
241
242 static struct _Keyword {
243         const char      *keyword;
244         int              token;
245 } keywords[] = {
246     { "bell",                   BELL                    },
247     { "accessx",                ACCESSX                 },
248     { "message",                MESSAGE                 },
249     { "none",                   NONE                    },
250     { "ignore",                 IGNORE                  },
251     { "echo",                   ECHO                    },
252     { "printevent",             PRINT_EV                },
253     { "shell",                  SHELL                   },
254     { "sound",                  SOUND                   }
255 };
256 static int numKeywords = sizeof(keywords)/sizeof(struct _Keyword);
257
258 static int
259 yyGetIdent(int first)
260 {
261 int ch,i,found;
262 int     rtrn = -1;
263
264     buf[0] = first; nInBuf = 1;
265     while ( ((ch=getc(yyin))!=EOF) && (isalnum(ch)||(ch=='_')) ) {
266         if ( nInBuf < BUFSIZE - 1 )
267             buf[nInBuf++] = ch;
268     }
269     buf[nInBuf++] = '\0';
270     found= 0;
271
272     for (i=0;(!found)&&(i<numKeywords);i++) {
273         if (uStrCaseCmp(buf,keywords[i].keyword)==0) {
274             rtrn= keywords[i].token;
275             found= 1;
276         }
277     }
278     if (!found) {
279         if  ( scanStr )
280             free( scanStr );
281         scanStr = uStringDup(buf);
282         scanStrLine = lineNum;
283         rtrn = IDENT;
284     }
285
286     if ( (ch!=EOF) && (!isspace(ch)) )
287         ungetc( ch, yyin );
288     else if ( ch=='\n' )
289         lineNum++;
290
291     return rtrn;
292 }
293
294 static int
295 yyGetNumber(int ch)
296 {
297 int     isFloat= 0;
298
299     buf[0]= ch;
300     nInBuf= 1;
301     while (((ch=getc(yyin))!=EOF)&&(isxdigit(ch)||((nInBuf==1)&&(ch=='x')))) {
302         buf[nInBuf++]= ch;
303     }
304     if (ch=='.') {
305         isFloat= 1;
306         buf[nInBuf++]= ch;
307         while (((ch=getc(yyin))!=EOF)&&(isxdigit(ch))) {
308             buf[nInBuf++]= ch;
309         }
310     }
311     buf[nInBuf++]= '\0';
312     if ((ch!=EOF)&&(!isspace(ch)))
313         ungetc( ch, yyin );
314
315     if (isFloat) {
316         float tmp;
317         if (sscanf(buf,"%g",&tmp)==1) {
318             scanInt= tmp*XkbGeomPtsPerMM;
319             return FLOAT;
320         }
321     }
322     else if ( sscanf(buf,"%i",&scanInt)==1 )
323         return INTEGER;
324     fprintf(stderr,"Malformed number %s\n",buf);
325     return ERROR;
326 }
327
328 int
329 yylex(void)
330 {
331 int     ch;
332 int     rtrn;
333
334     do {
335         ch = getc(yyin);
336         if ( ch == '\n' ) {
337             lineNum++;
338         }
339         else if ( ch=='/' ) {   /* handle C++ style double-/ comments */
340             int newch= getc(yyin);
341             if (newch=='/') {
342                 do {
343                     ch= getc(yyin);
344                 } while ((ch!='\n')&&(ch!=EOF));
345                 lineNum++;
346             }
347             else if (newch!=EOF) {
348                 ungetc(newch,yyin);
349             }
350         }
351     } while ((ch!=EOF)&&(isspace(ch)));
352     if ( ch == '=' )                    rtrn = EQUALS;
353     else if ( ch == '+' )               rtrn = PLUS;
354     else if ( ch == '-' )               rtrn = MINUS;
355     else if ( ch == '/' )               rtrn = DIVIDE;
356     else if ( ch == '*' )               rtrn = TIMES;
357     else if ( ch == '{' )               rtrn = OBRACE;
358     else if ( ch == '}' )               rtrn = CBRACE;
359     else if ( ch == '(' )               rtrn = OPAREN;
360     else if ( ch == ')' )               rtrn = CPAREN;
361     else if ( ch == '[' )               rtrn = OBRACKET;
362     else if ( ch == ']' )               rtrn = CBRACKET;
363     else if ( ch == '.' )               rtrn = DOT;
364     else if ( ch == ',' )               rtrn = COMMA;
365     else if ( ch == ';' )               rtrn = SEMI;
366     else if ( ch == '!' )               rtrn = EXCLAM;
367     else if ( ch == '~' )               rtrn = INVERT;
368     else if ( ch == '"' )               rtrn = yyGetString();
369     else if ( ch == '<' )               rtrn = yyGetKeyName();
370     else if ( isalpha(ch) || (ch=='_')) rtrn = yyGetIdent(ch);
371     else if ( isdigit(ch) )             rtrn = yyGetNumber(ch);
372     else if ( ch == EOF )               rtrn = END_OF_FILE;
373     else {
374         fprintf(stderr,"Unexpected character %c (%d) in input stream\n",ch,ch);
375         rtrn = ERROR;
376     }
377 #ifdef DEBUG
378     if (debugFlags&0x2)
379         fprintf(stderr,"scan: %s\n",tokText(rtrn));
380 #endif
381     return rtrn;
382 }