1 /****************************************************************************** 2 * 3 * Module Name: prscan - Preprocessor start-up and file scan module 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 Gbl_MapBlockHead = UtLocalCalloc (sizeof (PR_LINE_MAPPING)); 166 Gbl_MapBlockHead->Map = UtLocalCalloc (PR_LINES_PER_BLOCK * sizeof (UINT32)); 167 } 168 169 170 /******************************************************************************* 171 * 172 * FUNCTION: PrTerminatePreprocessor 173 * 174 * PARAMETERS: None 175 * 176 * RETURN: None 177 * 178 * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any 179 * defines that were specified on the command line, in order to 180 * support multiple compiles with a single compiler invocation. 181 * 182 ******************************************************************************/ 183 184 void 185 PrTerminatePreprocessor ( 186 void) 187 { 188 PR_DEFINE_INFO *DefineInfo; 189 PR_LINE_MAPPING *MapInfo; 190 191 192 /* 193 * The persistent defines (created on the command line) are always at the 194 * end of the list. We save them. 195 */ 196 while ((Gbl_DefineList) && (!Gbl_DefineList->Persist)) 197 { 198 DefineInfo = Gbl_DefineList; 199 Gbl_DefineList = DefineInfo->Next; 200 201 ACPI_FREE (DefineInfo->Replacement); 202 ACPI_FREE (DefineInfo->Identifier); 203 ACPI_FREE (DefineInfo); 204 } 205 206 /* Clear the line number mappings */ 207 208 while (Gbl_MapBlockHead) 209 { 210 MapInfo = Gbl_MapBlockHead; 211 Gbl_MapBlockHead = MapInfo->Next; 212 213 ACPI_FREE (MapInfo->Map); 214 ACPI_FREE (MapInfo); 215 } 216 } 217 218 219 /******************************************************************************* 220 * 221 * FUNCTION: PrDoPreprocess 222 * 223 * PARAMETERS: None 224 * 225 * RETURN: Error Status. TRUE if error, FALSE if OK. 226 * 227 * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must 228 * be already open. Handles multiple input files via the 229 * #include directive. 230 * 231 ******************************************************************************/ 232 233 BOOLEAN 234 PrDoPreprocess ( 235 void) 236 { 237 BOOLEAN MoreInputFiles; 238 239 240 DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n"); 241 242 243 FlSeekFile (ASL_FILE_INPUT, 0); 244 PrDumpPredefinedNames (); 245 246 /* Main preprocessor loop, handles include files */ 247 248 do 249 { 250 PrPreprocessInputFile (); 251 MoreInputFiles = PrPopInputFileStack (); 252 253 } while (MoreInputFiles); 254 255 256 /* 257 * TBD: is this necessary? (Do we abort on any preprocessing errors?) 258 */ 259 if (Gbl_PreprocessorError) 260 { 261 /* TBD: can't use source_output file for preprocessor error reporting */ 262 263 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle = NULL; 264 PrTerminatePreprocessor (); 265 return (TRUE); 266 } 267 268 /* Point compiler input to the new preprocessor file (.i) */ 269 270 FlCloseFile (ASL_FILE_INPUT); 271 Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle; 272 AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle; 273 274 /* Reset globals to allow compiler to run */ 275 276 FlSeekFile (ASL_FILE_INPUT, 0); 277 Gbl_CurrentLineNumber = 1; 278 279 DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n"); 280 return (FALSE); 281 } 282 283 284 /******************************************************************************* 285 * 286 * FUNCTION: PrPreprocessInputFile 287 * 288 * PARAMETERS: None 289 * 290 * RETURN: None 291 * 292 * DESCRIPTION: Preprocess one entire file, line-by-line. 293 * 294 * Input: Raw user ASL from ASL_FILE_INPUT 295 * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR 296 * 297 ******************************************************************************/ 298 299 static void 300 PrPreprocessInputFile ( 301 void) 302 { 303 UINT32 Offset; 304 char *Token; 305 char *ReplaceString; 306 PR_DEFINE_INFO *DefineInfo; 307 ACPI_SIZE TokenOffset; 308 BOOLEAN IgnoringThisCodeBlock = FALSE; 309 char *Next; 310 int OffsetAdjust; 311 312 313 /* Scan line-by-line. Comments and blank lines are skipped by this function */ 314 315 while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) 316 { 317 /* Need a copy of the input line for strok() */ 318 319 strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); 320 Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next); 321 OffsetAdjust = 0; 322 323 /* All preprocessor directives must begin with '#' */ 324 325 if (Token && (*Token == '#')) 326 { 327 if (strlen (Token) == 1) 328 { 329 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 330 } 331 else 332 { 333 Token++; /* Skip leading # */ 334 } 335 336 /* Execute the directive, do not write line to output file */ 337 338 PrDoDirective (Token, &Next, &IgnoringThisCodeBlock); 339 continue; 340 } 341 342 /* 343 * If we are currently within the part of an IF/ELSE block that is 344 * FALSE, ignore the line and do not write it to the output file. 345 * This continues until an #else or #endif is encountered. 346 */ 347 if (IgnoringThisCodeBlock == TRUE) 348 { 349 continue; 350 } 351 352 /* Match and replace all #defined names within this source line */ 353 354 while (Token) 355 { 356 DefineInfo = PrMatchDefine (Token); 357 if (DefineInfo) 358 { 359 if (DefineInfo->Body) 360 { 361 /* This is a macro */ 362 363 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 364 "Matched Macro: %s->%s\n", 365 Gbl_CurrentLineNumber, DefineInfo->Identifier, 366 DefineInfo->Replacement); 367 368 PrDoMacroInvocation (Gbl_MainTokenBuffer, Token, 369 DefineInfo, &Next); 370 } 371 else 372 { 373 ReplaceString = DefineInfo->Replacement; 374 375 /* Replace the name in the original line buffer */ 376 377 TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust; 378 PrReplaceData ( 379 &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), 380 ReplaceString, strlen (ReplaceString)); 381 382 /* Adjust for length difference between old and new name length */ 383 384 OffsetAdjust += strlen (ReplaceString) - strlen (Token); 385 386 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 387 "Matched #define: %s->%s\n", 388 Gbl_CurrentLineNumber, Token, 389 *ReplaceString ? ReplaceString : "(NULL STRING)"); 390 } 391 } 392 393 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 394 } 395 396 /* Write the possibly modified line to the .i file*/ 397 398 #if 0 399 /* Line prefix */ 400 FlPrintFile (ASL_FILE_PREPROCESSOR, "/* %14s %.5u i:%.5u */ ", 401 Gbl_Files[ASL_FILE_INPUT].Filename, 402 Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber); 403 #endif 404 405 FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, 406 strlen (Gbl_CurrentLineBuffer)); 407 408 PrSetLineNumber (Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber); 409 Gbl_PreprocessorLineNumber++; 410 } 411 } 412 413 414 /******************************************************************************* 415 * 416 * FUNCTION: PrDoDirective 417 * 418 * PARAMETERS: Directive - Pointer to directive name token 419 * Next - "Next" buffer from GetNextToken 420 * IgnoringThisCodeBlock - Where the "ignore code" flag is 421 * returned. 422 * 423 * RETURN: IgnoringThisCodeBlock: Set to TRUE if we are skipping the FALSE 424 * part of an #if or #else block. Set to FALSE when the 425 * corresponding #else or #endif is encountered. 426 * 427 * DESCRIPTION: Main processing for all preprocessor directives 428 * 429 ******************************************************************************/ 430 431 static void 432 PrDoDirective ( 433 char *DirectiveToken, 434 char **Next, 435 BOOLEAN *IgnoringThisCodeBlock) 436 { 437 char *Token = Gbl_MainTokenBuffer; 438 char *Token2; 439 char *End; 440 UINT64 Value; 441 ACPI_SIZE TokenOffset; 442 int Directive; 443 ACPI_STATUS Status; 444 445 446 if (!DirectiveToken) 447 { 448 goto SyntaxError; 449 } 450 451 Directive = PrMatchDirective (DirectiveToken); 452 if (Directive == ASL_DIRECTIVE_NOT_FOUND) 453 { 454 PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE, 455 THIS_TOKEN_OFFSET (DirectiveToken)); 456 457 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 458 "#%s: Unknown directive\n", 459 Gbl_CurrentLineNumber, DirectiveToken); 460 return; 461 } 462 463 /* TBD: Need a faster way to do this: */ 464 465 if ((Directive == PR_DIRECTIVE_ELIF) || 466 (Directive == PR_DIRECTIVE_ELSE) || 467 (Directive == PR_DIRECTIVE_ENDIF)) 468 { 469 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", 470 Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); 471 } 472 473 /* 474 * Need to always check for #else, #elif, #endif regardless of 475 * whether we are ignoring the current code block, since these 476 * are conditional code block terminators. 477 */ 478 switch (Directive) 479 { 480 case PR_DIRECTIVE_ELIF: 481 *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); 482 if (*IgnoringThisCodeBlock == TRUE) 483 { 484 /* Not executing the ELSE part -- all done here */ 485 return; 486 } 487 488 /* Will execute the ELSE..IF part */ 489 490 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 491 "#elif - Executing else block\n", 492 Gbl_CurrentLineNumber); 493 Directive = PR_DIRECTIVE_IF; 494 break; 495 496 case PR_DIRECTIVE_ELSE: 497 *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); 498 return; 499 500 case PR_DIRECTIVE_ENDIF: 501 *IgnoringThisCodeBlock = FALSE; 502 Gbl_IfDepth--; 503 if (Gbl_IfDepth < 0) 504 { 505 PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH, 506 THIS_TOKEN_OFFSET (DirectiveToken)); 507 Gbl_IfDepth = 0; 508 } 509 return; 510 511 default: 512 break; 513 } 514 515 /* 516 * At this point, if we are ignoring the current code block, 517 * do not process any more directives (i.e., ignore them also.) 518 */ 519 if (*IgnoringThisCodeBlock == TRUE) 520 { 521 return; 522 } 523 524 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", 525 Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); 526 527 /* Most directives have at least one argument */ 528 529 if (Gbl_DirectiveInfo[Directive].ArgCount == 1) 530 { 531 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 532 if (!Token) 533 { 534 goto SyntaxError; 535 } 536 } 537 538 switch (Directive) 539 { 540 case PR_DIRECTIVE_DEFINE: 541 /* 542 * By definition, if first char after the name is a paren, 543 * this is a function macro. 544 */ 545 TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); 546 if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') 547 { 548 #ifndef MACROS_SUPPORTED 549 AcpiOsPrintf ("#define macros not supported\n"); 550 goto SyntaxError; 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_PRAGMA: 664 /* Only "#pragma message" supported at this time */ 665 666 if (strcmp (Token, "message")) 667 { 668 PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA, 669 THIS_TOKEN_OFFSET (Token)); 670 return; 671 } 672 673 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 674 if (!Token) 675 { 676 goto SyntaxError; 677 } 678 679 TokenOffset = Token - Gbl_MainTokenBuffer; 680 AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]); 681 break; 682 683 case PR_DIRECTIVE_UNDEF: 684 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 685 "#undef: %s\n", Gbl_CurrentLineNumber, Token); 686 687 PrRemoveDefine (Token); 688 break; 689 690 case PR_DIRECTIVE_WARNING: 691 PrError (ASL_WARNING, ASL_MSG_ERROR_DIRECTIVE, 692 THIS_TOKEN_OFFSET (Token)); 693 break; 694 695 case PR_DIRECTIVE_LINE: 696 /* TBD: set line number -- or, do this in main compiler */ 697 default: 698 /* Should never get here */ 699 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 700 "Unrecognized directive: %u\n", 701 Gbl_CurrentLineNumber, Directive); 702 break; 703 } 704 705 return; 706 707 708 SyntaxError: 709 710 PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, 711 THIS_TOKEN_OFFSET (DirectiveToken)); 712 return; 713 } 714 715 716 /******************************************************************************* 717 * 718 * FUNCTION: PrMatchDirective 719 * 720 * PARAMETERS: Directive - Pointer to directive name token 721 * 722 * RETURN: Index into command array, -1 if not found 723 * 724 * DESCRIPTION: Lookup the incoming directive in the known directives table. 725 * 726 ******************************************************************************/ 727 728 static int 729 PrMatchDirective ( 730 char *Directive) 731 { 732 int i; 733 734 735 if (!Directive || Directive[0] == 0) 736 { 737 return (ASL_DIRECTIVE_NOT_FOUND); 738 } 739 740 for (i = 0; Gbl_DirectiveInfo[i].Name; i++) 741 { 742 if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive)) 743 { 744 return (i); 745 } 746 } 747 748 return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */ 749 } 750