]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/compiler/prscan.c
Import byacc from invisible island, it brings us lots of compatibilities with
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / compiler / prscan.c
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
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 }