parseutils.c revision 83e5f723
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(KeySym sym, 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 def->sym = sym; 233 def->match = match; 234 } 235 else 236 { 237 FATAL("Couldn't allocate interp definition in parser\n"); 238 /* NOTREACHED */ 239 } 240 return def; 241} 242 243KeyTypeDef * 244KeyTypeCreate(Atom name, VarDef * body) 245{ 246 KeyTypeDef *def; 247 248 def = uTypedAlloc(KeyTypeDef); 249 if (def) 250 { 251 def->common.stmtType = StmtKeyTypeDef; 252 def->common.next = NULL; 253 def->merge = MergeDefault; 254 def->name = name; 255 def->body = body; 256 } 257 else 258 { 259 FATAL("Couldn't allocate key type definition in parser\n"); 260 /* NOTREACHED */ 261 } 262 return def; 263} 264 265SymbolsDef * 266SymbolsCreate(char *keyName, ExprDef * symbols) 267{ 268 SymbolsDef *def; 269 270 def = uTypedAlloc(SymbolsDef); 271 if (def) 272 { 273 def->common.stmtType = StmtSymbolsDef; 274 def->common.next = NULL; 275 def->merge = MergeDefault; 276 bzero(def->keyName, 5); 277 strncpy(def->keyName, keyName, 4); 278 def->symbols = symbols; 279 } 280 else 281 { 282 FATAL("Couldn't allocate symbols definition in parser\n"); 283 /* NOTREACHED */ 284 } 285 return def; 286} 287 288GroupCompatDef * 289GroupCompatCreate(int group, ExprDef * val) 290{ 291 GroupCompatDef *def; 292 293 def = uTypedAlloc(GroupCompatDef); 294 if (def) 295 { 296 def->common.stmtType = StmtGroupCompatDef; 297 def->common.next = NULL; 298 def->merge = MergeDefault; 299 def->group = group; 300 def->def = val; 301 } 302 else 303 { 304 FATAL("Couldn't allocate group compat definition in parser\n"); 305 /* NOTREACHED */ 306 } 307 return def; 308} 309 310ModMapDef * 311ModMapCreate(Atom modifier, ExprDef * keys) 312{ 313 ModMapDef *def; 314 315 def = uTypedAlloc(ModMapDef); 316 if (def) 317 { 318 def->common.stmtType = StmtModMapDef; 319 def->common.next = NULL; 320 def->merge = MergeDefault; 321 def->modifier = modifier; 322 def->keys = keys; 323 } 324 else 325 { 326 FATAL("Couldn't allocate mod mask definition in parser\n"); 327 /* NOTREACHED */ 328 } 329 return def; 330} 331 332IndicatorMapDef * 333IndicatorMapCreate(Atom name, VarDef * body) 334{ 335 IndicatorMapDef *def; 336 337 def = uTypedAlloc(IndicatorMapDef); 338 if (def) 339 { 340 def->common.stmtType = StmtIndicatorMapDef; 341 def->common.next = NULL; 342 def->merge = MergeDefault; 343 def->name = name; 344 def->body = body; 345 } 346 else 347 { 348 FATAL("Couldn't allocate indicator map definition in parser\n"); 349 /* NOTREACHED */ 350 } 351 return def; 352} 353 354IndicatorNameDef * 355IndicatorNameCreate(int ndx, ExprDef * name, Bool virtual) 356{ 357 IndicatorNameDef *def; 358 359 def = uTypedAlloc(IndicatorNameDef); 360 if (def) 361 { 362 def->common.stmtType = StmtIndicatorNameDef; 363 def->common.next = NULL; 364 def->merge = MergeDefault; 365 def->ndx = ndx; 366 def->name = name; 367 def->virtual = virtual; 368 } 369 else 370 { 371 FATAL("Couldn't allocate indicator index definition in parser\n"); 372 /* NOTREACHED */ 373 } 374 return def; 375} 376 377ExprDef * 378ActionCreate(Atom name, ExprDef * args) 379{ 380 ExprDef *act; 381 382 act = uTypedAlloc(ExprDef); 383 if (act) 384 { 385 act->common.stmtType = StmtExpr; 386 act->common.next = NULL; 387 act->op = ExprActionDecl; 388 act->value.action.name = name; 389 act->value.action.args = args; 390 return act; 391 } 392 FATAL("Couldn't allocate ActionDef in parser\n"); 393 return NULL; 394} 395 396ExprDef * 397CreateKeysymList(char *sym) 398{ 399 ExprDef *def; 400 401 def = ExprCreate(ExprKeysymList, TypeSymbols); 402 if (def) 403 { 404 def->value.list.nSyms = 1; 405 def->value.list.szSyms = 4; 406 def->value.list.syms = uTypedCalloc(4, char *); 407 if (def->value.list.syms != NULL) 408 { 409 def->value.list.syms[0] = sym; 410 return def; 411 } 412 } 413 FATAL("Couldn't allocate expression for keysym list in parser\n"); 414 return NULL; 415} 416 417ShapeDef * 418ShapeDeclCreate(Atom name, OutlineDef * outlines) 419{ 420 ShapeDef *shape; 421 OutlineDef *ol; 422 423 shape = uTypedAlloc(ShapeDef); 424 if (shape != NULL) 425 { 426 bzero(shape, sizeof(ShapeDef)); 427 shape->common.stmtType = StmtShapeDef; 428 shape->common.next = NULL; 429 shape->merge = MergeDefault; 430 shape->name = name; 431 shape->nOutlines = 0; 432 shape->outlines = outlines; 433 for (ol = outlines; ol != NULL; ol = (OutlineDef *) ol->common.next) 434 { 435 if (ol->nPoints > 0) 436 shape->nOutlines++; 437 } 438 } 439 return shape; 440} 441 442OutlineDef * 443OutlineCreate(Atom field, ExprDef * points) 444{ 445 OutlineDef *outline; 446 ExprDef *pt; 447 448 outline = uTypedAlloc(OutlineDef); 449 if (outline != NULL) 450 { 451 bzero(outline, sizeof(OutlineDef)); 452 outline->common.stmtType = StmtOutlineDef; 453 outline->common.next = NULL; 454 outline->field = field; 455 outline->nPoints = 0; 456 if (points->op == ExprCoord) 457 { 458 for (pt = points; pt != NULL; pt = (ExprDef *) pt->common.next) 459 { 460 outline->nPoints++; 461 } 462 } 463 outline->points = points; 464 } 465 return outline; 466} 467 468KeyDef * 469KeyDeclCreate(char *name, ExprDef * expr) 470{ 471 KeyDef *key; 472 473 key = uTypedAlloc(KeyDef); 474 if (key != NULL) 475 { 476 bzero(key, sizeof(KeyDef)); 477 key->common.stmtType = StmtKeyDef; 478 key->common.next = NULL; 479 if (name) 480 key->name = name; 481 else 482 key->expr = expr; 483 } 484 return key; 485} 486 487KeyDef * 488KeyDeclMerge(KeyDef * into, KeyDef * from) 489{ 490 into->expr = 491 (ExprDef *) AppendStmt(&into->expr->common, &from->expr->common); 492 from->expr = NULL; 493 uFree(from); 494 return into; 495} 496 497RowDef * 498RowDeclCreate(KeyDef * keys) 499{ 500 RowDef *row; 501 KeyDef *key; 502 503 row = uTypedAlloc(RowDef); 504 if (row != NULL) 505 { 506 bzero(row, sizeof(RowDef)); 507 row->common.stmtType = StmtRowDef; 508 row->common.next = NULL; 509 row->nKeys = 0; 510 row->keys = keys; 511 for (key = keys; key != NULL; key = (KeyDef *) key->common.next) 512 { 513 if (key->common.stmtType == StmtKeyDef) 514 row->nKeys++; 515 } 516 } 517 return row; 518} 519 520SectionDef * 521SectionDeclCreate(Atom name, RowDef * rows) 522{ 523 SectionDef *section; 524 RowDef *row; 525 526 section = uTypedAlloc(SectionDef); 527 if (section != NULL) 528 { 529 bzero(section, sizeof(SectionDef)); 530 section->common.stmtType = StmtSectionDef; 531 section->common.next = NULL; 532 section->name = name; 533 section->nRows = 0; 534 section->rows = rows; 535 for (row = rows; row != NULL; row = (RowDef *) row->common.next) 536 { 537 if (row->common.stmtType == StmtRowDef) 538 section->nRows++; 539 } 540 } 541 return section; 542} 543 544OverlayKeyDef * 545OverlayKeyCreate(char *under, char *over) 546{ 547 OverlayKeyDef *key; 548 549 key = uTypedAlloc(OverlayKeyDef); 550 if (key != NULL) 551 { 552 bzero(key, sizeof(OverlayKeyDef)); 553 key->common.stmtType = StmtOverlayKeyDef; 554 strncpy(key->over, over, XkbKeyNameLength); 555 strncpy(key->under, under, XkbKeyNameLength); 556 if (over) 557 uFree(over); 558 if (under) 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(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, "0x%x", stmt); 749 if (stmt) 750 { 751 do 752 { 753 fprintf(stderr, "->0x%x", 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 yyin = 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