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