parseutils.c revision 3fb1fa07
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#define DEBUG_VAR parseDebug 28#include "parseutils.h" 29#include "xkbpath.h" 30#include <X11/keysym.h> 31#include <X11/extensions/XKBgeom.h> 32#include <limits.h> 33#include <stdlib.h> 34 35XkbFile *rtrnValue; 36 37ParseCommon * 38AppendStmt(ParseCommon * to, ParseCommon * append) 39{ 40 ParseCommon *start = to; 41 42 if (append == NULL) 43 return to; 44 while ((to != NULL) && (to->next != NULL)) 45 { 46 to = to->next; 47 } 48 if (to) 49 { 50 to->next = append; 51 return start; 52 } 53 return append; 54} 55 56ExprDef * 57ExprCreate(unsigned op, unsigned type) 58{ 59 ExprDef *expr; 60 expr = uTypedAlloc(ExprDef); 61 if (expr) 62 { 63 expr->common.stmtType = StmtExpr; 64 expr->common.next = NULL; 65 expr->op = op; 66 expr->type = type; 67 } 68 else 69 { 70 FATAL("Couldn't allocate expression in parser\n"); 71 /* NOTREACHED */ 72 } 73 return expr; 74} 75 76ExprDef * 77ExprCreateUnary(unsigned op, unsigned type, ExprDef * child) 78{ 79 ExprDef *expr; 80 expr = uTypedAlloc(ExprDef); 81 if (expr) 82 { 83 expr->common.stmtType = StmtExpr; 84 expr->common.next = NULL; 85 expr->op = op; 86 expr->type = type; 87 expr->value.child = child; 88 } 89 else 90 { 91 FATAL("Couldn't allocate expression in parser\n"); 92 /* NOTREACHED */ 93 } 94 return expr; 95} 96 97ExprDef * 98ExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right) 99{ 100 ExprDef *expr; 101 expr = uTypedAlloc(ExprDef); 102 if (expr) 103 { 104 expr->common.stmtType = StmtExpr; 105 expr->common.next = NULL; 106 expr->op = op; 107 if ((op == OpAssign) || (left->type == TypeUnknown)) 108 expr->type = right->type; 109 else if ((left->type == right->type) || (right->type == TypeUnknown)) 110 expr->type = left->type; 111 else 112 expr->type = TypeUnknown; 113 expr->value.binary.left = left; 114 expr->value.binary.right = right; 115 } 116 else 117 { 118 FATAL("Couldn't allocate expression in parser\n"); 119 /* NOTREACHED */ 120 } 121 return expr; 122} 123 124KeycodeDef * 125KeycodeCreate(char *name, ExprDef * value) 126{ 127 KeycodeDef *def; 128 129 def = uTypedAlloc(KeycodeDef); 130 if (def) 131 { 132 def->common.stmtType = StmtKeycodeDef; 133 def->common.next = NULL; 134 strncpy(def->name, name, XkbKeyNameLength); 135 def->name[XkbKeyNameLength] = '\0'; 136 def->value = value; 137 } 138 else 139 { 140 FATAL("Couldn't allocate key name definition in parser\n"); 141 /* NOTREACHED */ 142 } 143 return def; 144} 145 146KeyAliasDef * 147KeyAliasCreate(char *alias, char *real) 148{ 149 KeyAliasDef *def; 150 151 def = uTypedAlloc(KeyAliasDef); 152 if (def) 153 { 154 def->common.stmtType = StmtKeyAliasDef; 155 def->common.next = NULL; 156 strncpy(def->alias, alias, XkbKeyNameLength); 157 def->alias[XkbKeyNameLength] = '\0'; 158 strncpy(def->real, real, XkbKeyNameLength); 159 def->real[XkbKeyNameLength] = '\0'; 160 } 161 else 162 { 163 FATAL("Couldn't allocate key alias definition in parser\n"); 164 /* NOTREACHED */ 165 } 166 return def; 167} 168 169VModDef * 170VModCreate(Atom name, ExprDef * value) 171{ 172 VModDef *def; 173 def = uTypedAlloc(VModDef); 174 if (def) 175 { 176 def->common.stmtType = StmtVModDef; 177 def->common.next = NULL; 178 def->name = name; 179 def->value = value; 180 } 181 else 182 { 183 FATAL("Couldn't allocate variable definition in parser\n"); 184 /* NOTREACHED */ 185 } 186 return def; 187} 188 189VarDef * 190VarCreate(ExprDef * name, ExprDef * value) 191{ 192 VarDef *def; 193 def = uTypedAlloc(VarDef); 194 if (def) 195 { 196 def->common.stmtType = StmtVarDef; 197 def->common.next = NULL; 198 def->name = name; 199 def->value = value; 200 } 201 else 202 { 203 FATAL("Couldn't allocate variable definition in parser\n"); 204 /* NOTREACHED */ 205 } 206 return def; 207} 208 209VarDef * 210BoolVarCreate(Atom nameToken, unsigned set) 211{ 212 ExprDef *name, *value; 213 214 name = ExprCreate(ExprIdent, TypeUnknown); 215 name->value.str = nameToken; 216 value = ExprCreate(ExprValue, TypeBoolean); 217 value->value.uval = set; 218 return VarCreate(name, value); 219} 220 221InterpDef * 222InterpCreate(const char *sym_str, ExprDef * match) 223{ 224 InterpDef *def; 225 226 def = uTypedAlloc(InterpDef); 227 if (def) 228 { 229 def->common.stmtType = StmtInterpDef; 230 def->common.next = NULL; 231 if (LookupKeysym(sym_str, &def->sym) == 0) 232 def->ignore = True; 233 else 234 def->ignore = False; 235 def->match = match; 236 } 237 else 238 { 239 FATAL("Couldn't allocate interp definition in parser\n"); 240 /* NOTREACHED */ 241 } 242 return def; 243} 244 245KeyTypeDef * 246KeyTypeCreate(Atom name, VarDef * body) 247{ 248 KeyTypeDef *def; 249 250 def = uTypedAlloc(KeyTypeDef); 251 if (def) 252 { 253 def->common.stmtType = StmtKeyTypeDef; 254 def->common.next = NULL; 255 def->merge = MergeDefault; 256 def->name = name; 257 def->body = body; 258 } 259 else 260 { 261 FATAL("Couldn't allocate key type definition in parser\n"); 262 /* NOTREACHED */ 263 } 264 return def; 265} 266 267SymbolsDef * 268SymbolsCreate(char *keyName, ExprDef * symbols) 269{ 270 SymbolsDef *def; 271 272 def = uTypedAlloc(SymbolsDef); 273 if (def) 274 { 275 def->common.stmtType = StmtSymbolsDef; 276 def->common.next = NULL; 277 def->merge = MergeDefault; 278 bzero(def->keyName, 5); 279 strncpy(def->keyName, keyName, 4); 280 def->symbols = symbols; 281 } 282 else 283 { 284 FATAL("Couldn't allocate symbols definition in parser\n"); 285 /* NOTREACHED */ 286 } 287 return def; 288} 289 290GroupCompatDef * 291GroupCompatCreate(int group, ExprDef * val) 292{ 293 GroupCompatDef *def; 294 295 def = uTypedAlloc(GroupCompatDef); 296 if (def) 297 { 298 def->common.stmtType = StmtGroupCompatDef; 299 def->common.next = NULL; 300 def->merge = MergeDefault; 301 def->group = group; 302 def->def = val; 303 } 304 else 305 { 306 FATAL("Couldn't allocate group compat definition in parser\n"); 307 /* NOTREACHED */ 308 } 309 return def; 310} 311 312ModMapDef * 313ModMapCreate(Atom modifier, ExprDef * keys) 314{ 315 ModMapDef *def; 316 317 def = uTypedAlloc(ModMapDef); 318 if (def) 319 { 320 def->common.stmtType = StmtModMapDef; 321 def->common.next = NULL; 322 def->merge = MergeDefault; 323 def->modifier = modifier; 324 def->keys = keys; 325 } 326 else 327 { 328 FATAL("Couldn't allocate mod mask definition in parser\n"); 329 /* NOTREACHED */ 330 } 331 return def; 332} 333 334IndicatorMapDef * 335IndicatorMapCreate(Atom name, VarDef * body) 336{ 337 IndicatorMapDef *def; 338 339 def = uTypedAlloc(IndicatorMapDef); 340 if (def) 341 { 342 def->common.stmtType = StmtIndicatorMapDef; 343 def->common.next = NULL; 344 def->merge = MergeDefault; 345 def->name = name; 346 def->body = body; 347 } 348 else 349 { 350 FATAL("Couldn't allocate indicator map definition in parser\n"); 351 /* NOTREACHED */ 352 } 353 return def; 354} 355 356IndicatorNameDef * 357IndicatorNameCreate(int ndx, ExprDef * name, Bool virtual) 358{ 359 IndicatorNameDef *def; 360 361 def = uTypedAlloc(IndicatorNameDef); 362 if (def) 363 { 364 def->common.stmtType = StmtIndicatorNameDef; 365 def->common.next = NULL; 366 def->merge = MergeDefault; 367 def->ndx = ndx; 368 def->name = name; 369 def->virtual = virtual; 370 } 371 else 372 { 373 FATAL("Couldn't allocate indicator index definition in parser\n"); 374 /* NOTREACHED */ 375 } 376 return def; 377} 378 379ExprDef * 380ActionCreate(Atom name, ExprDef * args) 381{ 382 ExprDef *act; 383 384 act = uTypedAlloc(ExprDef); 385 if (act) 386 { 387 act->common.stmtType = StmtExpr; 388 act->common.next = NULL; 389 act->op = ExprActionDecl; 390 act->value.action.name = name; 391 act->value.action.args = args; 392 return act; 393 } 394 FATAL("Couldn't allocate ActionDef in parser\n"); 395 return NULL; 396} 397 398ExprDef * 399CreateKeysymList(char *sym) 400{ 401 ExprDef *def; 402 403 def = ExprCreate(ExprKeysymList, TypeSymbols); 404 if (def) 405 { 406 def->value.list.nSyms = 1; 407 def->value.list.szSyms = 4; 408 def->value.list.syms = uTypedCalloc(4, char *); 409 if (def->value.list.syms != NULL) 410 { 411 def->value.list.syms[0] = sym; 412 return def; 413 } 414 } 415 FATAL("Couldn't allocate expression for keysym list in parser\n"); 416 return NULL; 417} 418 419ShapeDef * 420ShapeDeclCreate(Atom name, OutlineDef * outlines) 421{ 422 ShapeDef *shape; 423 OutlineDef *ol; 424 425 shape = uTypedAlloc(ShapeDef); 426 if (shape != NULL) 427 { 428 bzero(shape, sizeof(ShapeDef)); 429 shape->common.stmtType = StmtShapeDef; 430 shape->common.next = NULL; 431 shape->merge = MergeDefault; 432 shape->name = name; 433 shape->nOutlines = 0; 434 shape->outlines = outlines; 435 for (ol = outlines; ol != NULL; ol = (OutlineDef *) ol->common.next) 436 { 437 if (ol->nPoints > 0) 438 shape->nOutlines++; 439 } 440 } 441 return shape; 442} 443 444OutlineDef * 445OutlineCreate(Atom field, ExprDef * points) 446{ 447 OutlineDef *outline; 448 ExprDef *pt; 449 450 outline = uTypedAlloc(OutlineDef); 451 if (outline != NULL) 452 { 453 bzero(outline, sizeof(OutlineDef)); 454 outline->common.stmtType = StmtOutlineDef; 455 outline->common.next = NULL; 456 outline->field = field; 457 outline->nPoints = 0; 458 if (points->op == ExprCoord) 459 { 460 for (pt = points; pt != NULL; pt = (ExprDef *) pt->common.next) 461 { 462 outline->nPoints++; 463 } 464 } 465 outline->points = points; 466 } 467 return outline; 468} 469 470KeyDef * 471KeyDeclCreate(char *name, ExprDef * expr) 472{ 473 KeyDef *key; 474 475 key = uTypedAlloc(KeyDef); 476 if (key != NULL) 477 { 478 bzero(key, sizeof(KeyDef)); 479 key->common.stmtType = StmtKeyDef; 480 key->common.next = NULL; 481 if (name) 482 key->name = name; 483 else 484 key->expr = expr; 485 } 486 return key; 487} 488 489KeyDef * 490KeyDeclMerge(KeyDef * into, KeyDef * from) 491{ 492 into->expr = 493 (ExprDef *) AppendStmt(&into->expr->common, &from->expr->common); 494 from->expr = NULL; 495 uFree(from); 496 return into; 497} 498 499RowDef * 500RowDeclCreate(KeyDef * keys) 501{ 502 RowDef *row; 503 KeyDef *key; 504 505 row = uTypedAlloc(RowDef); 506 if (row != NULL) 507 { 508 bzero(row, sizeof(RowDef)); 509 row->common.stmtType = StmtRowDef; 510 row->common.next = NULL; 511 row->nKeys = 0; 512 row->keys = keys; 513 for (key = keys; key != NULL; key = (KeyDef *) key->common.next) 514 { 515 if (key->common.stmtType == StmtKeyDef) 516 row->nKeys++; 517 } 518 } 519 return row; 520} 521 522SectionDef * 523SectionDeclCreate(Atom name, RowDef * rows) 524{ 525 SectionDef *section; 526 RowDef *row; 527 528 section = uTypedAlloc(SectionDef); 529 if (section != NULL) 530 { 531 bzero(section, sizeof(SectionDef)); 532 section->common.stmtType = StmtSectionDef; 533 section->common.next = NULL; 534 section->name = name; 535 section->nRows = 0; 536 section->rows = rows; 537 for (row = rows; row != NULL; row = (RowDef *) row->common.next) 538 { 539 if (row->common.stmtType == StmtRowDef) 540 section->nRows++; 541 } 542 } 543 return section; 544} 545 546OverlayKeyDef * 547OverlayKeyCreate(char *under, char *over) 548{ 549 OverlayKeyDef *key; 550 551 key = uTypedAlloc(OverlayKeyDef); 552 if (key != NULL) 553 { 554 bzero(key, sizeof(OverlayKeyDef)); 555 key->common.stmtType = StmtOverlayKeyDef; 556 strncpy(key->over, over, XkbKeyNameLength); 557 strncpy(key->under, under, XkbKeyNameLength); 558 uFree(over); 559 uFree(under); 560 } 561 return key; 562} 563 564OverlayDef * 565OverlayDeclCreate(Atom name, OverlayKeyDef * keys) 566{ 567 OverlayDef *ol; 568 OverlayKeyDef *key; 569 570 ol = uTypedAlloc(OverlayDef); 571 if (ol != NULL) 572 { 573 bzero(ol, sizeof(OverlayDef)); 574 ol->common.stmtType = StmtOverlayDef; 575 ol->name = name; 576 ol->keys = keys; 577 for (key = keys; key != NULL; 578 key = (OverlayKeyDef *) key->common.next) 579 { 580 ol->nKeys++; 581 } 582 } 583 return ol; 584} 585 586DoodadDef * 587DoodadCreate(unsigned type, Atom name, VarDef * body) 588{ 589 DoodadDef *doodad; 590 591 doodad = uTypedAlloc(DoodadDef); 592 if (doodad != NULL) 593 { 594 bzero(doodad, sizeof(DoodadDef)); 595 doodad->common.stmtType = StmtDoodadDef; 596 doodad->common.next = NULL; 597 doodad->type = type; 598 doodad->name = name; 599 doodad->body = body; 600 } 601 return doodad; 602} 603 604ExprDef * 605AppendKeysymList(ExprDef * list, char *sym) 606{ 607 if (list->value.list.nSyms >= list->value.list.szSyms) 608 { 609 list->value.list.szSyms *= 2; 610 list->value.list.syms = uTypedRecalloc(list->value.list.syms, 611 list->value.list.nSyms, 612 list->value.list.szSyms, 613 char *); 614 if (list->value.list.syms == NULL) 615 { 616 FATAL("Couldn't resize list of symbols for append\n"); 617 return NULL; 618 } 619 } 620 list->value.list.syms[list->value.list.nSyms++] = sym; 621 return list; 622} 623 624int 625LookupKeysym(const char *str, KeySym * sym_rtrn) 626{ 627 KeySym sym; 628 char *tmp; 629 630 if ((!str) || (uStrCaseCmp(str, "any") == 0) 631 || (uStrCaseCmp(str, "nosymbol") == 0)) 632 { 633 *sym_rtrn = NoSymbol; 634 return 1; 635 } 636 else if ((uStrCaseCmp(str, "none") == 0) 637 || (uStrCaseCmp(str, "voidsymbol") == 0)) 638 { 639 *sym_rtrn = XK_VoidSymbol; 640 return 1; 641 } 642 sym = XStringToKeysym(str); 643 if (sym != NoSymbol) 644 { 645 *sym_rtrn = sym; 646 return 1; 647 } 648 if (strlen(str) > 2 && str[0] == '0' && str[1] == 'x') { 649 sym = strtoul(str, &tmp, 16); 650 if (sym != ULONG_MAX && (!tmp || *tmp == '\0')) { 651 *sym_rtrn = sym; 652 return 1; 653 } 654 } 655 return 0; 656} 657 658IncludeStmt * 659IncludeCreate(char *str, unsigned merge) 660{ 661 IncludeStmt *incl, *first; 662 char *file, *map, *stmt, *tmp, *extra_data; 663 char nextop; 664 Bool haveSelf; 665 666 haveSelf = False; 667 incl = first = NULL; 668 file = map = NULL; 669 tmp = str; 670 stmt = uStringDup(str); 671 while ((tmp) && (*tmp)) 672 { 673 if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data)) 674 { 675 if ((file == NULL) && (map == NULL)) 676 { 677 if (haveSelf) 678 goto BAIL; 679 haveSelf = True; 680 } 681 if (first == NULL) 682 first = incl = uTypedAlloc(IncludeStmt); 683 else 684 { 685 incl->next = uTypedAlloc(IncludeStmt); 686 incl = incl->next; 687 } 688 if (incl) 689 { 690 incl->common.stmtType = StmtInclude; 691 incl->common.next = NULL; 692 incl->merge = merge; 693 incl->stmt = NULL; 694 incl->file = file; 695 incl->map = map; 696 incl->modifier = extra_data; 697 incl->path = NULL; 698 incl->next = NULL; 699 } 700 else 701 { 702 WSGO("Allocation failure in IncludeCreate\n"); 703 ACTION("Using only part of the include\n"); 704 break; 705 } 706 if (nextop == '|') 707 merge = MergeAugment; 708 else 709 merge = MergeOverride; 710 } 711 else 712 { 713 goto BAIL; 714 } 715 } 716 if (first) 717 first->stmt = stmt; 718 else if (stmt) 719 uFree(stmt); 720 return first; 721 BAIL: 722 ERROR1("Illegal include statement \"%s\"\n", stmt); 723 ACTION("Ignored\n"); 724 while (first) 725 { 726 incl = first->next; 727 if (first->file) 728 uFree(first->file); 729 if (first->map) 730 uFree(first->map); 731 if (first->modifier) 732 uFree(first->modifier); 733 if (first->path) 734 uFree(first->path); 735 first->file = first->map = first->path = NULL; 736 uFree(first); 737 first = incl; 738 } 739 if (stmt) 740 uFree(stmt); 741 return NULL; 742} 743 744#ifdef DEBUG 745void 746PrintStmtAddrs(ParseCommon * stmt) 747{ 748 fprintf(stderr, "%p", stmt); 749 if (stmt) 750 { 751 do 752 { 753 fprintf(stderr, "->%p", stmt->next); 754 stmt = stmt->next; 755 } 756 while (stmt); 757 } 758 fprintf(stderr, "\n"); 759} 760#endif 761 762static void 763CheckDefaultMap(XkbFile * maps) 764{ 765 XkbFile *dflt, *tmp; 766 767 dflt = NULL; 768 for (tmp = maps, dflt = NULL; tmp != NULL; 769 tmp = (XkbFile *) tmp->common.next) 770 { 771 if (tmp->flags & XkbLC_Default) 772 { 773 if (dflt == NULL) 774 dflt = tmp; 775 else 776 { 777 if (warningLevel > 2) 778 { 779 WARN1("Multiple default components in %s\n", 780 (scanFile ? scanFile : "(unknown)")); 781 ACTION2("Using %s, ignoring %s\n", 782 (dflt->name ? dflt->name : "(first)"), 783 (tmp->name ? tmp->name : "(subsequent)")); 784 } 785 tmp->flags &= (~XkbLC_Default); 786 } 787 } 788 } 789 return; 790} 791 792int 793XKBParseFile(FILE * file, XkbFile ** pRtrn) 794{ 795 if (file) 796 { 797 scan_set_file(file); 798 rtrnValue = NULL; 799 if (yyparse() == 0) 800 { 801 *pRtrn = rtrnValue; 802 CheckDefaultMap(rtrnValue); 803 rtrnValue = NULL; 804 return 1; 805 } 806 *pRtrn = NULL; 807 return 0; 808 } 809 *pRtrn = NULL; 810 return 1; 811} 812 813XkbFile * 814CreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags) 815{ 816 XkbFile *file; 817 static int fileID; 818 819 file = uTypedAlloc(XkbFile); 820 if (file) 821 { 822 XkbEnsureSafeMapName(name); 823 bzero(file, sizeof(XkbFile)); 824 file->type = type; 825 file->topName = uStringDup(name); 826 file->name = name; 827 file->defs = defs; 828 file->id = fileID++; 829 file->compiled = False; 830 file->flags = flags; 831 } 832 return file; 833} 834 835unsigned 836StmtSetMerge(ParseCommon * stmt, unsigned merge) 837{ 838 if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef)) 839 { 840 yyerror("illegal use of 'alternate' merge mode"); 841 merge = MergeDefault; 842 } 843 return merge; 844} 845