1/* 2 * Copyright (c) 1999, 2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * Mach Operating System 25 * Copyright (c) 1991,1990 Carnegie Mellon University 26 * All Rights Reserved. 27 * 28 * Permission to use, copy, modify and distribute this software and its 29 * documentation is hereby granted, provided that both the copyright 30 * notice and this permission notice appear in all copies of the 31 * software, derivative works or modified versions, and any portions 32 * thereof, and that both notices appear in supporting documentation. 33 * 34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 37 * 38 * Carnegie Mellon requests users of this software to return to 39 * 40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 41 * School of Computer Science 42 * Carnegie Mellon University 43 * Pittsburgh PA 15213-3890 44 * 45 * any improvements or extensions that they make and grant Carnegie the 46 * rights to redistribute these changes. 47 */ 48 49%token sySkip 50%token syRoutine 51%token sySimpleRoutine 52 53%token sySubsystem 54%token syKernelUser 55%token syKernelServer 56 57%token syMsgOption 58%token syMsgSeqno 59%token syWaitTime 60%token sySendTime 61%token syNoWaitTime 62%token syNoSendTime 63%token syErrorProc 64%token syServerPrefix 65%token syUserPrefix 66%token syServerDemux 67%token syRCSId 68 69%token syImport 70%token syUImport 71%token sySImport 72%token syIImport 73%token syDImport 74 75%token syIn 76%token syOut 77%token syInOut 78%token syUserImpl 79%token syServerImpl 80%token syRequestPort 81%token syReplyPort 82%token sySReplyPort 83%token syUReplyPort 84 85%token syType 86%token syArray 87%token syStruct 88%token syOf 89 90%token syInTran 91%token syOutTran 92%token syDestructor 93%token syCType 94%token syCUserType 95%token syUserTypeLimit 96%token syOnStackLimit 97%token syCServerType 98%token syPointerTo 99%token syPointerToIfNot 100%token syValueOf 101 102%token syCString 103%token sySecToken 104%token syUserSecToken 105%token syServerSecToken 106%token syAuditToken 107%token syUserAuditToken 108%token syServerAuditToken 109%token syServerContextToken 110 111%token syColon 112%token sySemi 113%token syComma 114%token syPlus 115%token syMinus 116%token syStar 117%token syDiv 118%token syLParen 119%token syRParen 120%token syEqual 121%token syCaret 122%token syTilde 123%token syLAngle 124%token syRAngle 125%token syLBrack 126%token syRBrack 127%token syBar 128 129%token syError /* lex error */ 130 131%token <number> syNumber 132%token <symtype> sySymbolicType 133%token <identifier> syIdentifier 134%token <string> syString syQString 135%token <string> syFileName 136%token <flag> syIPCFlag 137 138%left syPlus syMinus 139%left syStar syDiv 140 141 142%type <statement_kind> ImportIndicant 143%type <number> VarArrayHead ArrayHead StructHead IntExp 144%type <type> NamedTypeSpec TransTypeSpec NativeTypeSpec TypeSpec 145%type <type> CStringSpec 146%type <type> BasicTypeSpec PrevTypeSpec ArgumentType 147%type <identifier> TypePhrase 148%type <symtype> PrimIPCType IPCType 149%type <routine> RoutineDecl Routine SimpleRoutine 150%type <direction> Direction TrImplKeyword 151%type <argument> Argument Trailer Arguments ArgumentList 152%type <flag> IPCFlags 153 154%{ 155 156#include <stdio.h> 157#include "lexxer.h" 158#include "strdefs.h" 159#include "type.h" 160#include "routine.h" 161#include "statement.h" 162#include "global.h" 163#include "error.h" 164 165static char *import_name(); 166extern int yylex(void); 167 168/* forward declaration */ 169void yyerror(char *s); 170 171%} 172 173%union 174{ 175 u_int number; 176 identifier_t identifier; 177 string_t string; 178 statement_kind_t statement_kind; 179 ipc_type_t *type; 180 struct 181 { 182 u_int innumber; /* msgt_name value, when sending */ 183 string_t instr; 184 u_int outnumber; /* msgt_name value, when receiving */ 185 string_t outstr; 186 u_int size; /* 0 means there is no default size */ 187 } symtype; 188 routine_t *routine; 189 arg_kind_t direction; 190 argument_t *argument; 191 ipc_flags_t flag; 192} 193 194%% 195 196Statements : /* empty */ 197 | Statements Statement 198 ; 199 200Statement : Subsystem sySemi 201 | WaitTime sySemi 202 | SendTime sySemi 203 | MsgOption sySemi 204 | UserTypeLimit sySemi 205 | OnStackLimit sySemi 206 | Error sySemi 207 | ServerPrefix sySemi 208 | UserPrefix sySemi 209 | ServerDemux sySemi 210 | TypeDecl sySemi 211 | RoutineDecl sySemi 212{ 213 register statement_t *st = stAlloc(); 214 215 st->stKind = skRoutine; 216 st->stRoutine = $1; 217 rtCheckRoutine($1); 218 if (BeVerbose) 219 rtPrintRoutine($1); 220} 221 | sySkip sySemi 222 { rtSkip(); } 223 | Import sySemi 224 | RCSDecl sySemi 225 | sySemi 226 | error sySemi 227 { yyerrok; } 228 ; 229 230Subsystem : SubsystemStart SubsystemMods 231 SubsystemName SubsystemBase 232{ 233 if (BeVerbose) { 234 printf("Subsystem %s: base = %u%s%s\n\n", 235 SubsystemName, SubsystemBase, 236 IsKernelUser ? ", KernelUser" : "", 237 IsKernelServer ? ", KernelServer" : ""); 238 } 239} 240 ; 241 242SubsystemStart : sySubsystem 243{ 244 if (SubsystemName != strNULL) { 245 warn("previous Subsystem decl (of %s) will be ignored", SubsystemName); 246 IsKernelUser = FALSE; 247 IsKernelServer = FALSE; 248 strfree(SubsystemName); 249 } 250} 251 ; 252 253SubsystemMods : /* empty */ 254 | SubsystemMods SubsystemMod 255 ; 256 257SubsystemMod : syKernelUser 258{ 259 if (IsKernelUser) 260 warn("duplicate KernelUser keyword"); 261 if (!UseMsgRPC) { 262 warn("with KernelUser the -R option is meaningless"); 263 UseMsgRPC = TRUE; 264 } 265 IsKernelUser = TRUE; 266} 267 | syKernelServer 268{ 269 if (IsKernelServer) 270 warn("duplicate KernelServer keyword"); 271 IsKernelServer = TRUE; 272} 273 ; 274 275SubsystemName : syIdentifier { SubsystemName = $1; } 276 ; 277 278SubsystemBase : syNumber { SubsystemBase = $1; } 279 ; 280 281MsgOption : LookString syMsgOption syString 282{ 283 if (streql($3, "MACH_MSG_OPTION_NONE")) { 284 MsgOption = strNULL; 285 if (BeVerbose) 286 printf("MsgOption: canceled\n\n"); 287 } 288 else { 289 MsgOption = $3; 290 if (BeVerbose) 291 printf("MsgOption %s\n\n",$3); 292 } 293} 294 ; 295 296UserTypeLimit : syUserTypeLimit syNumber 297 {UserTypeLimit = $2; } 298 ; 299OnStackLimit : syOnStackLimit syNumber 300 {MaxMessSizeOnStack = $2; } 301 ; 302 303WaitTime : LookString syWaitTime syString 304{ 305 WaitTime = $3; 306 if (BeVerbose) 307 printf("WaitTime %s\n\n", WaitTime); 308} 309 | syNoWaitTime 310{ 311 WaitTime = strNULL; 312 if (BeVerbose) 313 printf("NoWaitTime\n\n"); 314} 315 ; 316 317SendTime : LookString sySendTime syString 318{ 319 SendTime = $3; 320 if (BeVerbose) 321 printf("SendTime %s\n\n", SendTime); 322} 323 | syNoSendTime 324{ 325 SendTime = strNULL; 326 if (BeVerbose) 327 printf("NoSendTime\n\n"); 328} 329 ; 330 331Error : syErrorProc syIdentifier 332{ 333 ErrorProc = $2; 334 if (BeVerbose) 335 printf("ErrorProc %s\n\n", ErrorProc); 336} 337 ; 338 339ServerPrefix : syServerPrefix syIdentifier 340{ 341 ServerPrefix = $2; 342 if (BeVerbose) 343 printf("ServerPrefix %s\n\n", ServerPrefix); 344} 345 ; 346 347UserPrefix : syUserPrefix syIdentifier 348{ 349 UserPrefix = $2; 350 if (BeVerbose) 351 printf("UserPrefix %s\n\n", UserPrefix); 352} 353 ; 354 355ServerDemux : syServerDemux syIdentifier 356{ 357 ServerDemux = $2; 358 if (BeVerbose) 359 printf("ServerDemux %s\n\n", ServerDemux); 360} 361 ; 362 363Import : LookFileName ImportIndicant syFileName 364{ 365 register statement_t *st = stAlloc(); 366 st->stKind = $2; 367 st->stFileName = $3; 368 369 if (BeVerbose) 370 printf("%s %s\n\n", import_name($2), $3); 371} 372 ; 373 374ImportIndicant : syImport { $$ = skImport; } 375 | syUImport { $$ = skUImport; } 376 | sySImport { $$ = skSImport; } 377 | syIImport { $$ = skIImport; } 378 | syDImport { $$ = skDImport; } 379 ; 380 381RCSDecl : LookQString syRCSId syQString 382{ 383 if (RCSId != strNULL) 384 warn("previous RCS decl will be ignored"); 385 if (BeVerbose) 386 printf("RCSId %s\n\n", $3); 387 RCSId = $3; 388} 389 ; 390 391TypeDecl : syType NamedTypeSpec 392{ 393 register identifier_t name = $2->itName; 394 395 if (itLookUp(name) != itNULL) 396 warn("overriding previous definition of %s", name); 397 itInsert(name, $2); 398} 399 ; 400 401NamedTypeSpec : syIdentifier syEqual TransTypeSpec 402 { itTypeDecl($1, $$ = $3); } 403 ; 404 405TransTypeSpec : TypeSpec 406 { $$ = itResetType($1); } 407 | TransTypeSpec syInTran syColon syIdentifier 408 syIdentifier syLParen syIdentifier syRParen 409{ 410 $$ = $1; 411 412 if (($$->itTransType != strNULL) && !streql($$->itTransType, $4)) 413 warn("conflicting translation types (%s, %s)", $$->itTransType, $4); 414 $$->itTransType = $4; 415 416 if (($$->itInTrans != strNULL) && !streql($$->itInTrans, $5)) 417 warn("conflicting in-translation functions (%s, %s)", $$->itInTrans, $5); 418 $$->itInTrans = $5; 419 420 if (($$->itServerType != strNULL) && !streql($$->itServerType, $7)) 421 warn("conflicting server types (%s, %s)", $$->itServerType, $7); 422 $$->itServerType = $7; 423} 424 | TransTypeSpec syOutTran syColon syIdentifier 425 syIdentifier syLParen syIdentifier syRParen 426{ 427 $$ = $1; 428 429 if (($$->itServerType != strNULL) && !streql($$->itServerType, $4)) 430 warn("conflicting server types (%s, %s)", $$->itServerType, $4); 431 $$->itServerType = $4; 432 433 if (($$->itOutTrans != strNULL) && !streql($$->itOutTrans, $5)) 434 warn("conflicting out-translation functions (%s, %s)", $$->itOutTrans, $5); 435 $$->itOutTrans = $5; 436 437 if (($$->itTransType != strNULL) && !streql($$->itTransType, $7)) 438 warn("conflicting translation types (%s, %s)", $$->itTransType, $7); 439 $$->itTransType = $7; 440} 441 | TransTypeSpec syDestructor syColon syIdentifier 442 syLParen syIdentifier syRParen 443{ 444 $$ = $1; 445 446 if (($$->itDestructor != strNULL) && !streql($$->itDestructor, $4)) 447 warn("conflicting destructor functions (%s, %s)", $$->itDestructor, $4); 448 $$->itDestructor = $4; 449 450 if (($$->itTransType != strNULL) && !streql($$->itTransType, $6)) 451 warn("conflicting translation types (%s, %s)", $$->itTransType, $6); 452 $$->itTransType = $6; 453} 454 | TransTypeSpec syCType syColon syIdentifier 455{ 456 $$ = $1; 457 458 if (($$->itUserType != strNULL) && !streql($$->itUserType, $4)) 459 warn("conflicting user types (%s, %s)", $$->itUserType, $4); 460 $$->itUserType = $4; 461 462 if (($$->itServerType != strNULL) && !streql($$->itServerType, $4)) 463 warn("conflicting server types (%s, %s)", $$->itServerType, $4); 464 $$->itServerType = $4; 465} 466 | TransTypeSpec syCUserType syColon syIdentifier 467{ 468 $$ = $1; 469 470 if (($$->itUserType != strNULL) && !streql($$->itUserType, $4)) 471 warn("conflicting user types (%s, %s)", $$->itUserType, $4); 472 $$->itUserType = $4; 473} 474 | TransTypeSpec syCServerType 475 syColon syIdentifier 476{ 477 $$ = $1; 478 479 if (($$->itServerType != strNULL) && !streql($$->itServerType, $4)) 480 warn("conflicting server types (%s, %s)", 481 $$->itServerType, $4); 482 $$->itServerType = $4; 483} 484 ; 485 486TypeSpec : BasicTypeSpec 487 { $$ = $1; } 488 | PrevTypeSpec 489 { $$ = $1; } 490 | VarArrayHead TypeSpec 491 { $$ = itVarArrayDecl($1, $2); } 492 | ArrayHead TypeSpec 493 { $$ = itArrayDecl($1, $2); } 494 | syCaret TypeSpec 495 { $$ = itPtrDecl($2); } 496 | StructHead TypeSpec 497 { $$ = itStructDecl($1, $2); } 498 | CStringSpec 499 { $$ = $1; } 500 | NativeTypeSpec 501 { $$ = $1; } 502 ; 503 504NativeTypeSpec : syPointerTo syLParen TypePhrase syRParen 505 { $$ = itNativeType($3, TRUE, 0); } 506 | syPointerToIfNot syLParen TypePhrase syComma 507 TypePhrase syRParen 508 { $$ = itNativeType($3, TRUE, $5); } 509 | syValueOf syLParen TypePhrase syRParen 510 { $$ = itNativeType($3, FALSE, 0); } 511 ; 512 513BasicTypeSpec : IPCType 514{ 515 $$ = itShortDecl($1.innumber, $1.instr, 516 $1.outnumber, $1.outstr, 517 $1.size); 518} 519 | syLParen IPCType syComma IntExp 520 IPCFlags syRParen 521{ 522 error("Long form type declarations aren't allowed any longer\n"); 523} 524 ; 525 526PrimIPCType : syNumber 527{ 528 $$.innumber = $$.outnumber = $1; 529 $$.instr = $$.outstr = strNULL; 530 $$.size = 0; 531} 532 | sySymbolicType 533 { $$ = $1; } 534 ; 535 536IPCType : PrimIPCType 537 { $$ = $1; } 538 | PrimIPCType syBar PrimIPCType 539{ 540 if ($1.size != $3.size) { 541 if ($1.size == 0) 542 $$.size = $3.size; 543 else if ($3.size == 0) 544 $$.size = $1.size; 545 else { 546 error("sizes in IPCTypes (%d, %d) aren't equal", 547 $1.size, $3.size); 548 $$.size = 0; 549 } 550 } 551 else 552 $$.size = $1.size; 553 $$.innumber = $1.innumber; 554 $$.instr = $1.instr; 555 $$.outnumber = $3.outnumber; 556 $$.outstr = $3.outstr; 557} 558 ; 559 560PrevTypeSpec : syIdentifier 561 { $$ = itPrevDecl($1); } 562 ; 563 564VarArrayHead : syArray syLBrack syRBrack syOf 565 { $$ = 0; } 566 | syArray syLBrack syStar syRBrack syOf 567 { $$ = 0; } 568 | syArray syLBrack syStar syColon IntExp 569 syRBrack syOf 570 { $$ = $5; } 571 ; 572 573ArrayHead : syArray syLBrack IntExp syRBrack syOf 574 { $$ = $3; } 575 ; 576 577StructHead : syStruct syLBrack IntExp syRBrack syOf 578 { $$ = $3; } 579 ; 580 581CStringSpec : syCString syLBrack IntExp syRBrack 582 { $$ = itCStringDecl($3, FALSE); } 583 | syCString syLBrack syStar syColon 584 IntExp syRBrack 585 { $$ = itCStringDecl($5, TRUE); } 586 ; 587 588TypePhrase : syIdentifier 589 { $$ = $1; } 590 | TypePhrase syIdentifier 591 { $$ = strphrase($1, $2); strfree($2); } 592 ; 593 594IntExp : IntExp syPlus IntExp 595 { $$ = $1 + $3; } 596 | IntExp syMinus IntExp 597 { $$ = $1 - $3; } 598 | IntExp syStar IntExp 599 { $$ = $1 * $3; } 600 | IntExp syDiv IntExp 601 { $$ = $1 / $3; } 602 | syNumber 603 { $$ = $1; } 604 | syLParen IntExp syRParen 605 { $$ = $2; } 606 ; 607 608 609RoutineDecl : Routine { $$ = $1; } 610 | SimpleRoutine { $$ = $1; } 611 ; 612 613Routine : syRoutine syIdentifier Arguments 614 { $$ = rtMakeRoutine($2, $3); } 615 ; 616 617SimpleRoutine : sySimpleRoutine syIdentifier Arguments 618 { $$ = rtMakeSimpleRoutine($2, $3); } 619 ; 620 621Arguments : syLParen syRParen 622 { $$ = argNULL; } 623 | syLParen ArgumentList syRParen 624 { $$ = $2; } 625 626 ; 627 628ArgumentList : Argument 629 { $$ = $1; } 630 | Trailer 631 { $$ = $1; } 632 | Argument sySemi ArgumentList 633{ 634 $$ = $1; 635 $$->argNext = $3; 636} 637 | Trailer sySemi ArgumentList 638{ 639 $$ = $1; 640 $$->argNext = $3; 641} 642 ; 643 644Argument : Direction syIdentifier ArgumentType IPCFlags 645{ 646 $$ = argAlloc(); 647 $$->argKind = $1; 648 $$->argName = $2; 649 $$->argType = $3; 650 $$->argFlags = $4; 651 if ($3 && $3->itNative) { 652 if ($1 != akIn && $1 != akOut && $1 != akInOut) 653 error("Illegal direction specified"); 654 655 if (!($3->itNativePointer) && $1 != akIn) 656 error("ValueOf only valid for in"); 657 658 if (($3->itBadValue) != NULL && $1 != akIn) 659 error("PointerToIfNot only valid for in"); 660 } 661} 662 ; 663 664Trailer : TrImplKeyword syIdentifier ArgumentType 665{ 666 $$ = argAlloc(); 667 $$->argKind = $1; 668 $$->argName = $2; 669 $$->argType = $3; 670} 671 ; 672 673 674Direction : /* empty */ { $$ = akNone; } 675 | syIn { $$ = akIn; } 676 | syOut { $$ = akOut; } 677 | syInOut { $$ = akInOut; } 678 | syRequestPort { $$ = akRequestPort; } 679 | syReplyPort { $$ = akReplyPort; } 680 | sySReplyPort { $$ = akSReplyPort; } 681 | syUReplyPort { $$ = akUReplyPort; } 682 | syWaitTime { $$ = akWaitTime; } 683 | sySendTime { $$ = akSendTime; } 684 | syMsgOption { $$ = akMsgOption; } 685 | sySecToken { $$ = akSecToken; } 686 | syServerSecToken { $$ = akServerSecToken; } 687 | syUserSecToken { $$ = akUserSecToken; } 688 | syAuditToken { $$ = akAuditToken; } 689 | syServerAuditToken { $$ = akServerAuditToken; } 690 | syUserAuditToken { $$ = akUserAuditToken; } 691 | syServerContextToken { $$ = akServerContextToken; } 692 | syMsgSeqno { $$ = akMsgSeqno; } 693 ; 694 695 696 697TrImplKeyword : syServerImpl { $$ = akServerImpl; } 698 | syUserImpl { $$ = akUserImpl; } 699 ; 700 701 702ArgumentType : syColon syIdentifier 703{ 704 $$ = itLookUp($2); 705 if ($$ == itNULL) 706 error("type '%s' not defined", $2); 707} 708 | syColon NamedTypeSpec 709 { $$ = $2; } 710 | syColon NativeTypeSpec 711 { $$ = $2; } 712 ; 713 714IPCFlags : /* empty */ 715 { $$ = flNone; } 716 | IPCFlags syComma syIPCFlag 717{ 718 if ($1 & $3) 719 warn("redundant IPC flag ignored"); 720 else 721 $$ = $1 | $3; 722} 723 | IPCFlags syComma syIPCFlag syLBrack syRBrack 724{ 725 if ($3 != flDealloc) 726 warn("only Dealloc is variable"); 727 else 728 $$ = $1 | flMaybeDealloc; 729} 730 731LookString : /* empty */ 732 { LookString(); } 733 ; 734 735LookFileName : /* empty */ 736 { LookFileName(); } 737 ; 738 739LookQString : /* empty */ 740 { LookQString(); } 741 ; 742 743%% 744 745void 746yyerror(char *s) 747{ 748 error(s); 749} 750 751static char * 752import_name(statement_kind_t sk) 753{ 754 switch (sk) { 755 756 case skImport: 757 return "Import"; 758 759 case skSImport: 760 return "SImport"; 761 762 case skUImport: 763 return "UImport"; 764 765 case skIImport: 766 return "IImport"; 767 768 case skDImport: 769 return "DImport"; 770 771 default: 772 fatal("import_name(%d): not import statement", (int) sk); 773 /*NOTREACHED*/ 774 return strNULL; 775 } 776} 777