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