xkbscan.c revision 1d8c7986
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 38unsigned int scanDebug; 39 40FILE *yyin = NULL; 41 42static char scanFileBuf[1024] = {0}; 43char *scanFile = scanFileBuf; 44int lineNum = 0; 45 46int scanInt; 47 48char scanBuf[1024]; 49static int scanStrLine = 0; 50 51#define BUFSIZE 4096 52static char readBuf[BUFSIZE]; 53static int readBufPos = 0; 54static int readBufLen = 0; 55 56#ifdef DEBUG 57extern int debugFlags; 58 59static char * 60tokText(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 272static int 273scanchar(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 287static void 288unscanchar(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 298int 299setScanState(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 308static int 309yyGetString(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 391static int 392yyGetKeyName(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 469static 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}; 566static int numKeywords = sizeof(keywords) / sizeof(struct _Keyword); 567 568static int 569yyGetIdent(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 606static int 607yyGetNumber(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 651int 652yylex(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} 749