1 /****************************************************************************** 2 * 3 * Module Name: prscan - Preprocessor start-up and file scan module 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #define _DECLARE_PR_GLOBALS 45 46 #include <contrib/dev/acpica/compiler/aslcompiler.h> 47 #include <contrib/dev/acpica/compiler/dtcompiler.h> 48 49 /* 50 * TBDs: 51 * 52 * No nested macros, maybe never 53 * Implement ASL "Include" as well as "#include" here? 54 */ 55 #define _COMPONENT ASL_PREPROCESSOR 56 ACPI_MODULE_NAME ("prscan") 57 58 59 /* Local prototypes */ 60 61 static void 62 PrPreprocessInputFile ( 63 void); 64 65 static void 66 PrDoDirective ( 67 char *DirectiveToken, 68 char **Next, 69 BOOLEAN *IgnoringThisCodeBlock); 70 71 static int 72 PrMatchDirective ( 73 char *Directive); 74 75 /* 76 * Supported preprocessor directives 77 */ 78 static const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] = 79 { 80 {"define", 1}, 81 {"elif", 0}, /* Converted to #else..#if internally */ 82 {"else", 0}, 83 {"endif", 0}, 84 {"error", 1}, 85 {"if", 1}, 86 {"ifdef", 1}, 87 {"ifndef", 1}, 88 {"include", 0}, /* Argument is not standard format, so 0 */ 89 {"line", 1}, 90 {"pragma", 1}, 91 {"undef", 1}, 92 {"warning", 1}, 93 {NULL, 0} 94 }; 95 96 enum Gbl_DirectiveIndexes 97 { 98 PR_DIRECTIVE_DEFINE = 0, 99 PR_DIRECTIVE_ELIF, 100 PR_DIRECTIVE_ELSE, 101 PR_DIRECTIVE_ENDIF, 102 PR_DIRECTIVE_ERROR, 103 PR_DIRECTIVE_IF, 104 PR_DIRECTIVE_IFDEF, 105 PR_DIRECTIVE_IFNDEF, 106 PR_DIRECTIVE_INCLUDE, 107 PR_DIRECTIVE_LINE, 108 PR_DIRECTIVE_PRAGMA, 109 PR_DIRECTIVE_UNDEF, 110 PR_DIRECTIVE_WARNING, 111 }; 112 113 #define ASL_DIRECTIVE_NOT_FOUND -1 114 115 116 /******************************************************************************* 117 * 118 * FUNCTION: PrInitializePreprocessor 119 * 120 * PARAMETERS: None 121 * 122 * RETURN: None 123 * 124 * DESCRIPTION: Startup initialization for the Preprocessor. 125 * 126 ******************************************************************************/ 127 128 void 129 PrInitializePreprocessor ( 130 void) 131 { 132 /* Init globals and the list of #defines */ 133 134 PrInitializeGlobals (); 135 Gbl_DefineList = NULL; 136 } 137 138 139 /******************************************************************************* 140 * 141 * FUNCTION: PrInitializeGlobals 142 * 143 * PARAMETERS: None 144 * 145 * RETURN: None 146 * 147 * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup 148 * initialization and re-initialization between compiles during 149 * a multiple source file compile. 150 * 151 ******************************************************************************/ 152 153 void 154 PrInitializeGlobals ( 155 void) 156 { 157 /* Init globals */ 158 159 Gbl_IfDepth = 0; 160 Gbl_InputFileList = NULL; 161 Gbl_CurrentLineNumber = 0; 162 Gbl_PreprocessorLineNumber = 1; 163 Gbl_PreprocessorError = FALSE; 164 } 165 166 167 /******************************************************************************* 168 * 169 * FUNCTION: PrTerminatePreprocessor 170 * 171 * PARAMETERS: None 172 * 173 * RETURN: None 174 * 175 * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any 176 * defines that were specified on the command line, in order to 177 * support multiple compiles with a single compiler invocation. 178 * 179 ******************************************************************************/ 180 181 void 182 PrTerminatePreprocessor ( 183 void) 184 { 185 PR_DEFINE_INFO *DefineInfo; 186 187 188 /* 189 * The persistent defines (created on the command line) are always at the 190 * end of the list. We save them. 191 */ 192 while ((Gbl_DefineList) && (!Gbl_DefineList->Persist)) 193 { 194 DefineInfo = Gbl_DefineList; 195 Gbl_DefineList = DefineInfo->Next; 196 197 ACPI_FREE (DefineInfo->Replacement); 198 ACPI_FREE (DefineInfo->Identifier); 199 ACPI_FREE (DefineInfo); 200 } 201 } 202 203 204 /******************************************************************************* 205 * 206 * FUNCTION: PrDoPreprocess 207 * 208 * PARAMETERS: None 209 * 210 * RETURN: Error Status. TRUE if error, FALSE if OK. 211 * 212 * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must 213 * be already open. Handles multiple input files via the 214 * #include directive. 215 * 216 ******************************************************************************/ 217 218 BOOLEAN 219 PrDoPreprocess ( 220 void) 221 { 222 BOOLEAN MoreInputFiles; 223 224 225 DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n"); 226 227 228 FlSeekFile (ASL_FILE_INPUT, 0); 229 PrDumpPredefinedNames (); 230 231 /* Main preprocessor loop, handles include files */ 232 233 do 234 { 235 PrPreprocessInputFile (); 236 MoreInputFiles = PrPopInputFileStack (); 237 238 } while (MoreInputFiles); 239 240 241 /* 242 * TBD: is this necessary? (Do we abort on any preprocessing errors?) 243 */ 244 if (Gbl_PreprocessorError) 245 { 246 /* TBD: can't use source_output file for preprocessor error reporting */ 247 248 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle = NULL; 249 PrTerminatePreprocessor (); 250 return (TRUE); 251 } 252 253 /* Point compiler input to the new preprocessor file (.i) */ 254 255 FlCloseFile (ASL_FILE_INPUT); 256 Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle; 257 AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle; 258 259 /* Reset globals to allow compiler to run */ 260 261 FlSeekFile (ASL_FILE_INPUT, 0); 262 Gbl_CurrentLineNumber = 1; 263 264 DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n"); 265 return (FALSE); 266 } 267 268 269 /******************************************************************************* 270 * 271 * FUNCTION: PrPreprocessInputFile 272 * 273 * PARAMETERS: None 274 * 275 * RETURN: None 276 * 277 * DESCRIPTION: Preprocess one entire file, line-by-line. 278 * 279 * Input: Raw user ASL from ASL_FILE_INPUT 280 * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR 281 * 282 ******************************************************************************/ 283 284 static void 285 PrPreprocessInputFile ( 286 void) 287 { 288 UINT32 Offset; 289 char *Token; 290 char *ReplaceString; 291 PR_DEFINE_INFO *DefineInfo; 292 ACPI_SIZE TokenOffset; 293 BOOLEAN IgnoringThisCodeBlock = FALSE; 294 char *Next; 295 int OffsetAdjust; 296 297 298 /* Scan line-by-line. Comments and blank lines are skipped by this function */ 299 300 while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) 301 { 302 /* Need a copy of the input line for strok() */ 303 304 strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); 305 Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next); 306 OffsetAdjust = 0; 307 308 /* All preprocessor directives must begin with '#' */ 309 310 if (Token && (*Token == '#')) 311 { 312 if (strlen (Token) == 1) 313 { 314 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 315 } 316 else 317 { 318 Token++; /* Skip leading # */ 319 } 320 321 /* Execute the directive, do not write line to output file */ 322 323 PrDoDirective (Token, &Next, &IgnoringThisCodeBlock); 324 continue; 325 } 326 327 /* 328 * If we are currently within the part of an IF/ELSE block that is 329 * FALSE, ignore the line and do not write it to the output file. 330 * This continues until an #else or #endif is encountered. 331 */ 332 if (IgnoringThisCodeBlock == TRUE) 333 { 334 continue; 335 } 336 337 /* Match and replace all #defined names within this source line */ 338 339 while (Token) 340 { 341 DefineInfo = PrMatchDefine (Token); 342 if (DefineInfo) 343 { 344 if (DefineInfo->Body) 345 { 346 /* This is a macro */ 347 348 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 349 "Matched Macro: %s->%s\n", 350 Gbl_CurrentLineNumber, DefineInfo->Identifier, 351 DefineInfo->Replacement); 352 353 PrDoMacroInvocation (Gbl_MainTokenBuffer, Token, 354 DefineInfo, &Next); 355 } 356 else 357 { 358 ReplaceString = DefineInfo->Replacement; 359 360 /* Replace the name in the original line buffer */ 361 362 TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust; 363 PrReplaceData ( 364 &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), 365 ReplaceString, strlen (ReplaceString)); 366 367 /* Adjust for length difference between old and new name length */ 368 369 OffsetAdjust += strlen (ReplaceString) - strlen (Token); 370 371 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 372 "Matched #define: %s->%s\n", 373 Gbl_CurrentLineNumber, Token, 374 *ReplaceString ? ReplaceString : "(NULL STRING)"); 375 } 376 } 377 378 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 379 } 380 381 #if 0 382 /* Line prefix */ 383 FlPrintFile (ASL_FILE_PREPROCESSOR, "/* %14s %.5u i:%.5u */ ", 384 Gbl_Files[ASL_FILE_INPUT].Filename, 385 Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber); 386 #endif 387 388 /* 389 * Emit a #line directive if necessary, to keep the line numbers in 390 * the (.i) file synchronized with the original source code file, so 391 * that the correct line number appears in any error messages 392 * generated by the actual compiler. 393 */ 394 if (Gbl_CurrentLineNumber > (Gbl_PreviousLineNumber + 1)) 395 { 396 FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u\n", 397 Gbl_CurrentLineNumber); 398 } 399 400 Gbl_PreviousLineNumber = Gbl_CurrentLineNumber; 401 Gbl_PreprocessorLineNumber++; 402 403 /* 404 * Now we can write the possibly modified source line to the 405 * preprocessor (.i) file 406 */ 407 FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, 408 strlen (Gbl_CurrentLineBuffer)); 409 } 410 } 411 412 413 /******************************************************************************* 414 * 415 * FUNCTION: PrDoDirective 416 * 417 * PARAMETERS: Directive - Pointer to directive name token 418 * Next - "Next" buffer from GetNextToken 419 * IgnoringThisCodeBlock - Where the "ignore code" flag is 420 * returned. 421 * 422 * RETURN: IgnoringThisCodeBlock: Set to TRUE if we are skipping the FALSE 423 * part of an #if or #else block. Set to FALSE when the 424 * corresponding #else or #endif is encountered. 425 * 426 * DESCRIPTION: Main processing for all preprocessor directives 427 * 428 ******************************************************************************/ 429 430 static void 431 PrDoDirective ( 432 char *DirectiveToken, 433 char **Next, 434 BOOLEAN *IgnoringThisCodeBlock) 435 { 436 char *Token = Gbl_MainTokenBuffer; 437 char *Token2; 438 char *End; 439 UINT64 Value; 440 ACPI_SIZE TokenOffset; 441 int Directive; 442 ACPI_STATUS Status; 443 444 445 if (!DirectiveToken) 446 { 447 goto SyntaxError; 448 } 449 450 Directive = PrMatchDirective (DirectiveToken); 451 if (Directive == ASL_DIRECTIVE_NOT_FOUND) 452 { 453 PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE, 454 THIS_TOKEN_OFFSET (DirectiveToken)); 455 456 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 457 "#%s: Unknown directive\n", 458 Gbl_CurrentLineNumber, DirectiveToken); 459 return; 460 } 461 462 /* TBD: Need a faster way to do this: */ 463 464 if ((Directive == PR_DIRECTIVE_ELIF) || 465 (Directive == PR_DIRECTIVE_ELSE) || 466 (Directive == PR_DIRECTIVE_ENDIF)) 467 { 468 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", 469 Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); 470 } 471 472 /* 473 * Need to always check for #else, #elif, #endif regardless of 474 * whether we are ignoring the current code block, since these 475 * are conditional code block terminators. 476 */ 477 switch (Directive) 478 { 479 case PR_DIRECTIVE_ELIF: 480 *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); 481 if (*IgnoringThisCodeBlock == TRUE) 482 { 483 /* Not executing the ELSE part -- all done here */ 484 return; 485 } 486 487 /* Will execute the ELSE..IF part */ 488 489 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 490 "#elif - Executing else block\n", 491 Gbl_CurrentLineNumber); 492 Directive = PR_DIRECTIVE_IF; 493 break; 494 495 case PR_DIRECTIVE_ELSE: 496 *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); 497 return; 498 499 case PR_DIRECTIVE_ENDIF: 500 *IgnoringThisCodeBlock = FALSE; 501 Gbl_IfDepth--; 502 if (Gbl_IfDepth < 0) 503 { 504 PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH, 505 THIS_TOKEN_OFFSET (DirectiveToken)); 506 Gbl_IfDepth = 0; 507 } 508 return; 509 510 default: 511 break; 512 } 513 514 /* 515 * At this point, if we are ignoring the current code block, 516 * do not process any more directives (i.e., ignore them also.) 517 */ 518 if (*IgnoringThisCodeBlock == TRUE) 519 { 520 return; 521 } 522 523 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", 524 Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); 525 526 /* Most directives have at least one argument */ 527 528 if (Gbl_DirectiveInfo[Directive].ArgCount == 1) 529 { 530 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 531 if (!Token) 532 { 533 goto SyntaxError; 534 } 535 } 536 537 switch (Directive) 538 { 539 case PR_DIRECTIVE_DEFINE: 540 /* 541 * By definition, if first char after the name is a paren, 542 * this is a function macro. 543 */ 544 TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); 545 if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') 546 { 547 #ifndef MACROS_SUPPORTED 548 AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n", 549 Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber); 550 exit(1); 551 #else 552 PrAddMacro (Token, Next); 553 #endif 554 } 555 else 556 { 557 /* Use the remainder of the line for the #define */ 558 559 Token2 = *Next; 560 if (Token2) 561 { 562 while ((*Token2 == ' ') || (*Token2 == '\t')) 563 { 564 Token2++; 565 } 566 End = Token2; 567 while (*End != '\n') 568 { 569 End++; 570 } 571 *End = 0; 572 } 573 else 574 { 575 Token2 = ""; 576 } 577 #if 0 578 Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next); 579 if (!Token2) 580 { 581 Token2 = ""; 582 } 583 #endif 584 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 585 "New #define: %s->%s\n", 586 Gbl_CurrentLineNumber, Token, Token2); 587 588 PrAddDefine (Token, Token2, FALSE); 589 } 590 break; 591 592 case PR_DIRECTIVE_ERROR: 593 /* TBD compiler should abort */ 594 /* Note: No macro expansion */ 595 596 PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE, 597 THIS_TOKEN_OFFSET (Token)); 598 break; 599 600 case PR_DIRECTIVE_IF: 601 TokenOffset = Token - Gbl_MainTokenBuffer; 602 603 /* Need to expand #define macros in the expression string first */ 604 605 Status = PrResolveIntegerExpression ( 606 &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); 607 if (ACPI_FAILURE (Status)) 608 { 609 return; 610 } 611 612 if (!Value) 613 { 614 *IgnoringThisCodeBlock = TRUE; 615 } 616 617 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 618 "Resolved #if: %8.8X%8.8X %s\n", 619 Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value), 620 *IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>"); 621 622 Gbl_IfDepth++; 623 break; 624 625 case PR_DIRECTIVE_IFDEF: 626 if (!PrMatchDefine (Token)) 627 { 628 *IgnoringThisCodeBlock = TRUE; 629 } 630 631 Gbl_IfDepth++; 632 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 633 "Start #ifdef %s\n", Gbl_CurrentLineNumber, 634 *IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>"); 635 break; 636 637 case PR_DIRECTIVE_IFNDEF: 638 if (PrMatchDefine (Token)) 639 { 640 *IgnoringThisCodeBlock = TRUE; 641 } 642 643 Gbl_IfDepth++; 644 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 645 "Start #ifndef %2.2X\n", Gbl_CurrentLineNumber, 646 *IgnoringThisCodeBlock, Gbl_CurrentLineNumber); 647 break; 648 649 case PR_DIRECTIVE_INCLUDE: 650 Token = PrGetNextToken (NULL, " \"<>", Next); 651 if (!Token) 652 { 653 goto SyntaxError; 654 } 655 656 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 657 "Start #include file \"%s\"\n", Gbl_CurrentLineNumber, 658 Token, Gbl_CurrentLineNumber); 659 660 PrOpenIncludeFile (Token); 661 break; 662 663 case PR_DIRECTIVE_LINE: 664 TokenOffset = Token - Gbl_MainTokenBuffer; 665 666 Status = PrResolveIntegerExpression ( 667 &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); 668 if (ACPI_FAILURE (Status)) 669 { 670 return; 671 } 672 673 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 674 "User #line invocation %s\n", Gbl_CurrentLineNumber, 675 Token); 676 677 /* Update local line numbers */ 678 679 Gbl_CurrentLineNumber = (UINT32) Value; 680 Gbl_PreviousLineNumber = 0; 681 682 /* Emit #line into the preprocessor file */ 683 684 FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n", 685 Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename); 686 break; 687 688 case PR_DIRECTIVE_PRAGMA: 689 /* Only "#pragma message" supported at this time */ 690 691 if (strcmp (Token, "message")) 692 { 693 PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA, 694 THIS_TOKEN_OFFSET (Token)); 695 return; 696 } 697 698 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 699 if (!Token) 700 { 701 goto SyntaxError; 702 } 703 704 TokenOffset = Token - Gbl_MainTokenBuffer; 705 AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]); 706 break; 707 708 case PR_DIRECTIVE_UNDEF: 709 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 710 "#undef: %s\n", Gbl_CurrentLineNumber, Token); 711 712 PrRemoveDefine (Token); 713 break; 714 715 case PR_DIRECTIVE_WARNING: 716 PrError (ASL_WARNING, ASL_MSG_ERROR_DIRECTIVE, 717 THIS_TOKEN_OFFSET (Token)); 718 break; 719 720 default: 721 /* Should never get here */ 722 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 723 "Unrecognized directive: %u\n", 724 Gbl_CurrentLineNumber, Directive); 725 break; 726 } 727 728 return; 729 730 731 SyntaxError: 732 733 PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, 734 THIS_TOKEN_OFFSET (DirectiveToken)); 735 return; 736 } 737 738 739 /******************************************************************************* 740 * 741 * FUNCTION: PrMatchDirective 742 * 743 * PARAMETERS: Directive - Pointer to directive name token 744 * 745 * RETURN: Index into command array, -1 if not found 746 * 747 * DESCRIPTION: Lookup the incoming directive in the known directives table. 748 * 749 ******************************************************************************/ 750 751 static int 752 PrMatchDirective ( 753 char *Directive) 754 { 755 int i; 756 757 758 if (!Directive || Directive[0] == 0) 759 { 760 return (ASL_DIRECTIVE_NOT_FOUND); 761 } 762 763 for (i = 0; Gbl_DirectiveInfo[i].Name; i++) 764 { 765 if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive)) 766 { 767 return (i); 768 } 769 } 770 771 return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */ 772 } 773