xref: /illumos-gate/usr/src/cmd/acpi/iasl/prscan.c (revision bc36eafd)
1*bc36eafdSMike Gerdts /******************************************************************************
2*bc36eafdSMike Gerdts  *
3*bc36eafdSMike Gerdts  * Module Name: prscan - Preprocessor start-up and file scan module
4*bc36eafdSMike Gerdts  *
5*bc36eafdSMike Gerdts  *****************************************************************************/
6*bc36eafdSMike Gerdts 
7*bc36eafdSMike Gerdts /*
8*bc36eafdSMike Gerdts  * Copyright (C) 2000 - 2016, Intel Corp.
9*bc36eafdSMike Gerdts  * All rights reserved.
10*bc36eafdSMike Gerdts  *
11*bc36eafdSMike Gerdts  * Redistribution and use in source and binary forms, with or without
12*bc36eafdSMike Gerdts  * modification, are permitted provided that the following conditions
13*bc36eafdSMike Gerdts  * are met:
14*bc36eafdSMike Gerdts  * 1. Redistributions of source code must retain the above copyright
15*bc36eafdSMike Gerdts  *    notice, this list of conditions, and the following disclaimer,
16*bc36eafdSMike Gerdts  *    without modification.
17*bc36eafdSMike Gerdts  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*bc36eafdSMike Gerdts  *    substantially similar to the "NO WARRANTY" disclaimer below
19*bc36eafdSMike Gerdts  *    ("Disclaimer") and any redistribution must be conditioned upon
20*bc36eafdSMike Gerdts  *    including a substantially similar Disclaimer requirement for further
21*bc36eafdSMike Gerdts  *    binary redistribution.
22*bc36eafdSMike Gerdts  * 3. Neither the names of the above-listed copyright holders nor the names
23*bc36eafdSMike Gerdts  *    of any contributors may be used to endorse or promote products derived
24*bc36eafdSMike Gerdts  *    from this software without specific prior written permission.
25*bc36eafdSMike Gerdts  *
26*bc36eafdSMike Gerdts  * Alternatively, this software may be distributed under the terms of the
27*bc36eafdSMike Gerdts  * GNU General Public License ("GPL") version 2 as published by the Free
28*bc36eafdSMike Gerdts  * Software Foundation.
29*bc36eafdSMike Gerdts  *
30*bc36eafdSMike Gerdts  * NO WARRANTY
31*bc36eafdSMike Gerdts  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*bc36eafdSMike Gerdts  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*bc36eafdSMike Gerdts  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*bc36eafdSMike Gerdts  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*bc36eafdSMike Gerdts  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*bc36eafdSMike Gerdts  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*bc36eafdSMike Gerdts  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*bc36eafdSMike Gerdts  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*bc36eafdSMike Gerdts  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*bc36eafdSMike Gerdts  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*bc36eafdSMike Gerdts  * POSSIBILITY OF SUCH DAMAGES.
42*bc36eafdSMike Gerdts  */
43*bc36eafdSMike Gerdts 
44*bc36eafdSMike Gerdts #define _DECLARE_PR_GLOBALS
45*bc36eafdSMike Gerdts 
46*bc36eafdSMike Gerdts #include "aslcompiler.h"
47*bc36eafdSMike Gerdts #include "dtcompiler.h"
48*bc36eafdSMike Gerdts 
49*bc36eafdSMike Gerdts /*
50*bc36eafdSMike Gerdts  * TBDs:
51*bc36eafdSMike Gerdts  *
52*bc36eafdSMike Gerdts  * No nested macros, maybe never
53*bc36eafdSMike Gerdts  * Implement ASL "Include" as well as "#include" here?
54*bc36eafdSMike Gerdts  */
55*bc36eafdSMike Gerdts #define _COMPONENT          ASL_PREPROCESSOR
56*bc36eafdSMike Gerdts         ACPI_MODULE_NAME    ("prscan")
57*bc36eafdSMike Gerdts 
58*bc36eafdSMike Gerdts 
59*bc36eafdSMike Gerdts /* Local prototypes */
60*bc36eafdSMike Gerdts 
61*bc36eafdSMike Gerdts static void
62*bc36eafdSMike Gerdts PrPreprocessInputFile (
63*bc36eafdSMike Gerdts     void);
64*bc36eafdSMike Gerdts 
65*bc36eafdSMike Gerdts static void
66*bc36eafdSMike Gerdts PrDoDirective (
67*bc36eafdSMike Gerdts     char                    *DirectiveToken,
68*bc36eafdSMike Gerdts     char                    **Next);
69*bc36eafdSMike Gerdts 
70*bc36eafdSMike Gerdts static void
71*bc36eafdSMike Gerdts PrGetNextLineInit (
72*bc36eafdSMike Gerdts     void);
73*bc36eafdSMike Gerdts 
74*bc36eafdSMike Gerdts static UINT32
75*bc36eafdSMike Gerdts PrGetNextLine (
76*bc36eafdSMike Gerdts     FILE                    *Handle);
77*bc36eafdSMike Gerdts 
78*bc36eafdSMike Gerdts static int
79*bc36eafdSMike Gerdts PrMatchDirective (
80*bc36eafdSMike Gerdts     char                    *Directive);
81*bc36eafdSMike Gerdts 
82*bc36eafdSMike Gerdts static void
83*bc36eafdSMike Gerdts PrPushDirective (
84*bc36eafdSMike Gerdts     int                     Directive,
85*bc36eafdSMike Gerdts     char                    *Argument);
86*bc36eafdSMike Gerdts 
87*bc36eafdSMike Gerdts static ACPI_STATUS
88*bc36eafdSMike Gerdts PrPopDirective (
89*bc36eafdSMike Gerdts     void);
90*bc36eafdSMike Gerdts 
91*bc36eafdSMike Gerdts static void
92*bc36eafdSMike Gerdts PrDbgPrint (
93*bc36eafdSMike Gerdts     char                    *Action,
94*bc36eafdSMike Gerdts     char                    *DirectiveName);
95*bc36eafdSMike Gerdts 
96*bc36eafdSMike Gerdts static void
97*bc36eafdSMike Gerdts PrDoIncludeBuffer (
98*bc36eafdSMike Gerdts     char                    *Pathname,
99*bc36eafdSMike Gerdts     char                    *BufferName);
100*bc36eafdSMike Gerdts 
101*bc36eafdSMike Gerdts static void
102*bc36eafdSMike Gerdts PrDoIncludeFile (
103*bc36eafdSMike Gerdts     char                    *Pathname);
104*bc36eafdSMike Gerdts 
105*bc36eafdSMike Gerdts 
106*bc36eafdSMike Gerdts /*
107*bc36eafdSMike Gerdts  * Supported preprocessor directives
108*bc36eafdSMike Gerdts  * Each entry is of the form "Name, ArgumentCount"
109*bc36eafdSMike Gerdts  */
110*bc36eafdSMike Gerdts static const PR_DIRECTIVE_INFO      Gbl_DirectiveInfo[] =
111*bc36eafdSMike Gerdts {
112*bc36eafdSMike Gerdts     {"define",          1},
113*bc36eafdSMike Gerdts     {"elif",            0}, /* Converted to #else..#if internally */
114*bc36eafdSMike Gerdts     {"else",            0},
115*bc36eafdSMike Gerdts     {"endif",           0},
116*bc36eafdSMike Gerdts     {"error",           1},
117*bc36eafdSMike Gerdts     {"if",              1},
118*bc36eafdSMike Gerdts     {"ifdef",           1},
119*bc36eafdSMike Gerdts     {"ifndef",          1},
120*bc36eafdSMike Gerdts     {"include",         0}, /* Argument is not standard format, so just use 0 here */
121*bc36eafdSMike Gerdts     {"includebuffer",   0}, /* Argument is not standard format, so just use 0 here */
122*bc36eafdSMike Gerdts     {"line",            1},
123*bc36eafdSMike Gerdts     {"pragma",          1},
124*bc36eafdSMike Gerdts     {"undef",           1},
125*bc36eafdSMike Gerdts     {"warning",         1},
126*bc36eafdSMike Gerdts     {NULL,              0}
127*bc36eafdSMike Gerdts };
128*bc36eafdSMike Gerdts 
129*bc36eafdSMike Gerdts /* This table must match ordering of above table exactly */
130*bc36eafdSMike Gerdts 
131*bc36eafdSMike Gerdts enum Gbl_DirectiveIndexes
132*bc36eafdSMike Gerdts {
133*bc36eafdSMike Gerdts     PR_DIRECTIVE_DEFINE = 0,
134*bc36eafdSMike Gerdts     PR_DIRECTIVE_ELIF,
135*bc36eafdSMike Gerdts     PR_DIRECTIVE_ELSE,
136*bc36eafdSMike Gerdts     PR_DIRECTIVE_ENDIF,
137*bc36eafdSMike Gerdts     PR_DIRECTIVE_ERROR,
138*bc36eafdSMike Gerdts     PR_DIRECTIVE_IF,
139*bc36eafdSMike Gerdts     PR_DIRECTIVE_IFDEF,
140*bc36eafdSMike Gerdts     PR_DIRECTIVE_IFNDEF,
141*bc36eafdSMike Gerdts     PR_DIRECTIVE_INCLUDE,
142*bc36eafdSMike Gerdts     PR_DIRECTIVE_INCLUDEBUFFER,
143*bc36eafdSMike Gerdts     PR_DIRECTIVE_LINE,
144*bc36eafdSMike Gerdts     PR_DIRECTIVE_PRAGMA,
145*bc36eafdSMike Gerdts     PR_DIRECTIVE_UNDEF,
146*bc36eafdSMike Gerdts     PR_DIRECTIVE_WARNING
147*bc36eafdSMike Gerdts };
148*bc36eafdSMike Gerdts 
149*bc36eafdSMike Gerdts #define ASL_DIRECTIVE_NOT_FOUND     -1
150*bc36eafdSMike Gerdts 
151*bc36eafdSMike Gerdts 
152*bc36eafdSMike Gerdts /*******************************************************************************
153*bc36eafdSMike Gerdts  *
154*bc36eafdSMike Gerdts  * FUNCTION:    PrInitializePreprocessor
155*bc36eafdSMike Gerdts  *
156*bc36eafdSMike Gerdts  * PARAMETERS:  None
157*bc36eafdSMike Gerdts  *
158*bc36eafdSMike Gerdts  * RETURN:      None
159*bc36eafdSMike Gerdts  *
160*bc36eafdSMike Gerdts  * DESCRIPTION: Startup initialization for the Preprocessor.
161*bc36eafdSMike Gerdts  *
162*bc36eafdSMike Gerdts  ******************************************************************************/
163*bc36eafdSMike Gerdts 
164*bc36eafdSMike Gerdts void
165*bc36eafdSMike Gerdts PrInitializePreprocessor (
166*bc36eafdSMike Gerdts     void)
167*bc36eafdSMike Gerdts {
168*bc36eafdSMike Gerdts     /* Init globals and the list of #defines */
169*bc36eafdSMike Gerdts 
170*bc36eafdSMike Gerdts     PrInitializeGlobals ();
171*bc36eafdSMike Gerdts     Gbl_DefineList = NULL;
172*bc36eafdSMike Gerdts }
173*bc36eafdSMike Gerdts 
174*bc36eafdSMike Gerdts 
175*bc36eafdSMike Gerdts /*******************************************************************************
176*bc36eafdSMike Gerdts  *
177*bc36eafdSMike Gerdts  * FUNCTION:    PrInitializeGlobals
178*bc36eafdSMike Gerdts  *
179*bc36eafdSMike Gerdts  * PARAMETERS:  None
180*bc36eafdSMike Gerdts  *
181*bc36eafdSMike Gerdts  * RETURN:      None
182*bc36eafdSMike Gerdts  *
183*bc36eafdSMike Gerdts  * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup
184*bc36eafdSMike Gerdts  *              initialization and re-initialization between compiles during
185*bc36eafdSMike Gerdts  *              a multiple source file compile.
186*bc36eafdSMike Gerdts  *
187*bc36eafdSMike Gerdts  ******************************************************************************/
188*bc36eafdSMike Gerdts 
189*bc36eafdSMike Gerdts void
190*bc36eafdSMike Gerdts PrInitializeGlobals (
191*bc36eafdSMike Gerdts     void)
192*bc36eafdSMike Gerdts {
193*bc36eafdSMike Gerdts     /* Init globals */
194*bc36eafdSMike Gerdts 
195*bc36eafdSMike Gerdts     Gbl_InputFileList = NULL;
196*bc36eafdSMike Gerdts     Gbl_CurrentLineNumber = 1;
197*bc36eafdSMike Gerdts     Gbl_PreprocessorLineNumber = 1;
198*bc36eafdSMike Gerdts     Gbl_PreprocessorError = FALSE;
199*bc36eafdSMike Gerdts 
200*bc36eafdSMike Gerdts     /* These are used to track #if/#else blocks (possibly nested) */
201*bc36eafdSMike Gerdts 
202*bc36eafdSMike Gerdts     Gbl_IfDepth = 0;
203*bc36eafdSMike Gerdts     Gbl_IgnoringThisCodeBlock = FALSE;
204*bc36eafdSMike Gerdts     Gbl_DirectiveStack = NULL;
205*bc36eafdSMike Gerdts }
206*bc36eafdSMike Gerdts 
207*bc36eafdSMike Gerdts 
208*bc36eafdSMike Gerdts /*******************************************************************************
209*bc36eafdSMike Gerdts  *
210*bc36eafdSMike Gerdts  * FUNCTION:    PrTerminatePreprocessor
211*bc36eafdSMike Gerdts  *
212*bc36eafdSMike Gerdts  * PARAMETERS:  None
213*bc36eafdSMike Gerdts  *
214*bc36eafdSMike Gerdts  * RETURN:      None
215*bc36eafdSMike Gerdts  *
216*bc36eafdSMike Gerdts  * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any
217*bc36eafdSMike Gerdts  *              defines that were specified on the command line, in order to
218*bc36eafdSMike Gerdts  *              support multiple compiles with a single compiler invocation.
219*bc36eafdSMike Gerdts  *
220*bc36eafdSMike Gerdts  ******************************************************************************/
221*bc36eafdSMike Gerdts 
222*bc36eafdSMike Gerdts void
223*bc36eafdSMike Gerdts PrTerminatePreprocessor (
224*bc36eafdSMike Gerdts     void)
225*bc36eafdSMike Gerdts {
226*bc36eafdSMike Gerdts     PR_DEFINE_INFO          *DefineInfo;
227*bc36eafdSMike Gerdts 
228*bc36eafdSMike Gerdts 
229*bc36eafdSMike Gerdts     /*
230*bc36eafdSMike Gerdts      * The persistent defines (created on the command line) are always at the
231*bc36eafdSMike Gerdts      * end of the list. We save them.
232*bc36eafdSMike Gerdts      */
233*bc36eafdSMike Gerdts     while ((Gbl_DefineList) && (!Gbl_DefineList->Persist))
234*bc36eafdSMike Gerdts     {
235*bc36eafdSMike Gerdts         DefineInfo = Gbl_DefineList;
236*bc36eafdSMike Gerdts         Gbl_DefineList = DefineInfo->Next;
237*bc36eafdSMike Gerdts 
238*bc36eafdSMike Gerdts         ACPI_FREE (DefineInfo->Replacement);
239*bc36eafdSMike Gerdts         ACPI_FREE (DefineInfo->Identifier);
240*bc36eafdSMike Gerdts         ACPI_FREE (DefineInfo);
241*bc36eafdSMike Gerdts     }
242*bc36eafdSMike Gerdts }
243*bc36eafdSMike Gerdts 
244*bc36eafdSMike Gerdts 
245*bc36eafdSMike Gerdts /*******************************************************************************
246*bc36eafdSMike Gerdts  *
247*bc36eafdSMike Gerdts  * FUNCTION:    PrDoPreprocess
248*bc36eafdSMike Gerdts  *
249*bc36eafdSMike Gerdts  * PARAMETERS:  None
250*bc36eafdSMike Gerdts  *
251*bc36eafdSMike Gerdts  * RETURN:      None
252*bc36eafdSMike Gerdts  *
253*bc36eafdSMike Gerdts  * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must
254*bc36eafdSMike Gerdts  *              be already open. Handles multiple input files via the
255*bc36eafdSMike Gerdts  *              #include directive.
256*bc36eafdSMike Gerdts  *
257*bc36eafdSMike Gerdts  ******************************************************************************/
258*bc36eafdSMike Gerdts 
259*bc36eafdSMike Gerdts void
260*bc36eafdSMike Gerdts PrDoPreprocess (
261*bc36eafdSMike Gerdts     void)
262*bc36eafdSMike Gerdts {
263*bc36eafdSMike Gerdts     BOOLEAN                 MoreInputFiles;
264*bc36eafdSMike Gerdts 
265*bc36eafdSMike Gerdts 
266*bc36eafdSMike Gerdts     DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n");
267*bc36eafdSMike Gerdts 
268*bc36eafdSMike Gerdts 
269*bc36eafdSMike Gerdts     FlSeekFile (ASL_FILE_INPUT, 0);
270*bc36eafdSMike Gerdts     PrDumpPredefinedNames ();
271*bc36eafdSMike Gerdts 
272*bc36eafdSMike Gerdts     /* Main preprocessor loop, handles include files */
273*bc36eafdSMike Gerdts 
274*bc36eafdSMike Gerdts     do
275*bc36eafdSMike Gerdts     {
276*bc36eafdSMike Gerdts         PrPreprocessInputFile ();
277*bc36eafdSMike Gerdts         MoreInputFiles = PrPopInputFileStack ();
278*bc36eafdSMike Gerdts 
279*bc36eafdSMike Gerdts     } while (MoreInputFiles);
280*bc36eafdSMike Gerdts 
281*bc36eafdSMike Gerdts     /* Point compiler input to the new preprocessor output file (.pre) */
282*bc36eafdSMike Gerdts 
283*bc36eafdSMike Gerdts     FlCloseFile (ASL_FILE_INPUT);
284*bc36eafdSMike Gerdts     Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle;
285*bc36eafdSMike Gerdts     AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
286*bc36eafdSMike Gerdts 
287*bc36eafdSMike Gerdts     /* Reset globals to allow compiler to run */
288*bc36eafdSMike Gerdts 
289*bc36eafdSMike Gerdts     FlSeekFile (ASL_FILE_INPUT, 0);
290*bc36eafdSMike Gerdts     if (!Gbl_PreprocessOnly)
291*bc36eafdSMike Gerdts     {
292*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber = 0;
293*bc36eafdSMike Gerdts     }
294*bc36eafdSMike Gerdts 
295*bc36eafdSMike Gerdts     DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n");
296*bc36eafdSMike Gerdts }
297*bc36eafdSMike Gerdts 
298*bc36eafdSMike Gerdts 
299*bc36eafdSMike Gerdts /*******************************************************************************
300*bc36eafdSMike Gerdts  *
301*bc36eafdSMike Gerdts  * FUNCTION:    PrPreprocessInputFile
302*bc36eafdSMike Gerdts  *
303*bc36eafdSMike Gerdts  * PARAMETERS:  None
304*bc36eafdSMike Gerdts  *
305*bc36eafdSMike Gerdts  * RETURN:      None
306*bc36eafdSMike Gerdts  *
307*bc36eafdSMike Gerdts  * DESCRIPTION: Preprocess one entire file, line-by-line.
308*bc36eafdSMike Gerdts  *
309*bc36eafdSMike Gerdts  * Input:  Raw user ASL from ASL_FILE_INPUT
310*bc36eafdSMike Gerdts  * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR and
311*bc36eafdSMike Gerdts  *         (optionally) ASL_FILE_PREPROCESSOR_USER
312*bc36eafdSMike Gerdts  *
313*bc36eafdSMike Gerdts  ******************************************************************************/
314*bc36eafdSMike Gerdts 
315*bc36eafdSMike Gerdts static void
316*bc36eafdSMike Gerdts PrPreprocessInputFile (
317*bc36eafdSMike Gerdts     void)
318*bc36eafdSMike Gerdts {
319*bc36eafdSMike Gerdts     UINT32                  Status;
320*bc36eafdSMike Gerdts     char                    *Token;
321*bc36eafdSMike Gerdts     char                    *ReplaceString;
322*bc36eafdSMike Gerdts     PR_DEFINE_INFO          *DefineInfo;
323*bc36eafdSMike Gerdts     ACPI_SIZE               TokenOffset;
324*bc36eafdSMike Gerdts     char                    *Next;
325*bc36eafdSMike Gerdts     int                     OffsetAdjust;
326*bc36eafdSMike Gerdts 
327*bc36eafdSMike Gerdts 
328*bc36eafdSMike Gerdts     PrGetNextLineInit ();
329*bc36eafdSMike Gerdts 
330*bc36eafdSMike Gerdts     /* Scan source line-by-line and process directives. Then write the .i file */
331*bc36eafdSMike Gerdts 
332*bc36eafdSMike Gerdts     while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF)
333*bc36eafdSMike Gerdts     {
334*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber++;
335*bc36eafdSMike Gerdts         Gbl_LogicalLineNumber++;
336*bc36eafdSMike Gerdts 
337*bc36eafdSMike Gerdts         if (Status == ASL_IGNORE_LINE)
338*bc36eafdSMike Gerdts         {
339*bc36eafdSMike Gerdts             goto WriteEntireLine;
340*bc36eafdSMike Gerdts         }
341*bc36eafdSMike Gerdts 
342*bc36eafdSMike Gerdts         /* Need a copy of the input line for strok() */
343*bc36eafdSMike Gerdts 
344*bc36eafdSMike Gerdts         strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer);
345*bc36eafdSMike Gerdts         Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next);
346*bc36eafdSMike Gerdts         OffsetAdjust = 0;
347*bc36eafdSMike Gerdts 
348*bc36eafdSMike Gerdts         /* All preprocessor directives must begin with '#' */
349*bc36eafdSMike Gerdts 
350*bc36eafdSMike Gerdts         if (Token && (*Token == '#'))
351*bc36eafdSMike Gerdts         {
352*bc36eafdSMike Gerdts             if (strlen (Token) == 1)
353*bc36eafdSMike Gerdts             {
354*bc36eafdSMike Gerdts                 Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
355*bc36eafdSMike Gerdts             }
356*bc36eafdSMike Gerdts             else
357*bc36eafdSMike Gerdts             {
358*bc36eafdSMike Gerdts                 Token++;    /* Skip leading # */
359*bc36eafdSMike Gerdts             }
360*bc36eafdSMike Gerdts 
361*bc36eafdSMike Gerdts             /* Execute the directive, do not write line to output file */
362*bc36eafdSMike Gerdts 
363*bc36eafdSMike Gerdts             PrDoDirective (Token, &Next);
364*bc36eafdSMike Gerdts             continue;
365*bc36eafdSMike Gerdts         }
366*bc36eafdSMike Gerdts 
367*bc36eafdSMike Gerdts         /*
368*bc36eafdSMike Gerdts          * If we are currently within the part of an IF/ELSE block that is
369*bc36eafdSMike Gerdts          * FALSE, ignore the line and do not write it to the output file.
370*bc36eafdSMike Gerdts          * This continues until an #else or #endif is encountered.
371*bc36eafdSMike Gerdts          */
372*bc36eafdSMike Gerdts         if (Gbl_IgnoringThisCodeBlock)
373*bc36eafdSMike Gerdts         {
374*bc36eafdSMike Gerdts             continue;
375*bc36eafdSMike Gerdts         }
376*bc36eafdSMike Gerdts 
377*bc36eafdSMike Gerdts         /* Match and replace all #defined names within this source line */
378*bc36eafdSMike Gerdts 
379*bc36eafdSMike Gerdts         while (Token)
380*bc36eafdSMike Gerdts         {
381*bc36eafdSMike Gerdts             DefineInfo = PrMatchDefine (Token);
382*bc36eafdSMike Gerdts             if (DefineInfo)
383*bc36eafdSMike Gerdts             {
384*bc36eafdSMike Gerdts                 if (DefineInfo->Body)
385*bc36eafdSMike Gerdts                 {
386*bc36eafdSMike Gerdts                     /* This is a macro */
387*bc36eafdSMike Gerdts 
388*bc36eafdSMike Gerdts                     DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
389*bc36eafdSMike Gerdts                         "Matched Macro: %s->%s\n",
390*bc36eafdSMike Gerdts                         Gbl_CurrentLineNumber, DefineInfo->Identifier,
391*bc36eafdSMike Gerdts                         DefineInfo->Replacement);
392*bc36eafdSMike Gerdts 
393*bc36eafdSMike Gerdts                     PrDoMacroInvocation (Gbl_MainTokenBuffer, Token,
394*bc36eafdSMike Gerdts                         DefineInfo, &Next);
395*bc36eafdSMike Gerdts                 }
396*bc36eafdSMike Gerdts                 else
397*bc36eafdSMike Gerdts                 {
398*bc36eafdSMike Gerdts                     ReplaceString = DefineInfo->Replacement;
399*bc36eafdSMike Gerdts 
400*bc36eafdSMike Gerdts                     /* Replace the name in the original line buffer */
401*bc36eafdSMike Gerdts 
402*bc36eafdSMike Gerdts                     TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust;
403*bc36eafdSMike Gerdts                     PrReplaceData (
404*bc36eafdSMike Gerdts                         &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token),
405*bc36eafdSMike Gerdts                         ReplaceString, strlen (ReplaceString));
406*bc36eafdSMike Gerdts 
407*bc36eafdSMike Gerdts                     /* Adjust for length difference between old and new name length */
408*bc36eafdSMike Gerdts 
409*bc36eafdSMike Gerdts                     OffsetAdjust += strlen (ReplaceString) - strlen (Token);
410*bc36eafdSMike Gerdts 
411*bc36eafdSMike Gerdts                     DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
412*bc36eafdSMike Gerdts                         "Matched #define: %s->%s\n",
413*bc36eafdSMike Gerdts                         Gbl_CurrentLineNumber, Token,
414*bc36eafdSMike Gerdts                         *ReplaceString ? ReplaceString : "(NULL STRING)");
415*bc36eafdSMike Gerdts                 }
416*bc36eafdSMike Gerdts             }
417*bc36eafdSMike Gerdts 
418*bc36eafdSMike Gerdts             Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
419*bc36eafdSMike Gerdts         }
420*bc36eafdSMike Gerdts 
421*bc36eafdSMike Gerdts         Gbl_PreprocessorLineNumber++;
422*bc36eafdSMike Gerdts 
423*bc36eafdSMike Gerdts 
424*bc36eafdSMike Gerdts WriteEntireLine:
425*bc36eafdSMike Gerdts         /*
426*bc36eafdSMike Gerdts          * Now we can write the possibly modified source line to the
427*bc36eafdSMike Gerdts          * preprocessor file(s).
428*bc36eafdSMike Gerdts          */
429*bc36eafdSMike Gerdts         FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer,
430*bc36eafdSMike Gerdts             strlen (Gbl_CurrentLineBuffer));
431*bc36eafdSMike Gerdts     }
432*bc36eafdSMike Gerdts }
433*bc36eafdSMike Gerdts 
434*bc36eafdSMike Gerdts 
435*bc36eafdSMike Gerdts /*******************************************************************************
436*bc36eafdSMike Gerdts  *
437*bc36eafdSMike Gerdts  * FUNCTION:    PrDoDirective
438*bc36eafdSMike Gerdts  *
439*bc36eafdSMike Gerdts  * PARAMETERS:  Directive               - Pointer to directive name token
440*bc36eafdSMike Gerdts  *              Next                    - "Next" buffer from GetNextToken
441*bc36eafdSMike Gerdts  *
442*bc36eafdSMike Gerdts  * RETURN:      None.
443*bc36eafdSMike Gerdts  *
444*bc36eafdSMike Gerdts  * DESCRIPTION: Main processing for all preprocessor directives
445*bc36eafdSMike Gerdts  *
446*bc36eafdSMike Gerdts  ******************************************************************************/
447*bc36eafdSMike Gerdts 
448*bc36eafdSMike Gerdts static void
449*bc36eafdSMike Gerdts PrDoDirective (
450*bc36eafdSMike Gerdts     char                    *DirectiveToken,
451*bc36eafdSMike Gerdts     char                    **Next)
452*bc36eafdSMike Gerdts {
453*bc36eafdSMike Gerdts     char                    *Token = Gbl_MainTokenBuffer;
454*bc36eafdSMike Gerdts     char                    *Token2 = NULL;
455*bc36eafdSMike Gerdts     char                    *End;
456*bc36eafdSMike Gerdts     UINT64                  Value;
457*bc36eafdSMike Gerdts     ACPI_SIZE               TokenOffset;
458*bc36eafdSMike Gerdts     int                     Directive;
459*bc36eafdSMike Gerdts     ACPI_STATUS             Status;
460*bc36eafdSMike Gerdts 
461*bc36eafdSMike Gerdts 
462*bc36eafdSMike Gerdts     if (!DirectiveToken)
463*bc36eafdSMike Gerdts     {
464*bc36eafdSMike Gerdts         goto SyntaxError;
465*bc36eafdSMike Gerdts     }
466*bc36eafdSMike Gerdts 
467*bc36eafdSMike Gerdts     Directive = PrMatchDirective (DirectiveToken);
468*bc36eafdSMike Gerdts     if (Directive == ASL_DIRECTIVE_NOT_FOUND)
469*bc36eafdSMike Gerdts     {
470*bc36eafdSMike Gerdts         PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE,
471*bc36eafdSMike Gerdts             THIS_TOKEN_OFFSET (DirectiveToken));
472*bc36eafdSMike Gerdts 
473*bc36eafdSMike Gerdts         DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
474*bc36eafdSMike Gerdts             "#%s: Unknown directive\n",
475*bc36eafdSMike Gerdts             Gbl_CurrentLineNumber, DirectiveToken);
476*bc36eafdSMike Gerdts         return;
477*bc36eafdSMike Gerdts     }
478*bc36eafdSMike Gerdts 
479*bc36eafdSMike Gerdts     /*
480*bc36eafdSMike Gerdts      * Emit a line directive into the preprocessor file (.pre) after
481*bc36eafdSMike Gerdts      * every matched directive. This is passed through to the compiler
482*bc36eafdSMike Gerdts      * so that error/warning messages are kept in sync with the
483*bc36eafdSMike Gerdts      * original source file.
484*bc36eafdSMike Gerdts      */
485*bc36eafdSMike Gerdts     FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\" // #%s\n",
486*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename,
487*bc36eafdSMike Gerdts         Gbl_DirectiveInfo[Directive].Name);
488*bc36eafdSMike Gerdts 
489*bc36eafdSMike Gerdts     /*
490*bc36eafdSMike Gerdts      * If we are currently ignoring this block and we encounter a #else or
491*bc36eafdSMike Gerdts      * #elif, we must ignore their blocks also if the parent block is also
492*bc36eafdSMike Gerdts      * being ignored.
493*bc36eafdSMike Gerdts      */
494*bc36eafdSMike Gerdts     if (Gbl_IgnoringThisCodeBlock)
495*bc36eafdSMike Gerdts     {
496*bc36eafdSMike Gerdts         switch (Directive)
497*bc36eafdSMike Gerdts         {
498*bc36eafdSMike Gerdts         case PR_DIRECTIVE_ELSE:
499*bc36eafdSMike Gerdts         case PR_DIRECTIVE_ELIF:
500*bc36eafdSMike Gerdts 
501*bc36eafdSMike Gerdts             if (Gbl_DirectiveStack &&
502*bc36eafdSMike Gerdts                 Gbl_DirectiveStack->IgnoringThisCodeBlock)
503*bc36eafdSMike Gerdts             {
504*bc36eafdSMike Gerdts                 PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
505*bc36eafdSMike Gerdts                 return;
506*bc36eafdSMike Gerdts             }
507*bc36eafdSMike Gerdts             break;
508*bc36eafdSMike Gerdts 
509*bc36eafdSMike Gerdts         default:
510*bc36eafdSMike Gerdts             break;
511*bc36eafdSMike Gerdts         }
512*bc36eafdSMike Gerdts     }
513*bc36eafdSMike Gerdts 
514*bc36eafdSMike Gerdts     /*
515*bc36eafdSMike Gerdts      * Need to always check for #else, #elif, #endif regardless of
516*bc36eafdSMike Gerdts      * whether we are ignoring the current code block, since these
517*bc36eafdSMike Gerdts      * are conditional code block terminators.
518*bc36eafdSMike Gerdts      */
519*bc36eafdSMike Gerdts     switch (Directive)
520*bc36eafdSMike Gerdts     {
521*bc36eafdSMike Gerdts     case PR_DIRECTIVE_ELSE:
522*bc36eafdSMike Gerdts 
523*bc36eafdSMike Gerdts         Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
524*bc36eafdSMike Gerdts         PrDbgPrint ("Executing", "else block");
525*bc36eafdSMike Gerdts         return;
526*bc36eafdSMike Gerdts 
527*bc36eafdSMike Gerdts     case PR_DIRECTIVE_ELIF:
528*bc36eafdSMike Gerdts 
529*bc36eafdSMike Gerdts         Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
530*bc36eafdSMike Gerdts         Directive = PR_DIRECTIVE_IF;
531*bc36eafdSMike Gerdts 
532*bc36eafdSMike Gerdts         if (Gbl_IgnoringThisCodeBlock == TRUE)
533*bc36eafdSMike Gerdts         {
534*bc36eafdSMike Gerdts             /* Not executing the ELSE part -- all done here */
535*bc36eafdSMike Gerdts             PrDbgPrint ("Ignoring", "elif block");
536*bc36eafdSMike Gerdts             return;
537*bc36eafdSMike Gerdts         }
538*bc36eafdSMike Gerdts 
539*bc36eafdSMike Gerdts         /*
540*bc36eafdSMike Gerdts          * After this, we will execute the IF part further below.
541*bc36eafdSMike Gerdts          * First, however, pop off the original #if directive.
542*bc36eafdSMike Gerdts          */
543*bc36eafdSMike Gerdts         if (ACPI_FAILURE (PrPopDirective ()))
544*bc36eafdSMike Gerdts         {
545*bc36eafdSMike Gerdts             PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
546*bc36eafdSMike Gerdts                 THIS_TOKEN_OFFSET (DirectiveToken));
547*bc36eafdSMike Gerdts         }
548*bc36eafdSMike Gerdts 
549*bc36eafdSMike Gerdts         PrDbgPrint ("Executing", "elif block");
550*bc36eafdSMike Gerdts         break;
551*bc36eafdSMike Gerdts 
552*bc36eafdSMike Gerdts     case PR_DIRECTIVE_ENDIF:
553*bc36eafdSMike Gerdts 
554*bc36eafdSMike Gerdts         PrDbgPrint ("Executing", "endif");
555*bc36eafdSMike Gerdts 
556*bc36eafdSMike Gerdts         /* Pop the owning #if/#ifdef/#ifndef */
557*bc36eafdSMike Gerdts 
558*bc36eafdSMike Gerdts         if (ACPI_FAILURE (PrPopDirective ()))
559*bc36eafdSMike Gerdts         {
560*bc36eafdSMike Gerdts             PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH,
561*bc36eafdSMike Gerdts                 THIS_TOKEN_OFFSET (DirectiveToken));
562*bc36eafdSMike Gerdts         }
563*bc36eafdSMike Gerdts         return;
564*bc36eafdSMike Gerdts 
565*bc36eafdSMike Gerdts     default:
566*bc36eafdSMike Gerdts         break;
567*bc36eafdSMike Gerdts     }
568*bc36eafdSMike Gerdts 
569*bc36eafdSMike Gerdts     /* Most directives have at least one argument */
570*bc36eafdSMike Gerdts 
571*bc36eafdSMike Gerdts     if (Gbl_DirectiveInfo[Directive].ArgCount >= 1)
572*bc36eafdSMike Gerdts     {
573*bc36eafdSMike Gerdts         Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
574*bc36eafdSMike Gerdts         if (!Token)
575*bc36eafdSMike Gerdts         {
576*bc36eafdSMike Gerdts             goto SyntaxError;
577*bc36eafdSMike Gerdts         }
578*bc36eafdSMike Gerdts     }
579*bc36eafdSMike Gerdts 
580*bc36eafdSMike Gerdts     if (Gbl_DirectiveInfo[Directive].ArgCount >= 2)
581*bc36eafdSMike Gerdts     {
582*bc36eafdSMike Gerdts         Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
583*bc36eafdSMike Gerdts         if (!Token2)
584*bc36eafdSMike Gerdts         {
585*bc36eafdSMike Gerdts             goto SyntaxError;
586*bc36eafdSMike Gerdts         }
587*bc36eafdSMike Gerdts     }
588*bc36eafdSMike Gerdts 
589*bc36eafdSMike Gerdts     /*
590*bc36eafdSMike Gerdts      * At this point, if we are ignoring the current code block,
591*bc36eafdSMike Gerdts      * do not process any more directives (i.e., ignore them also.)
592*bc36eafdSMike Gerdts      * For "if" style directives, open/push a new block anyway. We
593*bc36eafdSMike Gerdts      * must do this to keep track of #endif directives
594*bc36eafdSMike Gerdts      */
595*bc36eafdSMike Gerdts     if (Gbl_IgnoringThisCodeBlock)
596*bc36eafdSMike Gerdts     {
597*bc36eafdSMike Gerdts         switch (Directive)
598*bc36eafdSMike Gerdts         {
599*bc36eafdSMike Gerdts         case PR_DIRECTIVE_IF:
600*bc36eafdSMike Gerdts         case PR_DIRECTIVE_IFDEF:
601*bc36eafdSMike Gerdts         case PR_DIRECTIVE_IFNDEF:
602*bc36eafdSMike Gerdts 
603*bc36eafdSMike Gerdts             PrPushDirective (Directive, Token);
604*bc36eafdSMike Gerdts             PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
605*bc36eafdSMike Gerdts             break;
606*bc36eafdSMike Gerdts 
607*bc36eafdSMike Gerdts         default:
608*bc36eafdSMike Gerdts             break;
609*bc36eafdSMike Gerdts         }
610*bc36eafdSMike Gerdts 
611*bc36eafdSMike Gerdts         return;
612*bc36eafdSMike Gerdts     }
613*bc36eafdSMike Gerdts 
614*bc36eafdSMike Gerdts     /*
615*bc36eafdSMike Gerdts      * Execute the directive
616*bc36eafdSMike Gerdts      */
617*bc36eafdSMike Gerdts     PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name);
618*bc36eafdSMike Gerdts 
619*bc36eafdSMike Gerdts     switch (Directive)
620*bc36eafdSMike Gerdts     {
621*bc36eafdSMike Gerdts     case PR_DIRECTIVE_IF:
622*bc36eafdSMike Gerdts 
623*bc36eafdSMike Gerdts         TokenOffset = Token - Gbl_MainTokenBuffer;
624*bc36eafdSMike Gerdts 
625*bc36eafdSMike Gerdts         /* Need to expand #define macros in the expression string first */
626*bc36eafdSMike Gerdts 
627*bc36eafdSMike Gerdts         Status = PrResolveIntegerExpression (
628*bc36eafdSMike Gerdts             &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
629*bc36eafdSMike Gerdts         if (ACPI_FAILURE (Status))
630*bc36eafdSMike Gerdts         {
631*bc36eafdSMike Gerdts             return;
632*bc36eafdSMike Gerdts         }
633*bc36eafdSMike Gerdts 
634*bc36eafdSMike Gerdts         PrPushDirective (Directive, Token);
635*bc36eafdSMike Gerdts         if (!Value)
636*bc36eafdSMike Gerdts         {
637*bc36eafdSMike Gerdts             Gbl_IgnoringThisCodeBlock = TRUE;
638*bc36eafdSMike Gerdts         }
639*bc36eafdSMike Gerdts 
640*bc36eafdSMike Gerdts         DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
641*bc36eafdSMike Gerdts             "Resolved #if: %8.8X%8.8X %s\n",
642*bc36eafdSMike Gerdts             Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value),
643*bc36eafdSMike Gerdts             Gbl_IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>");
644*bc36eafdSMike Gerdts         break;
645*bc36eafdSMike Gerdts 
646*bc36eafdSMike Gerdts     case PR_DIRECTIVE_IFDEF:
647*bc36eafdSMike Gerdts 
648*bc36eafdSMike Gerdts         PrPushDirective (Directive, Token);
649*bc36eafdSMike Gerdts         if (!PrMatchDefine (Token))
650*bc36eafdSMike Gerdts         {
651*bc36eafdSMike Gerdts             Gbl_IgnoringThisCodeBlock = TRUE;
652*bc36eafdSMike Gerdts         }
653*bc36eafdSMike Gerdts 
654*bc36eafdSMike Gerdts         PrDbgPrint ("Evaluated", "ifdef");
655*bc36eafdSMike Gerdts         break;
656*bc36eafdSMike Gerdts 
657*bc36eafdSMike Gerdts     case PR_DIRECTIVE_IFNDEF:
658*bc36eafdSMike Gerdts 
659*bc36eafdSMike Gerdts         PrPushDirective (Directive, Token);
660*bc36eafdSMike Gerdts         if (PrMatchDefine (Token))
661*bc36eafdSMike Gerdts         {
662*bc36eafdSMike Gerdts             Gbl_IgnoringThisCodeBlock = TRUE;
663*bc36eafdSMike Gerdts         }
664*bc36eafdSMike Gerdts 
665*bc36eafdSMike Gerdts         PrDbgPrint ("Evaluated", "ifndef");
666*bc36eafdSMike Gerdts         break;
667*bc36eafdSMike Gerdts 
668*bc36eafdSMike Gerdts     case PR_DIRECTIVE_DEFINE:
669*bc36eafdSMike Gerdts         /*
670*bc36eafdSMike Gerdts          * By definition, if first char after the name is a paren,
671*bc36eafdSMike Gerdts          * this is a function macro.
672*bc36eafdSMike Gerdts          */
673*bc36eafdSMike Gerdts         TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token);
674*bc36eafdSMike Gerdts         if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(')
675*bc36eafdSMike Gerdts         {
676*bc36eafdSMike Gerdts #ifndef MACROS_SUPPORTED
677*bc36eafdSMike Gerdts             AcpiOsPrintf (
678*bc36eafdSMike Gerdts                 "%s ERROR - line %u: #define macros are not supported yet\n",
679*bc36eafdSMike Gerdts                 Gbl_CurrentLineBuffer, Gbl_LogicalLineNumber);
680*bc36eafdSMike Gerdts             exit(1);
681*bc36eafdSMike Gerdts #else
682*bc36eafdSMike Gerdts             PrAddMacro (Token, Next);
683*bc36eafdSMike Gerdts #endif
684*bc36eafdSMike Gerdts         }
685*bc36eafdSMike Gerdts         else
686*bc36eafdSMike Gerdts         {
687*bc36eafdSMike Gerdts             /* Use the remainder of the line for the #define */
688*bc36eafdSMike Gerdts 
689*bc36eafdSMike Gerdts             Token2 = *Next;
690*bc36eafdSMike Gerdts             if (Token2)
691*bc36eafdSMike Gerdts             {
692*bc36eafdSMike Gerdts                 while ((*Token2 == ' ') || (*Token2 == '\t'))
693*bc36eafdSMike Gerdts                 {
694*bc36eafdSMike Gerdts                     Token2++;
695*bc36eafdSMike Gerdts                 }
696*bc36eafdSMike Gerdts 
697*bc36eafdSMike Gerdts                 End = Token2;
698*bc36eafdSMike Gerdts                 while (*End != '\n')
699*bc36eafdSMike Gerdts                 {
700*bc36eafdSMike Gerdts                     End++;
701*bc36eafdSMike Gerdts                 }
702*bc36eafdSMike Gerdts 
703*bc36eafdSMike Gerdts                 *End = 0;
704*bc36eafdSMike Gerdts             }
705*bc36eafdSMike Gerdts             else
706*bc36eafdSMike Gerdts             {
707*bc36eafdSMike Gerdts                 Token2 = "";
708*bc36eafdSMike Gerdts             }
709*bc36eafdSMike Gerdts #if 0
710*bc36eafdSMike Gerdts             Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next);
711*bc36eafdSMike Gerdts             if (!Token2)
712*bc36eafdSMike Gerdts             {
713*bc36eafdSMike Gerdts                 Token2 = "";
714*bc36eafdSMike Gerdts             }
715*bc36eafdSMike Gerdts #endif
716*bc36eafdSMike Gerdts             DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
717*bc36eafdSMike Gerdts                 "New #define: %s->%s\n",
718*bc36eafdSMike Gerdts                 Gbl_LogicalLineNumber, Token, Token2);
719*bc36eafdSMike Gerdts 
720*bc36eafdSMike Gerdts             PrAddDefine (Token, Token2, FALSE);
721*bc36eafdSMike Gerdts         }
722*bc36eafdSMike Gerdts         break;
723*bc36eafdSMike Gerdts 
724*bc36eafdSMike Gerdts     case PR_DIRECTIVE_ERROR:
725*bc36eafdSMike Gerdts 
726*bc36eafdSMike Gerdts         /* Note: No macro expansion */
727*bc36eafdSMike Gerdts 
728*bc36eafdSMike Gerdts         PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE,
729*bc36eafdSMike Gerdts             THIS_TOKEN_OFFSET (Token));
730*bc36eafdSMike Gerdts 
731*bc36eafdSMike Gerdts         Gbl_SourceLine = 0;
732*bc36eafdSMike Gerdts         Gbl_NextError = Gbl_ErrorLog;
733*bc36eafdSMike Gerdts         CmCleanupAndExit ();
734*bc36eafdSMike Gerdts         exit(1);
735*bc36eafdSMike Gerdts 
736*bc36eafdSMike Gerdts     case PR_DIRECTIVE_INCLUDE:
737*bc36eafdSMike Gerdts 
738*bc36eafdSMike Gerdts         Token = PrGetNextToken (NULL, " \"<>", Next);
739*bc36eafdSMike Gerdts         if (!Token)
740*bc36eafdSMike Gerdts         {
741*bc36eafdSMike Gerdts             goto SyntaxError;
742*bc36eafdSMike Gerdts         }
743*bc36eafdSMike Gerdts 
744*bc36eafdSMike Gerdts         DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
745*bc36eafdSMike Gerdts             "Start #include file \"%s\"\n", Gbl_CurrentLineNumber,
746*bc36eafdSMike Gerdts             Token, Gbl_CurrentLineNumber);
747*bc36eafdSMike Gerdts 
748*bc36eafdSMike Gerdts         PrDoIncludeFile (Token);
749*bc36eafdSMike Gerdts         break;
750*bc36eafdSMike Gerdts 
751*bc36eafdSMike Gerdts     case PR_DIRECTIVE_INCLUDEBUFFER:
752*bc36eafdSMike Gerdts 
753*bc36eafdSMike Gerdts         Token = PrGetNextToken (NULL, " \"<>", Next);
754*bc36eafdSMike Gerdts         if (!Token)
755*bc36eafdSMike Gerdts         {
756*bc36eafdSMike Gerdts             goto SyntaxError;
757*bc36eafdSMike Gerdts         }
758*bc36eafdSMike Gerdts 
759*bc36eafdSMike Gerdts         Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
760*bc36eafdSMike Gerdts         if (!Token2)
761*bc36eafdSMike Gerdts         {
762*bc36eafdSMike Gerdts             goto SyntaxError;
763*bc36eafdSMike Gerdts         }
764*bc36eafdSMike Gerdts 
765*bc36eafdSMike Gerdts         DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
766*bc36eafdSMike Gerdts             "Start #includebuffer input from file \"%s\", buffer name %s\n",
767*bc36eafdSMike Gerdts             Gbl_CurrentLineNumber, Token, Token2);
768*bc36eafdSMike Gerdts 
769*bc36eafdSMike Gerdts         PrDoIncludeBuffer (Token, Token2);
770*bc36eafdSMike Gerdts         break;
771*bc36eafdSMike Gerdts 
772*bc36eafdSMike Gerdts     case PR_DIRECTIVE_LINE:
773*bc36eafdSMike Gerdts 
774*bc36eafdSMike Gerdts         TokenOffset = Token - Gbl_MainTokenBuffer;
775*bc36eafdSMike Gerdts 
776*bc36eafdSMike Gerdts         Status = PrResolveIntegerExpression (
777*bc36eafdSMike Gerdts             &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
778*bc36eafdSMike Gerdts         if (ACPI_FAILURE (Status))
779*bc36eafdSMike Gerdts         {
780*bc36eafdSMike Gerdts             return;
781*bc36eafdSMike Gerdts         }
782*bc36eafdSMike Gerdts 
783*bc36eafdSMike Gerdts         DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
784*bc36eafdSMike Gerdts             "User #line invocation %s\n", Gbl_CurrentLineNumber,
785*bc36eafdSMike Gerdts             Token);
786*bc36eafdSMike Gerdts 
787*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber = (UINT32) Value;
788*bc36eafdSMike Gerdts 
789*bc36eafdSMike Gerdts         /* Emit #line into the preprocessor file */
790*bc36eafdSMike Gerdts 
791*bc36eafdSMike Gerdts         FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
792*bc36eafdSMike Gerdts             Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename);
793*bc36eafdSMike Gerdts         break;
794*bc36eafdSMike Gerdts 
795*bc36eafdSMike Gerdts     case PR_DIRECTIVE_PRAGMA:
796*bc36eafdSMike Gerdts 
797*bc36eafdSMike Gerdts         if (!strcmp (Token, "disable"))
798*bc36eafdSMike Gerdts         {
799*bc36eafdSMike Gerdts             Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
800*bc36eafdSMike Gerdts             if (!Token)
801*bc36eafdSMike Gerdts             {
802*bc36eafdSMike Gerdts                 goto SyntaxError;
803*bc36eafdSMike Gerdts             }
804*bc36eafdSMike Gerdts 
805*bc36eafdSMike Gerdts             TokenOffset = Token - Gbl_MainTokenBuffer;
806*bc36eafdSMike Gerdts             AslDisableException (&Gbl_CurrentLineBuffer[TokenOffset]);
807*bc36eafdSMike Gerdts         }
808*bc36eafdSMike Gerdts         else if (!strcmp (Token, "message"))
809*bc36eafdSMike Gerdts         {
810*bc36eafdSMike Gerdts             Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
811*bc36eafdSMike Gerdts             if (!Token)
812*bc36eafdSMike Gerdts             {
813*bc36eafdSMike Gerdts                 goto SyntaxError;
814*bc36eafdSMike Gerdts             }
815*bc36eafdSMike Gerdts 
816*bc36eafdSMike Gerdts             TokenOffset = Token - Gbl_MainTokenBuffer;
817*bc36eafdSMike Gerdts             AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]);
818*bc36eafdSMike Gerdts         }
819*bc36eafdSMike Gerdts         else
820*bc36eafdSMike Gerdts         {
821*bc36eafdSMike Gerdts             PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA,
822*bc36eafdSMike Gerdts                 THIS_TOKEN_OFFSET (Token));
823*bc36eafdSMike Gerdts             return;
824*bc36eafdSMike Gerdts         }
825*bc36eafdSMike Gerdts 
826*bc36eafdSMike Gerdts         break;
827*bc36eafdSMike Gerdts 
828*bc36eafdSMike Gerdts     case PR_DIRECTIVE_UNDEF:
829*bc36eafdSMike Gerdts 
830*bc36eafdSMike Gerdts         DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
831*bc36eafdSMike Gerdts             "#undef: %s\n", Gbl_CurrentLineNumber, Token);
832*bc36eafdSMike Gerdts 
833*bc36eafdSMike Gerdts         PrRemoveDefine (Token);
834*bc36eafdSMike Gerdts         break;
835*bc36eafdSMike Gerdts 
836*bc36eafdSMike Gerdts     case PR_DIRECTIVE_WARNING:
837*bc36eafdSMike Gerdts 
838*bc36eafdSMike Gerdts         PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE,
839*bc36eafdSMike Gerdts             THIS_TOKEN_OFFSET (Token));
840*bc36eafdSMike Gerdts 
841*bc36eafdSMike Gerdts         Gbl_SourceLine = 0;
842*bc36eafdSMike Gerdts         Gbl_NextError = Gbl_ErrorLog;
843*bc36eafdSMike Gerdts         break;
844*bc36eafdSMike Gerdts 
845*bc36eafdSMike Gerdts     default:
846*bc36eafdSMike Gerdts 
847*bc36eafdSMike Gerdts         /* Should never get here */
848*bc36eafdSMike Gerdts         DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
849*bc36eafdSMike Gerdts             "Unrecognized directive: %u\n",
850*bc36eafdSMike Gerdts             Gbl_CurrentLineNumber, Directive);
851*bc36eafdSMike Gerdts         break;
852*bc36eafdSMike Gerdts     }
853*bc36eafdSMike Gerdts 
854*bc36eafdSMike Gerdts     return;
855*bc36eafdSMike Gerdts 
856*bc36eafdSMike Gerdts SyntaxError:
857*bc36eafdSMike Gerdts 
858*bc36eafdSMike Gerdts     PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX,
859*bc36eafdSMike Gerdts         THIS_TOKEN_OFFSET (DirectiveToken));
860*bc36eafdSMike Gerdts     return;
861*bc36eafdSMike Gerdts }
862*bc36eafdSMike Gerdts 
863*bc36eafdSMike Gerdts 
864*bc36eafdSMike Gerdts /*******************************************************************************
865*bc36eafdSMike Gerdts  *
866*bc36eafdSMike Gerdts  * FUNCTION:    PrGetNextLine, PrGetNextLineInit
867*bc36eafdSMike Gerdts  *
868*bc36eafdSMike Gerdts  * PARAMETERS:  Handle              - Open file handle for the source file
869*bc36eafdSMike Gerdts  *
870*bc36eafdSMike Gerdts  * RETURN:      Status of the GetLine operation:
871*bc36eafdSMike Gerdts  *              AE_OK               - Normal line, OK status
872*bc36eafdSMike Gerdts  *              ASL_IGNORE_LINE     - Line is blank or part of a multi-line
873*bc36eafdSMike Gerdts  *                                      comment
874*bc36eafdSMike Gerdts  *              ASL_EOF             - End-of-file reached
875*bc36eafdSMike Gerdts  *
876*bc36eafdSMike Gerdts  * DESCRIPTION: Get the next text line from the input file. Does not strip
877*bc36eafdSMike Gerdts  *              comments.
878*bc36eafdSMike Gerdts  *
879*bc36eafdSMike Gerdts  ******************************************************************************/
880*bc36eafdSMike Gerdts 
881*bc36eafdSMike Gerdts #define PR_NORMAL_TEXT          0
882*bc36eafdSMike Gerdts #define PR_MULTI_LINE_COMMENT   1
883*bc36eafdSMike Gerdts #define PR_SINGLE_LINE_COMMENT  2
884*bc36eafdSMike Gerdts #define PR_QUOTED_STRING        3
885*bc36eafdSMike Gerdts 
886*bc36eafdSMike Gerdts static UINT8                    AcpiGbl_LineScanState = PR_NORMAL_TEXT;
887*bc36eafdSMike Gerdts 
888*bc36eafdSMike Gerdts static void
889*bc36eafdSMike Gerdts PrGetNextLineInit (
890*bc36eafdSMike Gerdts     void)
891*bc36eafdSMike Gerdts {
892*bc36eafdSMike Gerdts     AcpiGbl_LineScanState = 0;
893*bc36eafdSMike Gerdts }
894*bc36eafdSMike Gerdts 
895*bc36eafdSMike Gerdts static UINT32
896*bc36eafdSMike Gerdts PrGetNextLine (
897*bc36eafdSMike Gerdts     FILE                    *Handle)
898*bc36eafdSMike Gerdts {
899*bc36eafdSMike Gerdts     UINT32                  i;
900*bc36eafdSMike Gerdts     int                     c = 0;
901*bc36eafdSMike Gerdts     int                     PreviousChar;
902*bc36eafdSMike Gerdts 
903*bc36eafdSMike Gerdts 
904*bc36eafdSMike Gerdts     /* Always clear the global line buffer */
905*bc36eafdSMike Gerdts 
906*bc36eafdSMike Gerdts     memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
907*bc36eafdSMike Gerdts     for (i = 0; ;)
908*bc36eafdSMike Gerdts     {
909*bc36eafdSMike Gerdts         /*
910*bc36eafdSMike Gerdts          * If line is too long, expand the line buffers. Also increases
911*bc36eafdSMike Gerdts          * Gbl_LineBufferSize.
912*bc36eafdSMike Gerdts          */
913*bc36eafdSMike Gerdts         if (i >= Gbl_LineBufferSize)
914*bc36eafdSMike Gerdts         {
915*bc36eafdSMike Gerdts             UtExpandLineBuffers ();
916*bc36eafdSMike Gerdts         }
917*bc36eafdSMike Gerdts 
918*bc36eafdSMike Gerdts         PreviousChar = c;
919*bc36eafdSMike Gerdts         c = getc (Handle);
920*bc36eafdSMike Gerdts         if (c == EOF)
921*bc36eafdSMike Gerdts         {
922*bc36eafdSMike Gerdts             /*
923*bc36eafdSMike Gerdts              * On EOF: If there is anything in the line buffer, terminate
924*bc36eafdSMike Gerdts              * it with a newline, and catch the EOF on the next call
925*bc36eafdSMike Gerdts              * to this function.
926*bc36eafdSMike Gerdts              */
927*bc36eafdSMike Gerdts             if (i > 0)
928*bc36eafdSMike Gerdts             {
929*bc36eafdSMike Gerdts                 Gbl_CurrentLineBuffer[i] = '\n';
930*bc36eafdSMike Gerdts                 return (AE_OK);
931*bc36eafdSMike Gerdts             }
932*bc36eafdSMike Gerdts 
933*bc36eafdSMike Gerdts             return (ASL_EOF);
934*bc36eafdSMike Gerdts         }
935*bc36eafdSMike Gerdts 
936*bc36eafdSMike Gerdts         /* Update state machine as necessary */
937*bc36eafdSMike Gerdts 
938*bc36eafdSMike Gerdts         switch (AcpiGbl_LineScanState)
939*bc36eafdSMike Gerdts         {
940*bc36eafdSMike Gerdts         case PR_NORMAL_TEXT:
941*bc36eafdSMike Gerdts 
942*bc36eafdSMike Gerdts             /* Check for multi-line comment start */
943*bc36eafdSMike Gerdts 
944*bc36eafdSMike Gerdts             if ((PreviousChar == '/') && (c == '*'))
945*bc36eafdSMike Gerdts             {
946*bc36eafdSMike Gerdts                 AcpiGbl_LineScanState = PR_MULTI_LINE_COMMENT;
947*bc36eafdSMike Gerdts             }
948*bc36eafdSMike Gerdts 
949*bc36eafdSMike Gerdts             /* Check for single-line comment start */
950*bc36eafdSMike Gerdts 
951*bc36eafdSMike Gerdts             else if ((PreviousChar == '/') && (c == '/'))
952*bc36eafdSMike Gerdts             {
953*bc36eafdSMike Gerdts                 AcpiGbl_LineScanState = PR_SINGLE_LINE_COMMENT;
954*bc36eafdSMike Gerdts             }
955*bc36eafdSMike Gerdts 
956*bc36eafdSMike Gerdts             /* Check for quoted string start */
957*bc36eafdSMike Gerdts 
958*bc36eafdSMike Gerdts             else if (PreviousChar == '"')
959*bc36eafdSMike Gerdts             {
960*bc36eafdSMike Gerdts                 AcpiGbl_LineScanState = PR_QUOTED_STRING;
961*bc36eafdSMike Gerdts             }
962*bc36eafdSMike Gerdts             break;
963*bc36eafdSMike Gerdts 
964*bc36eafdSMike Gerdts         case PR_QUOTED_STRING:
965*bc36eafdSMike Gerdts 
966*bc36eafdSMike Gerdts             if (PreviousChar == '"')
967*bc36eafdSMike Gerdts             {
968*bc36eafdSMike Gerdts                 AcpiGbl_LineScanState = PR_NORMAL_TEXT;
969*bc36eafdSMike Gerdts             }
970*bc36eafdSMike Gerdts             break;
971*bc36eafdSMike Gerdts 
972*bc36eafdSMike Gerdts         case PR_MULTI_LINE_COMMENT:
973*bc36eafdSMike Gerdts 
974*bc36eafdSMike Gerdts             /* Check for multi-line comment end */
975*bc36eafdSMike Gerdts 
976*bc36eafdSMike Gerdts             if ((PreviousChar == '*') && (c == '/'))
977*bc36eafdSMike Gerdts             {
978*bc36eafdSMike Gerdts                 AcpiGbl_LineScanState = PR_NORMAL_TEXT;
979*bc36eafdSMike Gerdts             }
980*bc36eafdSMike Gerdts             break;
981*bc36eafdSMike Gerdts 
982*bc36eafdSMike Gerdts         case PR_SINGLE_LINE_COMMENT: /* Just ignore text until EOL */
983*bc36eafdSMike Gerdts         default:
984*bc36eafdSMike Gerdts             break;
985*bc36eafdSMike Gerdts         }
986*bc36eafdSMike Gerdts 
987*bc36eafdSMike Gerdts         /* Always copy the character into line buffer */
988*bc36eafdSMike Gerdts 
989*bc36eafdSMike Gerdts         Gbl_CurrentLineBuffer[i] = (char) c;
990*bc36eafdSMike Gerdts         i++;
991*bc36eafdSMike Gerdts 
992*bc36eafdSMike Gerdts         /* Always exit on end-of-line */
993*bc36eafdSMike Gerdts 
994*bc36eafdSMike Gerdts         if (c == '\n')
995*bc36eafdSMike Gerdts         {
996*bc36eafdSMike Gerdts             /* Handle multi-line comments */
997*bc36eafdSMike Gerdts 
998*bc36eafdSMike Gerdts             if (AcpiGbl_LineScanState == PR_MULTI_LINE_COMMENT)
999*bc36eafdSMike Gerdts             {
1000*bc36eafdSMike Gerdts                 return (ASL_IGNORE_LINE);
1001*bc36eafdSMike Gerdts             }
1002*bc36eafdSMike Gerdts 
1003*bc36eafdSMike Gerdts             /* End of single-line comment */
1004*bc36eafdSMike Gerdts 
1005*bc36eafdSMike Gerdts             if (AcpiGbl_LineScanState == PR_SINGLE_LINE_COMMENT)
1006*bc36eafdSMike Gerdts             {
1007*bc36eafdSMike Gerdts                 AcpiGbl_LineScanState = PR_NORMAL_TEXT;
1008*bc36eafdSMike Gerdts                 return (AE_OK);
1009*bc36eafdSMike Gerdts             }
1010*bc36eafdSMike Gerdts 
1011*bc36eafdSMike Gerdts             /* Blank line */
1012*bc36eafdSMike Gerdts 
1013*bc36eafdSMike Gerdts             if (i == 1)
1014*bc36eafdSMike Gerdts             {
1015*bc36eafdSMike Gerdts                 return (ASL_IGNORE_LINE);
1016*bc36eafdSMike Gerdts             }
1017*bc36eafdSMike Gerdts 
1018*bc36eafdSMike Gerdts             return (AE_OK);
1019*bc36eafdSMike Gerdts         }
1020*bc36eafdSMike Gerdts     }
1021*bc36eafdSMike Gerdts }
1022*bc36eafdSMike Gerdts 
1023*bc36eafdSMike Gerdts 
1024*bc36eafdSMike Gerdts /*******************************************************************************
1025*bc36eafdSMike Gerdts  *
1026*bc36eafdSMike Gerdts  * FUNCTION:    PrMatchDirective
1027*bc36eafdSMike Gerdts  *
1028*bc36eafdSMike Gerdts  * PARAMETERS:  Directive           - Pointer to directive name token
1029*bc36eafdSMike Gerdts  *
1030*bc36eafdSMike Gerdts  * RETURN:      Index into command array, -1 if not found
1031*bc36eafdSMike Gerdts  *
1032*bc36eafdSMike Gerdts  * DESCRIPTION: Lookup the incoming directive in the known directives table.
1033*bc36eafdSMike Gerdts  *
1034*bc36eafdSMike Gerdts  ******************************************************************************/
1035*bc36eafdSMike Gerdts 
1036*bc36eafdSMike Gerdts static int
1037*bc36eafdSMike Gerdts PrMatchDirective (
1038*bc36eafdSMike Gerdts     char                    *Directive)
1039*bc36eafdSMike Gerdts {
1040*bc36eafdSMike Gerdts     int                     i;
1041*bc36eafdSMike Gerdts 
1042*bc36eafdSMike Gerdts 
1043*bc36eafdSMike Gerdts     if (!Directive || Directive[0] == 0)
1044*bc36eafdSMike Gerdts     {
1045*bc36eafdSMike Gerdts         return (ASL_DIRECTIVE_NOT_FOUND);
1046*bc36eafdSMike Gerdts     }
1047*bc36eafdSMike Gerdts 
1048*bc36eafdSMike Gerdts     for (i = 0; Gbl_DirectiveInfo[i].Name; i++)
1049*bc36eafdSMike Gerdts     {
1050*bc36eafdSMike Gerdts         if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive))
1051*bc36eafdSMike Gerdts         {
1052*bc36eafdSMike Gerdts             return (i);
1053*bc36eafdSMike Gerdts         }
1054*bc36eafdSMike Gerdts     }
1055*bc36eafdSMike Gerdts 
1056*bc36eafdSMike Gerdts     return (ASL_DIRECTIVE_NOT_FOUND);    /* Command not recognized */
1057*bc36eafdSMike Gerdts }
1058*bc36eafdSMike Gerdts 
1059*bc36eafdSMike Gerdts 
1060*bc36eafdSMike Gerdts /*******************************************************************************
1061*bc36eafdSMike Gerdts  *
1062*bc36eafdSMike Gerdts  * FUNCTION:    PrPushDirective
1063*bc36eafdSMike Gerdts  *
1064*bc36eafdSMike Gerdts  * PARAMETERS:  Directive           - Encoded directive ID
1065*bc36eafdSMike Gerdts  *              Argument            - String containing argument to the
1066*bc36eafdSMike Gerdts  *                                    directive
1067*bc36eafdSMike Gerdts  *
1068*bc36eafdSMike Gerdts  * RETURN:      None
1069*bc36eafdSMike Gerdts  *
1070*bc36eafdSMike Gerdts  * DESCRIPTION: Push an item onto the directive stack. Used for processing
1071*bc36eafdSMike Gerdts  *              nested #if/#else type conditional compilation directives.
1072*bc36eafdSMike Gerdts  *              Specifically: Used on detection of #if/#ifdef/#ifndef to open
1073*bc36eafdSMike Gerdts  *              a block.
1074*bc36eafdSMike Gerdts  *
1075*bc36eafdSMike Gerdts  ******************************************************************************/
1076*bc36eafdSMike Gerdts 
1077*bc36eafdSMike Gerdts static void
1078*bc36eafdSMike Gerdts PrPushDirective (
1079*bc36eafdSMike Gerdts     int                     Directive,
1080*bc36eafdSMike Gerdts     char                    *Argument)
1081*bc36eafdSMike Gerdts {
1082*bc36eafdSMike Gerdts     DIRECTIVE_INFO          *Info;
1083*bc36eafdSMike Gerdts 
1084*bc36eafdSMike Gerdts 
1085*bc36eafdSMike Gerdts     /* Allocate and populate a stack info item */
1086*bc36eafdSMike Gerdts 
1087*bc36eafdSMike Gerdts     Info = ACPI_ALLOCATE (sizeof (DIRECTIVE_INFO));
1088*bc36eafdSMike Gerdts 
1089*bc36eafdSMike Gerdts     Info->Next = Gbl_DirectiveStack;
1090*bc36eafdSMike Gerdts     Info->Directive = Directive;
1091*bc36eafdSMike Gerdts     Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock;
1092*bc36eafdSMike Gerdts     strncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH);
1093*bc36eafdSMike Gerdts 
1094*bc36eafdSMike Gerdts     DbgPrint (ASL_DEBUG_OUTPUT,
1095*bc36eafdSMike Gerdts         "Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n",
1096*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber, Gbl_IfDepth,
1097*bc36eafdSMike Gerdts         Gbl_IgnoringThisCodeBlock ? "I" : "E",
1098*bc36eafdSMike Gerdts         Gbl_IfDepth * 4, " ",
1099*bc36eafdSMike Gerdts         Gbl_DirectiveInfo[Directive].Name,
1100*bc36eafdSMike Gerdts         Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
1101*bc36eafdSMike Gerdts 
1102*bc36eafdSMike Gerdts     /* Push new item */
1103*bc36eafdSMike Gerdts 
1104*bc36eafdSMike Gerdts     Gbl_DirectiveStack = Info;
1105*bc36eafdSMike Gerdts     Gbl_IfDepth++;
1106*bc36eafdSMike Gerdts }
1107*bc36eafdSMike Gerdts 
1108*bc36eafdSMike Gerdts 
1109*bc36eafdSMike Gerdts /*******************************************************************************
1110*bc36eafdSMike Gerdts  *
1111*bc36eafdSMike Gerdts  * FUNCTION:    PrPopDirective
1112*bc36eafdSMike Gerdts  *
1113*bc36eafdSMike Gerdts  * PARAMETERS:  None
1114*bc36eafdSMike Gerdts  *
1115*bc36eafdSMike Gerdts  * RETURN:      Status. Error if the stack is empty.
1116*bc36eafdSMike Gerdts  *
1117*bc36eafdSMike Gerdts  * DESCRIPTION: Pop an item off the directive stack. Used for processing
1118*bc36eafdSMike Gerdts  *              nested #if/#else type conditional compilation directives.
1119*bc36eafdSMike Gerdts  *              Specifically: Used on detection of #elif and #endif to remove
1120*bc36eafdSMike Gerdts  *              the original #if/#ifdef/#ifndef from the stack and close
1121*bc36eafdSMike Gerdts  *              the block.
1122*bc36eafdSMike Gerdts  *
1123*bc36eafdSMike Gerdts  ******************************************************************************/
1124*bc36eafdSMike Gerdts 
1125*bc36eafdSMike Gerdts static ACPI_STATUS
1126*bc36eafdSMike Gerdts PrPopDirective (
1127*bc36eafdSMike Gerdts     void)
1128*bc36eafdSMike Gerdts {
1129*bc36eafdSMike Gerdts     DIRECTIVE_INFO          *Info;
1130*bc36eafdSMike Gerdts 
1131*bc36eafdSMike Gerdts 
1132*bc36eafdSMike Gerdts     /* Check for empty stack */
1133*bc36eafdSMike Gerdts 
1134*bc36eafdSMike Gerdts     Info = Gbl_DirectiveStack;
1135*bc36eafdSMike Gerdts     if (!Info)
1136*bc36eafdSMike Gerdts     {
1137*bc36eafdSMike Gerdts         return (AE_ERROR);
1138*bc36eafdSMike Gerdts     }
1139*bc36eafdSMike Gerdts 
1140*bc36eafdSMike Gerdts     /* Pop one item, keep globals up-to-date */
1141*bc36eafdSMike Gerdts 
1142*bc36eafdSMike Gerdts     Gbl_IfDepth--;
1143*bc36eafdSMike Gerdts     Gbl_IgnoringThisCodeBlock = Info->IgnoringThisCodeBlock;
1144*bc36eafdSMike Gerdts     Gbl_DirectiveStack = Info->Next;
1145*bc36eafdSMike Gerdts 
1146*bc36eafdSMike Gerdts     DbgPrint (ASL_DEBUG_OUTPUT,
1147*bc36eafdSMike Gerdts         "Pr(%.4u) - [%u %s] %*s Popped [#%s %s]: IgnoreFlag now = %s\n",
1148*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber, Gbl_IfDepth,
1149*bc36eafdSMike Gerdts         Gbl_IgnoringThisCodeBlock ? "I" : "E",
1150*bc36eafdSMike Gerdts         Gbl_IfDepth * 4, " ",
1151*bc36eafdSMike Gerdts         Gbl_DirectiveInfo[Info->Directive].Name,
1152*bc36eafdSMike Gerdts         Info->Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
1153*bc36eafdSMike Gerdts 
1154*bc36eafdSMike Gerdts     ACPI_FREE (Info);
1155*bc36eafdSMike Gerdts     return (AE_OK);
1156*bc36eafdSMike Gerdts }
1157*bc36eafdSMike Gerdts 
1158*bc36eafdSMike Gerdts 
1159*bc36eafdSMike Gerdts /*******************************************************************************
1160*bc36eafdSMike Gerdts  *
1161*bc36eafdSMike Gerdts  * FUNCTION:    PrDbgPrint
1162*bc36eafdSMike Gerdts  *
1163*bc36eafdSMike Gerdts  * PARAMETERS:  Action              - Action being performed
1164*bc36eafdSMike Gerdts  *              DirectiveName       - Directive being processed
1165*bc36eafdSMike Gerdts  *
1166*bc36eafdSMike Gerdts  * RETURN:      None
1167*bc36eafdSMike Gerdts  *
1168*bc36eafdSMike Gerdts  * DESCRIPTION: Special debug print for directive processing.
1169*bc36eafdSMike Gerdts  *
1170*bc36eafdSMike Gerdts  ******************************************************************************/
1171*bc36eafdSMike Gerdts 
1172*bc36eafdSMike Gerdts static void
1173*bc36eafdSMike Gerdts PrDbgPrint (
1174*bc36eafdSMike Gerdts     char                    *Action,
1175*bc36eafdSMike Gerdts     char                    *DirectiveName)
1176*bc36eafdSMike Gerdts {
1177*bc36eafdSMike Gerdts 
1178*bc36eafdSMike Gerdts     DbgPrint (ASL_DEBUG_OUTPUT, "Pr(%.4u) - [%u %s] "
1179*bc36eafdSMike Gerdts         "%*s %s #%s, IfDepth %u\n",
1180*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber, Gbl_IfDepth,
1181*bc36eafdSMike Gerdts         Gbl_IgnoringThisCodeBlock ? "I" : "E",
1182*bc36eafdSMike Gerdts         Gbl_IfDepth * 4, " ",
1183*bc36eafdSMike Gerdts         Action, DirectiveName, Gbl_IfDepth);
1184*bc36eafdSMike Gerdts }
1185*bc36eafdSMike Gerdts 
1186*bc36eafdSMike Gerdts 
1187*bc36eafdSMike Gerdts /*******************************************************************************
1188*bc36eafdSMike Gerdts  *
1189*bc36eafdSMike Gerdts  * FUNCTION:    PrDoIncludeFile
1190*bc36eafdSMike Gerdts  *
1191*bc36eafdSMike Gerdts  * PARAMETERS:  Pathname                - Name of the input file
1192*bc36eafdSMike Gerdts  *
1193*bc36eafdSMike Gerdts  * RETURN:      None.
1194*bc36eafdSMike Gerdts  *
1195*bc36eafdSMike Gerdts  * DESCRIPTION: Open an include file, from #include.
1196*bc36eafdSMike Gerdts  *
1197*bc36eafdSMike Gerdts  ******************************************************************************/
1198*bc36eafdSMike Gerdts 
1199*bc36eafdSMike Gerdts static void
1200*bc36eafdSMike Gerdts PrDoIncludeFile (
1201*bc36eafdSMike Gerdts     char                    *Pathname)
1202*bc36eafdSMike Gerdts {
1203*bc36eafdSMike Gerdts     char                    *FullPathname;
1204*bc36eafdSMike Gerdts 
1205*bc36eafdSMike Gerdts 
1206*bc36eafdSMike Gerdts     (void) PrOpenIncludeFile (Pathname, "r", &FullPathname);
1207*bc36eafdSMike Gerdts }
1208*bc36eafdSMike Gerdts 
1209*bc36eafdSMike Gerdts 
1210*bc36eafdSMike Gerdts /*******************************************************************************
1211*bc36eafdSMike Gerdts  *
1212*bc36eafdSMike Gerdts  * FUNCTION:    PrDoIncludeBuffer
1213*bc36eafdSMike Gerdts  *
1214*bc36eafdSMike Gerdts  * PARAMETERS:  Pathname                - Name of the input binary file
1215*bc36eafdSMike Gerdts  *              BufferName              - ACPI namepath of the buffer
1216*bc36eafdSMike Gerdts  *
1217*bc36eafdSMike Gerdts  * RETURN:      None.
1218*bc36eafdSMike Gerdts  *
1219*bc36eafdSMike Gerdts  * DESCRIPTION: Create an ACPI buffer object from a binary file. The contents
1220*bc36eafdSMike Gerdts  *              of the file are emitted into the buffer object as ascii
1221*bc36eafdSMike Gerdts  *              hex data. From #includebuffer.
1222*bc36eafdSMike Gerdts  *
1223*bc36eafdSMike Gerdts  ******************************************************************************/
1224*bc36eafdSMike Gerdts 
1225*bc36eafdSMike Gerdts static void
1226*bc36eafdSMike Gerdts PrDoIncludeBuffer (
1227*bc36eafdSMike Gerdts     char                    *Pathname,
1228*bc36eafdSMike Gerdts     char                    *BufferName)
1229*bc36eafdSMike Gerdts {
1230*bc36eafdSMike Gerdts     char                    *FullPathname;
1231*bc36eafdSMike Gerdts     FILE                    *BinaryBufferFile;
1232*bc36eafdSMike Gerdts     UINT32                  i = 0;
1233*bc36eafdSMike Gerdts     UINT8                   c;
1234*bc36eafdSMike Gerdts 
1235*bc36eafdSMike Gerdts 
1236*bc36eafdSMike Gerdts     BinaryBufferFile = PrOpenIncludeFile (Pathname, "rb", &FullPathname);
1237*bc36eafdSMike Gerdts     if (!BinaryBufferFile)
1238*bc36eafdSMike Gerdts     {
1239*bc36eafdSMike Gerdts         return;
1240*bc36eafdSMike Gerdts     }
1241*bc36eafdSMike Gerdts 
1242*bc36eafdSMike Gerdts     /* Emit "Name (XXXX, Buffer() {" header */
1243*bc36eafdSMike Gerdts 
1244*bc36eafdSMike Gerdts     FlPrintFile (ASL_FILE_PREPROCESSOR, "Name (%s, Buffer()\n{", BufferName);
1245*bc36eafdSMike Gerdts 
1246*bc36eafdSMike Gerdts     /* Dump the entire file in ascii hex format */
1247*bc36eafdSMike Gerdts 
1248*bc36eafdSMike Gerdts     while (fread (&c, 1, 1, BinaryBufferFile))
1249*bc36eafdSMike Gerdts     {
1250*bc36eafdSMike Gerdts         if (!(i % 8))
1251*bc36eafdSMike Gerdts         {
1252*bc36eafdSMike Gerdts             FlPrintFile (ASL_FILE_PREPROCESSOR, "\n   ", c);
1253*bc36eafdSMike Gerdts         }
1254*bc36eafdSMike Gerdts 
1255*bc36eafdSMike Gerdts         FlPrintFile (ASL_FILE_PREPROCESSOR, " 0x%2.2X,", c);
1256*bc36eafdSMike Gerdts         i++;
1257*bc36eafdSMike Gerdts     }
1258*bc36eafdSMike Gerdts 
1259*bc36eafdSMike Gerdts     DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
1260*bc36eafdSMike Gerdts         "#includebuffer: read %u bytes from %s\n",
1261*bc36eafdSMike Gerdts         Gbl_CurrentLineNumber, i, FullPathname);
1262*bc36eafdSMike Gerdts 
1263*bc36eafdSMike Gerdts     /* Close the Name() operator */
1264*bc36eafdSMike Gerdts 
1265*bc36eafdSMike Gerdts     FlPrintFile (ASL_FILE_PREPROCESSOR, "\n})\n", BufferName);
1266*bc36eafdSMike Gerdts     fclose (BinaryBufferFile);
1267*bc36eafdSMike Gerdts }
1268