Fixed compatibility of output.
[AROS.git] / arch / all-pc / acpica / source / compiler / prscan.c
blob3b5416a61195a295cd70ac067c405d8d91fa294d
1 /******************************************************************************
3 * Module Name: prscan - Preprocessor start-up and file scan module
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
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.
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.
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.
44 #define _DECLARE_PR_GLOBALS
46 #include "aslcompiler.h"
47 #include "dtcompiler.h"
50 * TBDs:
52 * No nested macros, maybe never
53 * Implement ASL "Include" as well as "#include" here?
55 #define _COMPONENT ASL_PREPROCESSOR
56 ACPI_MODULE_NAME ("prscan")
59 /* Local prototypes */
61 static void
62 PrPreprocessInputFile (
63 void);
65 static void
66 PrDoDirective (
67 char *DirectiveToken,
68 char **Next);
70 static int
71 PrMatchDirective (
72 char *Directive);
74 static void
75 PrPushDirective (
76 int Directive,
77 char *Argument);
79 static ACPI_STATUS
80 PrPopDirective (
81 void);
83 static void
84 PrDbgPrint (
85 char *Action,
86 char *DirectiveName);
90 * Supported preprocessor directives
92 static const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] =
94 {"define", 1},
95 {"elif", 0}, /* Converted to #else..#if internally */
96 {"else", 0},
97 {"endif", 0},
98 {"error", 1},
99 {"if", 1},
100 {"ifdef", 1},
101 {"ifndef", 1},
102 {"include", 0}, /* Argument is not standard format, so 0 */
103 {"line", 1},
104 {"pragma", 1},
105 {"undef", 1},
106 {"warning", 1},
107 {NULL, 0}
110 enum Gbl_DirectiveIndexes
112 PR_DIRECTIVE_DEFINE = 0,
113 PR_DIRECTIVE_ELIF,
114 PR_DIRECTIVE_ELSE,
115 PR_DIRECTIVE_ENDIF,
116 PR_DIRECTIVE_ERROR,
117 PR_DIRECTIVE_IF,
118 PR_DIRECTIVE_IFDEF,
119 PR_DIRECTIVE_IFNDEF,
120 PR_DIRECTIVE_INCLUDE,
121 PR_DIRECTIVE_LINE,
122 PR_DIRECTIVE_PRAGMA,
123 PR_DIRECTIVE_UNDEF,
124 PR_DIRECTIVE_WARNING,
127 #define ASL_DIRECTIVE_NOT_FOUND -1
130 /*******************************************************************************
132 * FUNCTION: PrInitializePreprocessor
134 * PARAMETERS: None
136 * RETURN: None
138 * DESCRIPTION: Startup initialization for the Preprocessor.
140 ******************************************************************************/
142 void
143 PrInitializePreprocessor (
144 void)
146 /* Init globals and the list of #defines */
148 PrInitializeGlobals ();
149 Gbl_DefineList = NULL;
153 /*******************************************************************************
155 * FUNCTION: PrInitializeGlobals
157 * PARAMETERS: None
159 * RETURN: None
161 * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup
162 * initialization and re-initialization between compiles during
163 * a multiple source file compile.
165 ******************************************************************************/
167 void
168 PrInitializeGlobals (
169 void)
171 /* Init globals */
173 Gbl_InputFileList = NULL;
174 Gbl_CurrentLineNumber = 0;
175 Gbl_PreprocessorLineNumber = 1;
176 Gbl_PreprocessorError = FALSE;
178 /* These are used to track #if/#else blocks (possibly nested) */
180 Gbl_IfDepth = 0;
181 Gbl_IgnoringThisCodeBlock = FALSE;
182 Gbl_DirectiveStack = NULL;
186 /*******************************************************************************
188 * FUNCTION: PrTerminatePreprocessor
190 * PARAMETERS: None
192 * RETURN: None
194 * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any
195 * defines that were specified on the command line, in order to
196 * support multiple compiles with a single compiler invocation.
198 ******************************************************************************/
200 void
201 PrTerminatePreprocessor (
202 void)
204 PR_DEFINE_INFO *DefineInfo;
208 * The persistent defines (created on the command line) are always at the
209 * end of the list. We save them.
211 while ((Gbl_DefineList) && (!Gbl_DefineList->Persist))
213 DefineInfo = Gbl_DefineList;
214 Gbl_DefineList = DefineInfo->Next;
216 ACPI_FREE (DefineInfo->Replacement);
217 ACPI_FREE (DefineInfo->Identifier);
218 ACPI_FREE (DefineInfo);
223 /*******************************************************************************
225 * FUNCTION: PrDoPreprocess
227 * PARAMETERS: None
229 * RETURN: None
231 * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must
232 * be already open. Handles multiple input files via the
233 * #include directive.
235 ******************************************************************************/
237 void
238 PrDoPreprocess (
239 void)
241 BOOLEAN MoreInputFiles;
244 DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n");
247 FlSeekFile (ASL_FILE_INPUT, 0);
248 PrDumpPredefinedNames ();
250 /* Main preprocessor loop, handles include files */
254 PrPreprocessInputFile ();
255 MoreInputFiles = PrPopInputFileStack ();
257 } while (MoreInputFiles);
259 /* Point compiler input to the new preprocessor output file (.i) */
261 FlCloseFile (ASL_FILE_INPUT);
262 Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle;
263 AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
265 /* Reset globals to allow compiler to run */
267 FlSeekFile (ASL_FILE_INPUT, 0);
268 Gbl_CurrentLineNumber = 1;
270 DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n");
274 /*******************************************************************************
276 * FUNCTION: PrPreprocessInputFile
278 * PARAMETERS: None
280 * RETURN: None
282 * DESCRIPTION: Preprocess one entire file, line-by-line.
284 * Input: Raw user ASL from ASL_FILE_INPUT
285 * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR
287 ******************************************************************************/
289 static void
290 PrPreprocessInputFile (
291 void)
293 UINT32 Offset;
294 char *Token;
295 char *ReplaceString;
296 PR_DEFINE_INFO *DefineInfo;
297 ACPI_SIZE TokenOffset;
298 char *Next;
299 int OffsetAdjust;
302 /* Scan line-by-line. Comments and blank lines are skipped by this function */
304 while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF)
306 /* Need a copy of the input line for strok() */
308 strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer);
309 Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next);
310 OffsetAdjust = 0;
312 /* All preprocessor directives must begin with '#' */
314 if (Token && (*Token == '#'))
316 if (strlen (Token) == 1)
318 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
320 else
322 Token++; /* Skip leading # */
325 /* Execute the directive, do not write line to output file */
327 PrDoDirective (Token, &Next);
328 continue;
332 * If we are currently within the part of an IF/ELSE block that is
333 * FALSE, ignore the line and do not write it to the output file.
334 * This continues until an #else or #endif is encountered.
336 if (Gbl_IgnoringThisCodeBlock)
338 continue;
341 /* Match and replace all #defined names within this source line */
343 while (Token)
345 DefineInfo = PrMatchDefine (Token);
346 if (DefineInfo)
348 if (DefineInfo->Body)
350 /* This is a macro */
352 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
353 "Matched Macro: %s->%s\n",
354 Gbl_CurrentLineNumber, DefineInfo->Identifier,
355 DefineInfo->Replacement);
357 PrDoMacroInvocation (Gbl_MainTokenBuffer, Token,
358 DefineInfo, &Next);
360 else
362 ReplaceString = DefineInfo->Replacement;
364 /* Replace the name in the original line buffer */
366 TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust;
367 PrReplaceData (
368 &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token),
369 ReplaceString, strlen (ReplaceString));
371 /* Adjust for length difference between old and new name length */
373 OffsetAdjust += strlen (ReplaceString) - strlen (Token);
375 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
376 "Matched #define: %s->%s\n",
377 Gbl_CurrentLineNumber, Token,
378 *ReplaceString ? ReplaceString : "(NULL STRING)");
382 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
385 #if 0
386 /* Line prefix */
387 FlPrintFile (ASL_FILE_PREPROCESSOR, "/* %14s %.5u i:%.5u */ ",
388 Gbl_Files[ASL_FILE_INPUT].Filename,
389 Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber);
390 #endif
393 * Emit a #line directive if necessary, to keep the line numbers in
394 * the (.i) file synchronized with the original source code file, so
395 * that the correct line number appears in any error messages
396 * generated by the actual compiler.
398 if (Gbl_CurrentLineNumber > (Gbl_PreviousLineNumber + 1))
400 FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u\n",
401 Gbl_CurrentLineNumber);
404 Gbl_PreviousLineNumber = Gbl_CurrentLineNumber;
405 Gbl_PreprocessorLineNumber++;
408 * Now we can write the possibly modified source line to the
409 * preprocessor (.i) file
411 FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer,
412 strlen (Gbl_CurrentLineBuffer));
417 /*******************************************************************************
419 * FUNCTION: PrDoDirective
421 * PARAMETERS: Directive - Pointer to directive name token
422 * Next - "Next" buffer from GetNextToken
424 * RETURN: None.
426 * DESCRIPTION: Main processing for all preprocessor directives
428 ******************************************************************************/
430 static void
431 PrDoDirective (
432 char *DirectiveToken,
433 char **Next)
435 char *Token = Gbl_MainTokenBuffer;
436 char *Token2;
437 char *End;
438 UINT64 Value;
439 ACPI_SIZE TokenOffset;
440 int Directive;
441 ACPI_STATUS Status;
444 if (!DirectiveToken)
446 goto SyntaxError;
449 Directive = PrMatchDirective (DirectiveToken);
450 if (Directive == ASL_DIRECTIVE_NOT_FOUND)
452 PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE,
453 THIS_TOKEN_OFFSET (DirectiveToken));
455 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
456 "#%s: Unknown directive\n",
457 Gbl_CurrentLineNumber, DirectiveToken);
458 return;
462 * If we are currently ignoring this block and we encounter a #else or
463 * #elif, we must ignore their blocks also if the parent block is also
464 * being ignored.
466 if (Gbl_IgnoringThisCodeBlock)
468 switch (Directive)
470 case PR_DIRECTIVE_ELSE:
471 case PR_DIRECTIVE_ELIF:
473 if (Gbl_DirectiveStack && Gbl_DirectiveStack->IgnoringThisCodeBlock)
475 PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
476 return;
478 break;
480 default:
481 break;
486 * Need to always check for #else, #elif, #endif regardless of
487 * whether we are ignoring the current code block, since these
488 * are conditional code block terminators.
490 switch (Directive)
492 case PR_DIRECTIVE_ELSE:
494 Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
495 PrDbgPrint ("Executing", "else block");
496 return;
498 case PR_DIRECTIVE_ELIF:
500 Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
501 Directive = PR_DIRECTIVE_IF;
503 if (Gbl_IgnoringThisCodeBlock == TRUE)
505 /* Not executing the ELSE part -- all done here */
506 PrDbgPrint ("Ignoring", "elif block");
507 return;
511 * After this, we will execute the IF part further below.
512 * First, however, pop off the original #if directive.
514 if (ACPI_FAILURE (PrPopDirective ()))
516 PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
517 THIS_TOKEN_OFFSET (DirectiveToken));
520 PrDbgPrint ("Executing", "elif block");
521 break;
523 case PR_DIRECTIVE_ENDIF:
525 PrDbgPrint ("Executing", "endif");
527 /* Pop the owning #if/#ifdef/#ifndef */
529 if (ACPI_FAILURE (PrPopDirective ()))
531 PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH,
532 THIS_TOKEN_OFFSET (DirectiveToken));
534 return;
536 default:
537 break;
540 /* Most directives have at least one argument */
542 if (Gbl_DirectiveInfo[Directive].ArgCount == 1)
544 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
545 if (!Token)
547 goto SyntaxError;
552 * At this point, if we are ignoring the current code block,
553 * do not process any more directives (i.e., ignore them also.)
554 * For "if" style directives, open/push a new block anyway. We
555 * must do this to keep track of #endif directives
557 if (Gbl_IgnoringThisCodeBlock)
559 switch (Directive)
561 case PR_DIRECTIVE_IF:
562 case PR_DIRECTIVE_IFDEF:
563 case PR_DIRECTIVE_IFNDEF:
565 PrPushDirective (Directive, Token);
566 PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
567 break;
569 default:
570 break;
573 return;
577 * Execute the directive
579 PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name);
581 switch (Directive)
583 case PR_DIRECTIVE_IF:
585 TokenOffset = Token - Gbl_MainTokenBuffer;
587 /* Need to expand #define macros in the expression string first */
589 Status = PrResolveIntegerExpression (
590 &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
591 if (ACPI_FAILURE (Status))
593 return;
596 PrPushDirective (Directive, Token);
597 if (!Value)
599 Gbl_IgnoringThisCodeBlock = TRUE;
602 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
603 "Resolved #if: %8.8X%8.8X %s\n",
604 Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value),
605 Gbl_IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>");
606 break;
608 case PR_DIRECTIVE_IFDEF:
610 PrPushDirective (Directive, Token);
611 if (!PrMatchDefine (Token))
613 Gbl_IgnoringThisCodeBlock = TRUE;
616 PrDbgPrint ("Evaluated", "ifdef");
617 break;
619 case PR_DIRECTIVE_IFNDEF:
621 PrPushDirective (Directive, Token);
622 if (PrMatchDefine (Token))
624 Gbl_IgnoringThisCodeBlock = TRUE;
627 PrDbgPrint ("Evaluated", "ifndef");
628 break;
630 case PR_DIRECTIVE_DEFINE:
632 * By definition, if first char after the name is a paren,
633 * this is a function macro.
635 TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token);
636 if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(')
638 #ifndef MACROS_SUPPORTED
639 AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n",
640 Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber);
641 exit(1);
642 #else
643 PrAddMacro (Token, Next);
644 #endif
646 else
648 /* Use the remainder of the line for the #define */
650 Token2 = *Next;
651 if (Token2)
653 while ((*Token2 == ' ') || (*Token2 == '\t'))
655 Token2++;
657 End = Token2;
658 while (*End != '\n')
660 End++;
662 *End = 0;
664 else
666 Token2 = "";
668 #if 0
669 Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next);
670 if (!Token2)
672 Token2 = "";
674 #endif
675 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
676 "New #define: %s->%s\n",
677 Gbl_CurrentLineNumber, Token, Token2);
679 PrAddDefine (Token, Token2, FALSE);
681 break;
683 case PR_DIRECTIVE_ERROR:
685 /* Note: No macro expansion */
687 PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE,
688 THIS_TOKEN_OFFSET (Token));
690 Gbl_SourceLine = 0;
691 Gbl_NextError = Gbl_ErrorLog;
692 CmCleanupAndExit ();
693 exit(1);
695 case PR_DIRECTIVE_INCLUDE:
697 Token = PrGetNextToken (NULL, " \"<>", Next);
698 if (!Token)
700 goto SyntaxError;
703 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
704 "Start #include file \"%s\"\n", Gbl_CurrentLineNumber,
705 Token, Gbl_CurrentLineNumber);
707 PrOpenIncludeFile (Token);
708 break;
710 case PR_DIRECTIVE_LINE:
712 TokenOffset = Token - Gbl_MainTokenBuffer;
714 Status = PrResolveIntegerExpression (
715 &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
716 if (ACPI_FAILURE (Status))
718 return;
721 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
722 "User #line invocation %s\n", Gbl_CurrentLineNumber,
723 Token);
725 /* Update local line numbers */
727 Gbl_CurrentLineNumber = (UINT32) Value;
728 Gbl_PreviousLineNumber = 0;
730 /* Emit #line into the preprocessor file */
732 FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
733 Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename);
734 break;
736 case PR_DIRECTIVE_PRAGMA:
738 if (!strcmp (Token, "disable"))
740 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
741 if (!Token)
743 goto SyntaxError;
746 TokenOffset = Token - Gbl_MainTokenBuffer;
747 AslDisableException (&Gbl_CurrentLineBuffer[TokenOffset]);
749 else if (!strcmp (Token, "message"))
751 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
752 if (!Token)
754 goto SyntaxError;
757 TokenOffset = Token - Gbl_MainTokenBuffer;
758 AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]);
760 else
762 PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA,
763 THIS_TOKEN_OFFSET (Token));
764 return;
767 break;
769 case PR_DIRECTIVE_UNDEF:
771 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
772 "#undef: %s\n", Gbl_CurrentLineNumber, Token);
774 PrRemoveDefine (Token);
775 break;
777 case PR_DIRECTIVE_WARNING:
779 PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE,
780 THIS_TOKEN_OFFSET (Token));
781 break;
783 default:
785 /* Should never get here */
786 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
787 "Unrecognized directive: %u\n",
788 Gbl_CurrentLineNumber, Directive);
789 break;
792 return;
794 SyntaxError:
796 PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX,
797 THIS_TOKEN_OFFSET (DirectiveToken));
798 return;
802 /*******************************************************************************
804 * FUNCTION: PrMatchDirective
806 * PARAMETERS: Directive - Pointer to directive name token
808 * RETURN: Index into command array, -1 if not found
810 * DESCRIPTION: Lookup the incoming directive in the known directives table.
812 ******************************************************************************/
814 static int
815 PrMatchDirective (
816 char *Directive)
818 int i;
821 if (!Directive || Directive[0] == 0)
823 return (ASL_DIRECTIVE_NOT_FOUND);
826 for (i = 0; Gbl_DirectiveInfo[i].Name; i++)
828 if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive))
830 return (i);
834 return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */
838 /*******************************************************************************
840 * FUNCTION: PrPushDirective
842 * PARAMETERS: Directive - Encoded directive ID
843 * Argument - String containing argument to the
844 * directive
846 * RETURN: None
848 * DESCRIPTION: Push an item onto the directive stack. Used for processing
849 * nested #if/#else type conditional compilation directives.
850 * Specifically: Used on detection of #if/#ifdef/#ifndef to open
851 * a block.
853 ******************************************************************************/
855 static void
856 PrPushDirective (
857 int Directive,
858 char *Argument)
860 DIRECTIVE_INFO *Info;
863 /* Allocate and populate a stack info item */
865 Info = ACPI_ALLOCATE (sizeof (DIRECTIVE_INFO));
867 Info->Next = Gbl_DirectiveStack;
868 Info->Directive = Directive;
869 Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock;
870 strncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH);
872 DbgPrint (ASL_DEBUG_OUTPUT,
873 "Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n",
874 Gbl_CurrentLineNumber, Gbl_IfDepth,
875 Gbl_IgnoringThisCodeBlock ? "I" : "E",
876 Gbl_IfDepth * 4, " ",
877 Gbl_DirectiveInfo[Directive].Name,
878 Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
880 /* Push new item */
882 Gbl_DirectiveStack = Info;
883 Gbl_IfDepth++;
887 /*******************************************************************************
889 * FUNCTION: PrPopDirective
891 * PARAMETERS: None
893 * RETURN: Status. Error if the stack is empty.
895 * DESCRIPTION: Pop an item off the directive stack. Used for processing
896 * nested #if/#else type conditional compilation directives.
897 * Specifically: Used on detection of #elif and #endif to remove
898 * the original #if/#ifdef/#ifndef from the stack and close
899 * the block.
901 ******************************************************************************/
903 static ACPI_STATUS
904 PrPopDirective (
905 void)
907 DIRECTIVE_INFO *Info;
910 /* Check for empty stack */
912 Info = Gbl_DirectiveStack;
913 if (!Info)
915 return (AE_ERROR);
918 /* Pop one item, keep globals up-to-date */
920 Gbl_IfDepth--;
921 Gbl_IgnoringThisCodeBlock = Info->IgnoringThisCodeBlock;
922 Gbl_DirectiveStack = Info->Next;
924 DbgPrint (ASL_DEBUG_OUTPUT,
925 "Pr(%.4u) - [%u %s] %*s Popped [#%s %s]: IgnoreFlag now = %s\n",
926 Gbl_CurrentLineNumber, Gbl_IfDepth,
927 Gbl_IgnoringThisCodeBlock ? "I" : "E",
928 Gbl_IfDepth * 4, " ",
929 Gbl_DirectiveInfo[Info->Directive].Name,
930 Info->Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
932 ACPI_FREE (Info);
933 return (AE_OK);
937 /*******************************************************************************
939 * FUNCTION: PrDbgPrint
941 * PARAMETERS: Action - Action being performed
942 * DirectiveName - Directive being processed
944 * RETURN: None
946 * DESCRIPTION: Special debug print for directive processing.
948 ******************************************************************************/
950 static void
951 PrDbgPrint (
952 char *Action,
953 char *DirectiveName)
956 DbgPrint (ASL_DEBUG_OUTPUT, "Pr(%.4u) - [%u %s] "
957 "%*s %s #%s, Depth %u\n",
958 Gbl_CurrentLineNumber, Gbl_IfDepth,
959 Gbl_IgnoringThisCodeBlock ? "I" : "E",
960 Gbl_IfDepth * 4, " ",
961 Action, DirectiveName, Gbl_IfDepth);