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