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