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