176910425Smrg/************************************************************ 276910425Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 376910425Smrg 476910425Smrg Permission to use, copy, modify, and distribute this 576910425Smrg software and its documentation for any purpose and without 676910425Smrg fee is hereby granted, provided that the above copyright 776910425Smrg notice appear in all copies and that both that copyright 876910425Smrg notice and this permission notice appear in supporting 99ff100acSmrg documentation, and that the name of Silicon Graphics not be 109ff100acSmrg used in advertising or publicity pertaining to distribution 1176910425Smrg of the software without specific prior written permission. 129ff100acSmrg Silicon Graphics makes no representation about the suitability 1376910425Smrg of this software for any purpose. It is provided "as is" 1476910425Smrg without any express or implied warranty. 159ff100acSmrg 169ff100acSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 179ff100acSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1876910425Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 199ff100acSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 209ff100acSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 219ff100acSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2276910425Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2376910425Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 2476910425Smrg 2576910425Smrg ********************************************************/ 2676910425Smrg 2776910425Smrg#include <stdio.h> 2876910425Smrg#include <stdlib.h> 2976910425Smrg#include <ctype.h> 3076910425Smrg#include <X11/Xos.h> 3176910425Smrg#include <X11/X.h> 3276910425Smrg#include <X11/extensions/XKB.h> 3376910425Smrg 3476910425Smrg#include "tokens.h" 3576910425Smrg#include "xkbevd.h" 3676910425Smrg 379ff100acSmrgFILE *yyin = NULL; 3876910425Smrg 3976910425Smrgstatic char scanFileBuf[1024]; 409ff100acSmrgchar *scanFile = scanFileBuf; 419ff100acSmrgint lineNum = 0; 4276910425Smrg 439ff100acSmrgint scanInt; 449ff100acSmrgchar *scanIntStr; 459ff100acSmrgint scanIntClass; 4676910425Smrg 479ff100acSmrgchar *scanStr = NULL; 489ff100acSmrgint scanStrLine = 0; 4976910425Smrg 509ff100acSmrg#define BUFSIZE 512 519ff100acSmrgstatic int nInBuf = 0; 529ff100acSmrgstatic char buf[BUFSIZE]; 5376910425Smrg 5476910425Smrg#ifdef DEBUG 5576910425Smrg 569ff100acSmrgextern unsigned debugFlags; 5776910425Smrg 5876910425Smrgstatic char * 5976910425SmrgtokText(int tok) 6076910425Smrg{ 619ff100acSmrg static char buf[32]; 6276910425Smrg 6376910425Smrg switch (tok) { 649ff100acSmrg case END_OF_FILE: 659ff100acSmrg snprintf(buf, sizeof(buf), "END_OF_FILE"); 669ff100acSmrg break; 679ff100acSmrg case ERROR: 689ff100acSmrg snprintf(buf, sizeof(buf), "ERROR"); 699ff100acSmrg break; 709ff100acSmrg 719ff100acSmrg case BELL: 729ff100acSmrg snprintf(buf, sizeof(buf), "BELL"); 739ff100acSmrg break; 749ff100acSmrg case ACCESSX: 759ff100acSmrg snprintf(buf, sizeof(buf), "ACCESSX"); 769ff100acSmrg break; 779ff100acSmrg case MESSAGE: 789ff100acSmrg snprintf(buf, sizeof(buf), "MESSAGE"); 799ff100acSmrg break; 809ff100acSmrg 819ff100acSmrg case NONE: 829ff100acSmrg snprintf(buf, sizeof(buf), "NONE"); 839ff100acSmrg break; 849ff100acSmrg case IGNORE: 859ff100acSmrg snprintf(buf, sizeof(buf), "IGNORE"); 869ff100acSmrg break; 879ff100acSmrg case ECHO: 889ff100acSmrg snprintf(buf, sizeof(buf), "ECHO"); 899ff100acSmrg break; 909ff100acSmrg case PRINT_EV: 919ff100acSmrg snprintf(buf, sizeof(buf), "PRINT_EV"); 929ff100acSmrg break; 939ff100acSmrg case SHELL: 949ff100acSmrg snprintf(buf, sizeof(buf), "SHELL"); 959ff100acSmrg break; 969ff100acSmrg case SOUND: 979ff100acSmrg snprintf(buf, sizeof(buf), "SOUND"); 989ff100acSmrg break; 999ff100acSmrg 1009ff100acSmrg case EQUALS: 1019ff100acSmrg snprintf(buf, sizeof(buf), "EQUALS"); 1029ff100acSmrg break; 1039ff100acSmrg case PLUS: 1049ff100acSmrg snprintf(buf, sizeof(buf), "PLUS"); 1059ff100acSmrg break; 1069ff100acSmrg case MINUS: 1079ff100acSmrg snprintf(buf, sizeof(buf), "MINUS"); 1089ff100acSmrg break; 1099ff100acSmrg case DIVIDE: 1109ff100acSmrg snprintf(buf, sizeof(buf), "DIVIDE"); 1119ff100acSmrg break; 1129ff100acSmrg case TIMES: 1139ff100acSmrg snprintf(buf, sizeof(buf), "TIMES"); 1149ff100acSmrg break; 1159ff100acSmrg case OBRACE: 1169ff100acSmrg snprintf(buf, sizeof(buf), "OBRACE"); 1179ff100acSmrg break; 1189ff100acSmrg case CBRACE: 1199ff100acSmrg snprintf(buf, sizeof(buf), "CBRACE"); 1209ff100acSmrg break; 1219ff100acSmrg case OPAREN: 1229ff100acSmrg snprintf(buf, sizeof(buf), "OPAREN"); 1239ff100acSmrg break; 1249ff100acSmrg case CPAREN: 1259ff100acSmrg snprintf(buf, sizeof(buf), "CPAREN"); 1269ff100acSmrg break; 1279ff100acSmrg case OBRACKET: 1289ff100acSmrg snprintf(buf, sizeof(buf), "OBRACKET"); 1299ff100acSmrg break; 1309ff100acSmrg case CBRACKET: 1319ff100acSmrg snprintf(buf, sizeof(buf), "CBRACKET"); 1329ff100acSmrg break; 1339ff100acSmrg case DOT: 1349ff100acSmrg snprintf(buf, sizeof(buf), "DOT"); 1359ff100acSmrg break; 1369ff100acSmrg case COMMA: 1379ff100acSmrg snprintf(buf, sizeof(buf), "COMMA"); 1389ff100acSmrg break; 1399ff100acSmrg case SEMI: 1409ff100acSmrg snprintf(buf, sizeof(buf), "SEMI"); 1419ff100acSmrg break; 1429ff100acSmrg case EXCLAM: 1439ff100acSmrg snprintf(buf, sizeof(buf), "EXCLAM"); 1449ff100acSmrg break; 1459ff100acSmrg case INVERT: 1469ff100acSmrg snprintf(buf, sizeof(buf), "INVERT"); 1479ff100acSmrg break; 1489ff100acSmrg 1499ff100acSmrg case STRING: 1509ff100acSmrg snprintf(buf, sizeof(buf), "STRING (%s)", scanStr); 1519ff100acSmrg break; 1529ff100acSmrg case INTEGER: 1539ff100acSmrg snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt); 1549ff100acSmrg break; 1559ff100acSmrg case FLOAT: 1569ff100acSmrg snprintf(buf, sizeof(buf), "FLOAT (%d.%d)", 1579ff100acSmrg scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM); 1589ff100acSmrg break; 1599ff100acSmrg case IDENT: 1609ff100acSmrg snprintf(buf, sizeof(buf), "IDENT (%s)", scanStr); 1619ff100acSmrg break; 1629ff100acSmrg case KEYNAME: 1639ff100acSmrg snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanStr); 1649ff100acSmrg break; 1659ff100acSmrg default: 1669ff100acSmrg snprintf(buf, sizeof(buf), "UNKNOWN"); 1679ff100acSmrg break; 16876910425Smrg } 16976910425Smrg return buf; 17076910425Smrg} 17176910425Smrg#endif 17276910425Smrg 17376910425Smrgint 1749ff100acSmrgsetScanState(const char *file, int line) 17576910425Smrg{ 1769ff100acSmrg if (file != NULL) 1779ff100acSmrg strncpy(scanFile, file, 1024); 1789ff100acSmrg if (line >= 0) 1799ff100acSmrg lineNum = line; 18076910425Smrg return 1; 18176910425Smrg} 18276910425Smrg 18376910425Smrgstatic int 18476910425SmrgyyGetString(void) 18576910425Smrg{ 1869ff100acSmrg int ch; 18776910425Smrg 18876910425Smrg nInBuf = 0; 1899ff100acSmrg while (((ch = getc(yyin)) != EOF) && (ch != '"')) { 1909ff100acSmrg if (ch == '\\') { 1919ff100acSmrg if ((ch = getc(yyin)) != EOF) { 1929ff100acSmrg if (ch == 'n') 1939ff100acSmrg ch = '\n'; 1949ff100acSmrg else if (ch == 't') 1959ff100acSmrg ch = '\t'; 1969ff100acSmrg else if (ch == 'v') 1979ff100acSmrg ch = '\v'; 1989ff100acSmrg else if (ch == 'b') 1999ff100acSmrg ch = '\b'; 2009ff100acSmrg else if (ch == 'r') 2019ff100acSmrg ch = '\r'; 2029ff100acSmrg else if (ch == 'f') 2039ff100acSmrg ch = '\f'; 2049ff100acSmrg else if (ch == 'e') 2059ff100acSmrg ch = '\033'; 2069ff100acSmrg else if (ch == '0') { 2079ff100acSmrg int tmp, stop; 2089ff100acSmrg 2099ff100acSmrg ch = stop = 0; 2109ff100acSmrg if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) && 2119ff100acSmrg (tmp != '8') && (tmp != '9')) { 2129ff100acSmrg ch = (ch * 8) + (tmp - '0'); 2139ff100acSmrg } 2149ff100acSmrg else { 2159ff100acSmrg stop = 1; 2169ff100acSmrg ungetc(tmp, yyin); 2179ff100acSmrg } 2189ff100acSmrg if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) 2199ff100acSmrg && (tmp != '8') && (tmp != '9')) { 2209ff100acSmrg ch = (ch * 8) + (tmp - '0'); 2219ff100acSmrg } 2229ff100acSmrg else { 2239ff100acSmrg stop = 1; 2249ff100acSmrg ungetc(tmp, yyin); 2259ff100acSmrg } 2269ff100acSmrg if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) 2279ff100acSmrg && (tmp != '8') && (tmp != '9')) { 2289ff100acSmrg ch = (ch * 8) + (tmp - '0'); 2299ff100acSmrg } 2309ff100acSmrg else { 2319ff100acSmrg stop = 1; 2329ff100acSmrg ungetc(tmp, yyin); 2339ff100acSmrg } 2349ff100acSmrg } 2359ff100acSmrg } 2369ff100acSmrg else 2379ff100acSmrg return ERROR; 2389ff100acSmrg } 2399ff100acSmrg 2409ff100acSmrg if (nInBuf < BUFSIZE - 1) 2419ff100acSmrg buf[nInBuf++] = ch; 24276910425Smrg } 2439ff100acSmrg if (ch == '"') { 2449ff100acSmrg buf[nInBuf++] = '\0'; 2459ff100acSmrg if (scanStr) 2469ff100acSmrg free(scanStr); 2479ff100acSmrg scanStr = uStringDup(buf); 2489ff100acSmrg scanStrLine = lineNum; 2499ff100acSmrg return STRING; 25076910425Smrg } 25176910425Smrg return ERROR; 25276910425Smrg} 25376910425Smrg 25476910425Smrgstatic int 25576910425SmrgyyGetKeyName(void) 25676910425Smrg{ 2579ff100acSmrg int ch; 25876910425Smrg 25976910425Smrg nInBuf = 0; 2609ff100acSmrg while (((ch = getc(yyin)) != EOF) && (ch != '>')) { 2619ff100acSmrg if (ch == '\\') { 2629ff100acSmrg if ((ch = getc(yyin)) != EOF) { 2639ff100acSmrg if (ch == 'n') 2649ff100acSmrg ch = '\n'; 2659ff100acSmrg else if (ch == 't') 2669ff100acSmrg ch = '\t'; 2679ff100acSmrg else if (ch == 'v') 2689ff100acSmrg ch = '\v'; 2699ff100acSmrg else if (ch == 'b') 2709ff100acSmrg ch = '\b'; 2719ff100acSmrg else if (ch == 'r') 2729ff100acSmrg ch = '\r'; 2739ff100acSmrg else if (ch == 'f') 2749ff100acSmrg ch = '\f'; 2759ff100acSmrg else if (ch == 'e') 2769ff100acSmrg ch = '\033'; 2779ff100acSmrg else if (ch == '0') { 2789ff100acSmrg int tmp, stop; 2799ff100acSmrg 2809ff100acSmrg ch = stop = 0; 2819ff100acSmrg if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) && 2829ff100acSmrg (tmp != '8') && (tmp != '9')) { 2839ff100acSmrg ch = (ch * 8) + (tmp - '0'); 2849ff100acSmrg } 2859ff100acSmrg else { 2869ff100acSmrg stop = 1; 2879ff100acSmrg ungetc(tmp, yyin); 2889ff100acSmrg } 2899ff100acSmrg if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) 2909ff100acSmrg && (tmp != '8') && (tmp != '9')) { 2919ff100acSmrg ch = (ch * 8) + (tmp - '0'); 2929ff100acSmrg } 2939ff100acSmrg else { 2949ff100acSmrg stop = 1; 2959ff100acSmrg ungetc(tmp, yyin); 2969ff100acSmrg } 2979ff100acSmrg if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) 2989ff100acSmrg && (tmp != '8') && (tmp != '9')) { 2999ff100acSmrg ch = (ch * 8) + (tmp - '0'); 3009ff100acSmrg } 3019ff100acSmrg else { 3029ff100acSmrg stop = 1; 3039ff100acSmrg ungetc(tmp, yyin); 3049ff100acSmrg } 3059ff100acSmrg } 3069ff100acSmrg } 3079ff100acSmrg else 3089ff100acSmrg return ERROR; 3099ff100acSmrg } 3109ff100acSmrg 3119ff100acSmrg if (nInBuf < BUFSIZE - 1) 3129ff100acSmrg buf[nInBuf++] = ch; 31376910425Smrg } 3149ff100acSmrg if ((ch == '>') && (nInBuf < 5)) { 3159ff100acSmrg buf[nInBuf++] = '\0'; 3169ff100acSmrg if (scanStr) 3179ff100acSmrg free(scanStr); 3189ff100acSmrg scanStr = uStringDup(buf); 3199ff100acSmrg scanStrLine = lineNum; 3209ff100acSmrg return KEYNAME; 32176910425Smrg } 32276910425Smrg return ERROR; 32376910425Smrg} 32476910425Smrg 325db17cd6dSmrgstatic struct _Keyword { 3269ff100acSmrg const char *keyword; 3279ff100acSmrg int token; 32876910425Smrg} keywords[] = { 3299ff100acSmrg { "bell", BELL }, 3309ff100acSmrg { "accessx", ACCESSX }, 3319ff100acSmrg { "message", MESSAGE }, 3329ff100acSmrg { "none", NONE }, 3339ff100acSmrg { "ignore", IGNORE }, 3349ff100acSmrg { "echo", ECHO }, 3359ff100acSmrg { "printevent", PRINT_EV }, 3369ff100acSmrg { "shell", SHELL }, 3379ff100acSmrg { "sound", SOUND } 33876910425Smrg}; 3399ff100acSmrgstatic int numKeywords = sizeof(keywords) / sizeof(struct _Keyword); 34076910425Smrg 34176910425Smrgstatic int 34276910425SmrgyyGetIdent(int first) 34376910425Smrg{ 344a67f45c3Smrg int ch, found; 3459ff100acSmrg int rtrn = -1; 34676910425Smrg 3479ff100acSmrg buf[0] = first; 3489ff100acSmrg nInBuf = 1; 3499ff100acSmrg while (((ch = getc(yyin)) != EOF) && (isalnum(ch) || (ch == '_'))) { 3509ff100acSmrg if (nInBuf < BUFSIZE - 1) 3519ff100acSmrg buf[nInBuf++] = ch; 35276910425Smrg } 35376910425Smrg buf[nInBuf++] = '\0'; 3549ff100acSmrg found = 0; 35576910425Smrg 356a67f45c3Smrg for (int i = 0; (!found) && (i < numKeywords); i++) { 3579ff100acSmrg if (uStrCaseCmp(buf, keywords[i].keyword) == 0) { 3589ff100acSmrg rtrn = keywords[i].token; 3599ff100acSmrg found = 1; 3609ff100acSmrg } 36176910425Smrg } 36276910425Smrg if (!found) { 3639ff100acSmrg if (scanStr) 3649ff100acSmrg free(scanStr); 3659ff100acSmrg scanStr = uStringDup(buf); 3669ff100acSmrg scanStrLine = lineNum; 3679ff100acSmrg rtrn = IDENT; 36876910425Smrg } 36976910425Smrg 3709ff100acSmrg if ((ch != EOF) && (!isspace(ch))) 3719ff100acSmrg ungetc(ch, yyin); 3729ff100acSmrg else if (ch == '\n') 3739ff100acSmrg lineNum++; 37476910425Smrg 37576910425Smrg return rtrn; 37676910425Smrg} 37776910425Smrg 37876910425Smrgstatic int 37976910425SmrgyyGetNumber(int ch) 38076910425Smrg{ 3819ff100acSmrg int isFloat = 0; 38276910425Smrg 3839ff100acSmrg buf[0] = ch; 3849ff100acSmrg nInBuf = 1; 3859ff100acSmrg while (((ch = getc(yyin)) != EOF) && 3869ff100acSmrg (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x')))) { 3879ff100acSmrg buf[nInBuf++] = ch; 38876910425Smrg } 3899ff100acSmrg if (ch == '.') { 3909ff100acSmrg isFloat = 1; 3919ff100acSmrg buf[nInBuf++] = ch; 3929ff100acSmrg while (((ch = getc(yyin)) != EOF) && (isxdigit(ch))) { 3939ff100acSmrg buf[nInBuf++] = ch; 3949ff100acSmrg } 39576910425Smrg } 3969ff100acSmrg buf[nInBuf++] = '\0'; 3979ff100acSmrg if ((ch != EOF) && (!isspace(ch))) 3989ff100acSmrg ungetc(ch, yyin); 39976910425Smrg 40076910425Smrg if (isFloat) { 4019ff100acSmrg float tmp; 4029ff100acSmrg 4039ff100acSmrg if (sscanf(buf, "%g", &tmp) == 1) { 4049ff100acSmrg scanInt = tmp * XkbGeomPtsPerMM; 4059ff100acSmrg return FLOAT; 4069ff100acSmrg } 40776910425Smrg } 4089ff100acSmrg else if (sscanf(buf, "%i", &scanInt) == 1) 4099ff100acSmrg return INTEGER; 4109ff100acSmrg fprintf(stderr, "Malformed number %s\n", buf); 41176910425Smrg return ERROR; 41276910425Smrg} 41376910425Smrg 41476910425Smrgint 41576910425Smrgyylex(void) 41676910425Smrg{ 4179ff100acSmrg int ch; 4189ff100acSmrg int rtrn; 4199ff100acSmrg 42076910425Smrg do { 4219ff100acSmrg ch = getc(yyin); 4229ff100acSmrg if (ch == '\n') { 4239ff100acSmrg lineNum++; 4249ff100acSmrg } 4259ff100acSmrg else if (ch == '/') { /* handle C++ style double-/ comments */ 4269ff100acSmrg int newch = getc(yyin); 4279ff100acSmrg 4289ff100acSmrg if (newch == '/') { 4299ff100acSmrg do { 4309ff100acSmrg ch = getc(yyin); 4319ff100acSmrg } while ((ch != '\n') && (ch != EOF)); 4329ff100acSmrg lineNum++; 4339ff100acSmrg } 4349ff100acSmrg else if (newch != EOF) { 4359ff100acSmrg ungetc(newch, yyin); 4369ff100acSmrg } 4379ff100acSmrg } 4389ff100acSmrg } while ((ch != EOF) && (isspace(ch))); 4399ff100acSmrg if (ch == '=') 4409ff100acSmrg rtrn = EQUALS; 4419ff100acSmrg else if (ch == '+') 4429ff100acSmrg rtrn = PLUS; 4439ff100acSmrg else if (ch == '-') 4449ff100acSmrg rtrn = MINUS; 4459ff100acSmrg else if (ch == '/') 4469ff100acSmrg rtrn = DIVIDE; 4479ff100acSmrg else if (ch == '*') 4489ff100acSmrg rtrn = TIMES; 4499ff100acSmrg else if (ch == '{') 4509ff100acSmrg rtrn = OBRACE; 4519ff100acSmrg else if (ch == '}') 4529ff100acSmrg rtrn = CBRACE; 4539ff100acSmrg else if (ch == '(') 4549ff100acSmrg rtrn = OPAREN; 4559ff100acSmrg else if (ch == ')') 4569ff100acSmrg rtrn = CPAREN; 4579ff100acSmrg else if (ch == '[') 4589ff100acSmrg rtrn = OBRACKET; 4599ff100acSmrg else if (ch == ']') 4609ff100acSmrg rtrn = CBRACKET; 4619ff100acSmrg else if (ch == '.') 4629ff100acSmrg rtrn = DOT; 4639ff100acSmrg else if (ch == ',') 4649ff100acSmrg rtrn = COMMA; 4659ff100acSmrg else if (ch == ';') 4669ff100acSmrg rtrn = SEMI; 4679ff100acSmrg else if (ch == '!') 4689ff100acSmrg rtrn = EXCLAM; 4699ff100acSmrg else if (ch == '~') 4709ff100acSmrg rtrn = INVERT; 4719ff100acSmrg else if (ch == '"') 4729ff100acSmrg rtrn = yyGetString(); 4739ff100acSmrg else if (ch == '<') 4749ff100acSmrg rtrn = yyGetKeyName(); 475a67f45c3Smrg else if (ch == EOF) 476a67f45c3Smrg rtrn = END_OF_FILE; 4779ff100acSmrg else if (isalpha(ch) || (ch == '_')) 4789ff100acSmrg rtrn = yyGetIdent(ch); 4799ff100acSmrg else if (isdigit(ch)) 4809ff100acSmrg rtrn = yyGetNumber(ch); 48176910425Smrg else { 4829ff100acSmrg fprintf(stderr, "Unexpected character %c (%d) in input stream\n", 4839ff100acSmrg ch, ch); 4849ff100acSmrg rtrn = ERROR; 48576910425Smrg } 48676910425Smrg#ifdef DEBUG 4879ff100acSmrg if (debugFlags & 0x2) 4889ff100acSmrg fprintf(stderr, "scan: %s\n", tokText(rtrn)); 48976910425Smrg#endif 49076910425Smrg return rtrn; 49176910425Smrg} 492