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