1233237Sjkim/******************************************************************************
2233237Sjkim *
3233237Sjkim * Module Name: prscan - Preprocessor start-up and file scan module
4233237Sjkim *
5233237Sjkim *****************************************************************************/
6233237Sjkim
7233237Sjkim/*
8281075Sdim * Copyright (C) 2000 - 2015, Intel Corp.
9233237Sjkim * All rights reserved.
10233237Sjkim *
11233237Sjkim * Redistribution and use in source and binary forms, with or without
12233237Sjkim * modification, are permitted provided that the following conditions
13233237Sjkim * are met:
14233237Sjkim * 1. Redistributions of source code must retain the above copyright
15233237Sjkim *    notice, this list of conditions, and the following disclaimer,
16233237Sjkim *    without modification.
17233237Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18233237Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19233237Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20233237Sjkim *    including a substantially similar Disclaimer requirement for further
21233237Sjkim *    binary redistribution.
22233237Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23233237Sjkim *    of any contributors may be used to endorse or promote products derived
24233237Sjkim *    from this software without specific prior written permission.
25233237Sjkim *
26233237Sjkim * Alternatively, this software may be distributed under the terms of the
27233237Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28233237Sjkim * Software Foundation.
29233237Sjkim *
30233237Sjkim * NO WARRANTY
31233237Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32233237Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33233237Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34233237Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35233237Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36233237Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37233237Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38233237Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39233237Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40233237Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41233237Sjkim * POSSIBILITY OF SUCH DAMAGES.
42233237Sjkim */
43233237Sjkim
44233237Sjkim#define _DECLARE_PR_GLOBALS
45233237Sjkim
46233250Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47233250Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
48233237Sjkim
49233237Sjkim/*
50233237Sjkim * TBDs:
51233237Sjkim *
52233237Sjkim * No nested macros, maybe never
53233237Sjkim * Implement ASL "Include" as well as "#include" here?
54233237Sjkim */
55233237Sjkim#define _COMPONENT          ASL_PREPROCESSOR
56233237Sjkim        ACPI_MODULE_NAME    ("prscan")
57233237Sjkim
58233237Sjkim
59233237Sjkim/* Local prototypes */
60233237Sjkim
61233237Sjkimstatic void
62233237SjkimPrPreprocessInputFile (
63233237Sjkim    void);
64233237Sjkim
65233237Sjkimstatic void
66233237SjkimPrDoDirective (
67233237Sjkim    char                    *DirectiveToken,
68252279Sjkim    char                    **Next);
69233237Sjkim
70233237Sjkimstatic int
71233237SjkimPrMatchDirective (
72233237Sjkim    char                    *Directive);
73233237Sjkim
74252279Sjkimstatic void
75252279SjkimPrPushDirective (
76252279Sjkim    int                     Directive,
77252279Sjkim    char                    *Argument);
78252279Sjkim
79252279Sjkimstatic ACPI_STATUS
80252279SjkimPrPopDirective (
81252279Sjkim    void);
82252279Sjkim
83252279Sjkimstatic void
84252279SjkimPrDbgPrint (
85252279Sjkim    char                    *Action,
86252279Sjkim    char                    *DirectiveName);
87252279Sjkim
88284460Sjkimstatic void
89284460SjkimPrDoIncludeBuffer (
90284460Sjkim    char                    *Pathname,
91284460Sjkim    char                    *BufferName);
92252279Sjkim
93284460Sjkimstatic void
94284460SjkimPrDoIncludeFile (
95284460Sjkim    char                    *Pathname);
96284460Sjkim
97284460Sjkim
98233237Sjkim/*
99233237Sjkim * Supported preprocessor directives
100284460Sjkim * Each entry is of the form "Name, ArgumentCount"
101233237Sjkim */
102233237Sjkimstatic const PR_DIRECTIVE_INFO      Gbl_DirectiveInfo[] =
103233237Sjkim{
104284460Sjkim    {"define",          1},
105284460Sjkim    {"elif",            0}, /* Converted to #else..#if internally */
106284460Sjkim    {"else",            0},
107284460Sjkim    {"endif",           0},
108284460Sjkim    {"error",           1},
109284460Sjkim    {"if",              1},
110284460Sjkim    {"ifdef",           1},
111284460Sjkim    {"ifndef",          1},
112284460Sjkim    {"include",         0}, /* Argument is not standard format, so just use 0 here */
113284460Sjkim    {"includebuffer",   0}, /* Argument is not standard format, so just use 0 here */
114284460Sjkim    {"line",            1},
115284460Sjkim    {"loadbuffer",      0},
116284460Sjkim    {"pragma",          1},
117284460Sjkim    {"undef",           1},
118284460Sjkim    {"warning",         1},
119284460Sjkim    {NULL,              0}
120233237Sjkim};
121233237Sjkim
122284460Sjkim/* This table must match ordering of above table exactly */
123284460Sjkim
124233237Sjkimenum Gbl_DirectiveIndexes
125233237Sjkim{
126233237Sjkim    PR_DIRECTIVE_DEFINE = 0,
127233237Sjkim    PR_DIRECTIVE_ELIF,
128233237Sjkim    PR_DIRECTIVE_ELSE,
129233237Sjkim    PR_DIRECTIVE_ENDIF,
130233237Sjkim    PR_DIRECTIVE_ERROR,
131233237Sjkim    PR_DIRECTIVE_IF,
132233237Sjkim    PR_DIRECTIVE_IFDEF,
133233237Sjkim    PR_DIRECTIVE_IFNDEF,
134233237Sjkim    PR_DIRECTIVE_INCLUDE,
135284460Sjkim    PR_DIRECTIVE_INCLUDEBUFFER,
136233237Sjkim    PR_DIRECTIVE_LINE,
137233237Sjkim    PR_DIRECTIVE_PRAGMA,
138233237Sjkim    PR_DIRECTIVE_UNDEF,
139233237Sjkim    PR_DIRECTIVE_WARNING,
140233237Sjkim};
141233237Sjkim
142233237Sjkim#define ASL_DIRECTIVE_NOT_FOUND     -1
143233237Sjkim
144233237Sjkim
145233237Sjkim/*******************************************************************************
146233237Sjkim *
147233237Sjkim * FUNCTION:    PrInitializePreprocessor
148233237Sjkim *
149233237Sjkim * PARAMETERS:  None
150233237Sjkim *
151233237Sjkim * RETURN:      None
152233237Sjkim *
153233237Sjkim * DESCRIPTION: Startup initialization for the Preprocessor.
154233237Sjkim *
155233237Sjkim ******************************************************************************/
156233237Sjkim
157233237Sjkimvoid
158233237SjkimPrInitializePreprocessor (
159233237Sjkim    void)
160233237Sjkim{
161233237Sjkim    /* Init globals and the list of #defines */
162233237Sjkim
163233237Sjkim    PrInitializeGlobals ();
164233237Sjkim    Gbl_DefineList = NULL;
165233237Sjkim}
166233237Sjkim
167233237Sjkim
168233237Sjkim/*******************************************************************************
169233237Sjkim *
170233237Sjkim * FUNCTION:    PrInitializeGlobals
171233237Sjkim *
172233237Sjkim * PARAMETERS:  None
173233237Sjkim *
174233237Sjkim * RETURN:      None
175233237Sjkim *
176233237Sjkim * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup
177233237Sjkim *              initialization and re-initialization between compiles during
178233237Sjkim *              a multiple source file compile.
179233237Sjkim *
180233237Sjkim ******************************************************************************/
181233237Sjkim
182233237Sjkimvoid
183233237SjkimPrInitializeGlobals (
184233237Sjkim    void)
185233237Sjkim{
186233237Sjkim    /* Init globals */
187233237Sjkim
188233237Sjkim    Gbl_InputFileList = NULL;
189233237Sjkim    Gbl_CurrentLineNumber = 0;
190233237Sjkim    Gbl_PreprocessorLineNumber = 1;
191233237Sjkim    Gbl_PreprocessorError = FALSE;
192252279Sjkim
193252279Sjkim    /* These are used to track #if/#else blocks (possibly nested) */
194252279Sjkim
195252279Sjkim    Gbl_IfDepth = 0;
196252279Sjkim    Gbl_IgnoringThisCodeBlock = FALSE;
197252279Sjkim    Gbl_DirectiveStack = NULL;
198233237Sjkim}
199233237Sjkim
200233237Sjkim
201233237Sjkim/*******************************************************************************
202233237Sjkim *
203233237Sjkim * FUNCTION:    PrTerminatePreprocessor
204233237Sjkim *
205233237Sjkim * PARAMETERS:  None
206233237Sjkim *
207233237Sjkim * RETURN:      None
208233237Sjkim *
209233237Sjkim * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any
210233237Sjkim *              defines that were specified on the command line, in order to
211233237Sjkim *              support multiple compiles with a single compiler invocation.
212233237Sjkim *
213233237Sjkim ******************************************************************************/
214233237Sjkim
215233237Sjkimvoid
216233237SjkimPrTerminatePreprocessor (
217233237Sjkim    void)
218233237Sjkim{
219233237Sjkim    PR_DEFINE_INFO          *DefineInfo;
220233237Sjkim
221233237Sjkim
222233237Sjkim    /*
223233237Sjkim     * The persistent defines (created on the command line) are always at the
224233237Sjkim     * end of the list. We save them.
225233237Sjkim     */
226233237Sjkim    while ((Gbl_DefineList) && (!Gbl_DefineList->Persist))
227233237Sjkim    {
228233237Sjkim        DefineInfo = Gbl_DefineList;
229233237Sjkim        Gbl_DefineList = DefineInfo->Next;
230233237Sjkim
231233237Sjkim        ACPI_FREE (DefineInfo->Replacement);
232233237Sjkim        ACPI_FREE (DefineInfo->Identifier);
233233237Sjkim        ACPI_FREE (DefineInfo);
234233237Sjkim    }
235233237Sjkim}
236233237Sjkim
237233237Sjkim
238233237Sjkim/*******************************************************************************
239233237Sjkim *
240233237Sjkim * FUNCTION:    PrDoPreprocess
241233237Sjkim *
242233237Sjkim * PARAMETERS:  None
243233237Sjkim *
244252279Sjkim * RETURN:      None
245233237Sjkim *
246233237Sjkim * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must
247233237Sjkim *              be already open. Handles multiple input files via the
248233237Sjkim *              #include directive.
249233237Sjkim *
250233237Sjkim ******************************************************************************/
251233237Sjkim
252252279Sjkimvoid
253233237SjkimPrDoPreprocess (
254233237Sjkim    void)
255233237Sjkim{
256233237Sjkim    BOOLEAN                 MoreInputFiles;
257233237Sjkim
258233237Sjkim
259233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n");
260233237Sjkim
261233237Sjkim
262233237Sjkim    FlSeekFile (ASL_FILE_INPUT, 0);
263233237Sjkim    PrDumpPredefinedNames ();
264233237Sjkim
265233237Sjkim    /* Main preprocessor loop, handles include files */
266233237Sjkim
267233237Sjkim    do
268233237Sjkim    {
269233237Sjkim        PrPreprocessInputFile ();
270233237Sjkim        MoreInputFiles = PrPopInputFileStack ();
271233237Sjkim
272233237Sjkim    } while (MoreInputFiles);
273233237Sjkim
274252279Sjkim    /* Point compiler input to the new preprocessor output file (.i) */
275233237Sjkim
276233237Sjkim    FlCloseFile (ASL_FILE_INPUT);
277233237Sjkim    Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle;
278233237Sjkim    AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
279233237Sjkim
280233237Sjkim    /* Reset globals to allow compiler to run */
281233237Sjkim
282233237Sjkim    FlSeekFile (ASL_FILE_INPUT, 0);
283233237Sjkim    Gbl_CurrentLineNumber = 1;
284233237Sjkim
285233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n");
286233237Sjkim}
287233237Sjkim
288233237Sjkim
289233237Sjkim/*******************************************************************************
290233237Sjkim *
291233237Sjkim * FUNCTION:    PrPreprocessInputFile
292233237Sjkim *
293233237Sjkim * PARAMETERS:  None
294233237Sjkim *
295233237Sjkim * RETURN:      None
296233237Sjkim *
297233237Sjkim * DESCRIPTION: Preprocess one entire file, line-by-line.
298233237Sjkim *
299233237Sjkim * Input:  Raw user ASL from ASL_FILE_INPUT
300233237Sjkim * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR
301233237Sjkim *
302233237Sjkim ******************************************************************************/
303233237Sjkim
304233237Sjkimstatic void
305233237SjkimPrPreprocessInputFile (
306233237Sjkim    void)
307233237Sjkim{
308233237Sjkim    UINT32                  Offset;
309233237Sjkim    char                    *Token;
310233237Sjkim    char                    *ReplaceString;
311233237Sjkim    PR_DEFINE_INFO          *DefineInfo;
312233237Sjkim    ACPI_SIZE               TokenOffset;
313233237Sjkim    char                    *Next;
314233237Sjkim    int                     OffsetAdjust;
315233237Sjkim
316233237Sjkim
317233237Sjkim    /* Scan line-by-line. Comments and blank lines are skipped by this function */
318233237Sjkim
319233237Sjkim    while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF)
320233237Sjkim    {
321233237Sjkim        /* Need a copy of the input line for strok() */
322233237Sjkim
323233237Sjkim        strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer);
324233237Sjkim        Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next);
325233237Sjkim        OffsetAdjust = 0;
326233237Sjkim
327233237Sjkim        /* All preprocessor directives must begin with '#' */
328233237Sjkim
329233237Sjkim        if (Token && (*Token == '#'))
330233237Sjkim        {
331233237Sjkim            if (strlen (Token) == 1)
332233237Sjkim            {
333233237Sjkim                Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
334233237Sjkim            }
335233237Sjkim            else
336233237Sjkim            {
337233237Sjkim                Token++;    /* Skip leading # */
338233237Sjkim            }
339233237Sjkim
340233237Sjkim            /* Execute the directive, do not write line to output file */
341233237Sjkim
342252279Sjkim            PrDoDirective (Token, &Next);
343233237Sjkim            continue;
344233237Sjkim        }
345233237Sjkim
346233237Sjkim        /*
347233237Sjkim         * If we are currently within the part of an IF/ELSE block that is
348233237Sjkim         * FALSE, ignore the line and do not write it to the output file.
349233237Sjkim         * This continues until an #else or #endif is encountered.
350233237Sjkim         */
351252279Sjkim        if (Gbl_IgnoringThisCodeBlock)
352233237Sjkim        {
353233237Sjkim            continue;
354233237Sjkim        }
355233237Sjkim
356233237Sjkim        /* Match and replace all #defined names within this source line */
357233237Sjkim
358233237Sjkim        while (Token)
359233237Sjkim        {
360233237Sjkim            DefineInfo = PrMatchDefine (Token);
361233237Sjkim            if (DefineInfo)
362233237Sjkim            {
363233237Sjkim                if (DefineInfo->Body)
364233237Sjkim                {
365233237Sjkim                    /* This is a macro */
366233237Sjkim
367233237Sjkim                    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
368233237Sjkim                        "Matched Macro: %s->%s\n",
369233237Sjkim                        Gbl_CurrentLineNumber, DefineInfo->Identifier,
370233237Sjkim                        DefineInfo->Replacement);
371233237Sjkim
372233237Sjkim                    PrDoMacroInvocation (Gbl_MainTokenBuffer, Token,
373233237Sjkim                        DefineInfo, &Next);
374233237Sjkim                }
375233237Sjkim                else
376233237Sjkim                {
377233237Sjkim                    ReplaceString = DefineInfo->Replacement;
378233237Sjkim
379233237Sjkim                    /* Replace the name in the original line buffer */
380233237Sjkim
381233237Sjkim                    TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust;
382233237Sjkim                    PrReplaceData (
383233237Sjkim                        &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token),
384233237Sjkim                        ReplaceString, strlen (ReplaceString));
385233237Sjkim
386233237Sjkim                    /* Adjust for length difference between old and new name length */
387233237Sjkim
388233237Sjkim                    OffsetAdjust += strlen (ReplaceString) - strlen (Token);
389233237Sjkim
390233237Sjkim                    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
391233237Sjkim                        "Matched #define: %s->%s\n",
392233237Sjkim                        Gbl_CurrentLineNumber, Token,
393233237Sjkim                        *ReplaceString ? ReplaceString : "(NULL STRING)");
394233237Sjkim                }
395233237Sjkim            }
396233237Sjkim
397233237Sjkim            Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
398233237Sjkim        }
399233237Sjkim
400234623Sjkim        /*
401234623Sjkim         * Emit a #line directive if necessary, to keep the line numbers in
402234623Sjkim         * the (.i) file synchronized with the original source code file, so
403234623Sjkim         * that the correct line number appears in any error messages
404234623Sjkim         * generated by the actual compiler.
405234623Sjkim         */
406234623Sjkim        if (Gbl_CurrentLineNumber > (Gbl_PreviousLineNumber + 1))
407234623Sjkim        {
408234623Sjkim            FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u\n",
409234623Sjkim                Gbl_CurrentLineNumber);
410234623Sjkim        }
411234623Sjkim
412234623Sjkim        Gbl_PreviousLineNumber = Gbl_CurrentLineNumber;
413234623Sjkim        Gbl_PreprocessorLineNumber++;
414234623Sjkim
415234623Sjkim        /*
416234623Sjkim         * Now we can write the possibly modified source line to the
417234623Sjkim         * preprocessor (.i) file
418234623Sjkim         */
419233237Sjkim        FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer,
420233237Sjkim            strlen (Gbl_CurrentLineBuffer));
421233237Sjkim    }
422233237Sjkim}
423233237Sjkim
424233237Sjkim
425233237Sjkim/*******************************************************************************
426233237Sjkim *
427233237Sjkim * FUNCTION:    PrDoDirective
428233237Sjkim *
429233237Sjkim * PARAMETERS:  Directive               - Pointer to directive name token
430233237Sjkim *              Next                    - "Next" buffer from GetNextToken
431233237Sjkim *
432252279Sjkim * RETURN:      None.
433233237Sjkim *
434233237Sjkim * DESCRIPTION: Main processing for all preprocessor directives
435233237Sjkim *
436233237Sjkim ******************************************************************************/
437233237Sjkim
438233237Sjkimstatic void
439233237SjkimPrDoDirective (
440233237Sjkim    char                    *DirectiveToken,
441252279Sjkim    char                    **Next)
442233237Sjkim{
443233237Sjkim    char                    *Token = Gbl_MainTokenBuffer;
444284460Sjkim    char                    *Token2 = NULL;
445233237Sjkim    char                    *End;
446233237Sjkim    UINT64                  Value;
447233237Sjkim    ACPI_SIZE               TokenOffset;
448233237Sjkim    int                     Directive;
449233237Sjkim    ACPI_STATUS             Status;
450233237Sjkim
451233237Sjkim
452233237Sjkim    if (!DirectiveToken)
453233237Sjkim    {
454233237Sjkim        goto SyntaxError;
455233237Sjkim    }
456233237Sjkim
457233237Sjkim    Directive = PrMatchDirective (DirectiveToken);
458233237Sjkim    if (Directive == ASL_DIRECTIVE_NOT_FOUND)
459233237Sjkim    {
460233237Sjkim        PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE,
461233237Sjkim            THIS_TOKEN_OFFSET (DirectiveToken));
462233237Sjkim
463284460Sjkim        DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
464233237Sjkim            "#%s: Unknown directive\n",
465233237Sjkim            Gbl_CurrentLineNumber, DirectiveToken);
466233237Sjkim        return;
467233237Sjkim    }
468233237Sjkim
469252279Sjkim    /*
470252279Sjkim     * If we are currently ignoring this block and we encounter a #else or
471252279Sjkim     * #elif, we must ignore their blocks also if the parent block is also
472252279Sjkim     * being ignored.
473252279Sjkim     */
474252279Sjkim    if (Gbl_IgnoringThisCodeBlock)
475252279Sjkim    {
476252279Sjkim        switch (Directive)
477252279Sjkim        {
478252279Sjkim        case PR_DIRECTIVE_ELSE:
479252279Sjkim        case PR_DIRECTIVE_ELIF:
480233237Sjkim
481252279Sjkim            if (Gbl_DirectiveStack && Gbl_DirectiveStack->IgnoringThisCodeBlock)
482252279Sjkim            {
483252279Sjkim                PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
484252279Sjkim                return;
485252279Sjkim            }
486252279Sjkim            break;
487252279Sjkim
488252279Sjkim        default:
489252279Sjkim            break;
490252279Sjkim        }
491233237Sjkim    }
492233237Sjkim
493233237Sjkim    /*
494233237Sjkim     * Need to always check for #else, #elif, #endif regardless of
495233237Sjkim     * whether we are ignoring the current code block, since these
496233237Sjkim     * are conditional code block terminators.
497233237Sjkim     */
498233237Sjkim    switch (Directive)
499233237Sjkim    {
500252279Sjkim    case PR_DIRECTIVE_ELSE:
501252279Sjkim
502252279Sjkim        Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
503252279Sjkim        PrDbgPrint ("Executing", "else block");
504252279Sjkim        return;
505252279Sjkim
506233237Sjkim    case PR_DIRECTIVE_ELIF:
507250838Sjkim
508252279Sjkim        Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock);
509252279Sjkim        Directive = PR_DIRECTIVE_IF;
510252279Sjkim
511252279Sjkim        if (Gbl_IgnoringThisCodeBlock == TRUE)
512233237Sjkim        {
513233237Sjkim            /* Not executing the ELSE part -- all done here */
514252279Sjkim            PrDbgPrint ("Ignoring", "elif block");
515233237Sjkim            return;
516233237Sjkim        }
517233237Sjkim
518252279Sjkim        /*
519252279Sjkim         * After this, we will execute the IF part further below.
520252279Sjkim         * First, however, pop off the original #if directive.
521252279Sjkim         */
522252279Sjkim        if (ACPI_FAILURE (PrPopDirective ()))
523252279Sjkim        {
524252279Sjkim            PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
525252279Sjkim                THIS_TOKEN_OFFSET (DirectiveToken));
526252279Sjkim        }
527233237Sjkim
528252279Sjkim        PrDbgPrint ("Executing", "elif block");
529233237Sjkim        break;
530233237Sjkim
531252279Sjkim    case PR_DIRECTIVE_ENDIF:
532250838Sjkim
533252279Sjkim        PrDbgPrint ("Executing", "endif");
534233237Sjkim
535252279Sjkim        /* Pop the owning #if/#ifdef/#ifndef */
536250838Sjkim
537252279Sjkim        if (ACPI_FAILURE (PrPopDirective ()))
538233237Sjkim        {
539233237Sjkim            PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH,
540233237Sjkim                THIS_TOKEN_OFFSET (DirectiveToken));
541233237Sjkim        }
542233237Sjkim        return;
543233237Sjkim
544233237Sjkim    default:
545233237Sjkim        break;
546233237Sjkim    }
547233237Sjkim
548252279Sjkim    /* Most directives have at least one argument */
549252279Sjkim
550284460Sjkim    if (Gbl_DirectiveInfo[Directive].ArgCount >= 1)
551252279Sjkim    {
552252279Sjkim        Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
553252279Sjkim        if (!Token)
554252279Sjkim        {
555252279Sjkim            goto SyntaxError;
556252279Sjkim        }
557252279Sjkim    }
558252279Sjkim
559284460Sjkim    if (Gbl_DirectiveInfo[Directive].ArgCount >= 2)
560284460Sjkim    {
561284460Sjkim        Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
562284460Sjkim        if (!Token2)
563284460Sjkim        {
564284460Sjkim            goto SyntaxError;
565284460Sjkim        }
566284460Sjkim    }
567284460Sjkim
568233237Sjkim    /*
569233237Sjkim     * At this point, if we are ignoring the current code block,
570233237Sjkim     * do not process any more directives (i.e., ignore them also.)
571252279Sjkim     * For "if" style directives, open/push a new block anyway. We
572252279Sjkim     * must do this to keep track of #endif directives
573233237Sjkim     */
574252279Sjkim    if (Gbl_IgnoringThisCodeBlock)
575233237Sjkim    {
576252279Sjkim        switch (Directive)
577252279Sjkim        {
578252279Sjkim        case PR_DIRECTIVE_IF:
579252279Sjkim        case PR_DIRECTIVE_IFDEF:
580252279Sjkim        case PR_DIRECTIVE_IFNDEF:
581252279Sjkim
582252279Sjkim            PrPushDirective (Directive, Token);
583252279Sjkim            PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name);
584252279Sjkim            break;
585252279Sjkim
586252279Sjkim        default:
587252279Sjkim            break;
588252279Sjkim        }
589252279Sjkim
590233237Sjkim        return;
591233237Sjkim    }
592233237Sjkim
593252279Sjkim    /*
594252279Sjkim     * Execute the directive
595252279Sjkim     */
596252279Sjkim    PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name);
597233237Sjkim
598252279Sjkim    switch (Directive)
599252279Sjkim    {
600252279Sjkim    case PR_DIRECTIVE_IF:
601233237Sjkim
602252279Sjkim        TokenOffset = Token - Gbl_MainTokenBuffer;
603252279Sjkim
604252279Sjkim        /* Need to expand #define macros in the expression string first */
605252279Sjkim
606252279Sjkim        Status = PrResolveIntegerExpression (
607252279Sjkim            &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
608252279Sjkim        if (ACPI_FAILURE (Status))
609233237Sjkim        {
610252279Sjkim            return;
611233237Sjkim        }
612233237Sjkim
613252279Sjkim        PrPushDirective (Directive, Token);
614252279Sjkim        if (!Value)
615252279Sjkim        {
616252279Sjkim            Gbl_IgnoringThisCodeBlock = TRUE;
617252279Sjkim        }
618252279Sjkim
619284460Sjkim        DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
620252279Sjkim            "Resolved #if: %8.8X%8.8X %s\n",
621252279Sjkim            Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value),
622252279Sjkim            Gbl_IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>");
623252279Sjkim        break;
624252279Sjkim
625252279Sjkim    case PR_DIRECTIVE_IFDEF:
626252279Sjkim
627252279Sjkim        PrPushDirective (Directive, Token);
628252279Sjkim        if (!PrMatchDefine (Token))
629252279Sjkim        {
630252279Sjkim            Gbl_IgnoringThisCodeBlock = TRUE;
631252279Sjkim        }
632252279Sjkim
633252279Sjkim        PrDbgPrint ("Evaluated", "ifdef");
634252279Sjkim        break;
635252279Sjkim
636252279Sjkim    case PR_DIRECTIVE_IFNDEF:
637252279Sjkim
638252279Sjkim        PrPushDirective (Directive, Token);
639252279Sjkim        if (PrMatchDefine (Token))
640252279Sjkim        {
641252279Sjkim            Gbl_IgnoringThisCodeBlock = TRUE;
642252279Sjkim        }
643252279Sjkim
644252279Sjkim        PrDbgPrint ("Evaluated", "ifndef");
645252279Sjkim        break;
646252279Sjkim
647233237Sjkim    case PR_DIRECTIVE_DEFINE:
648233237Sjkim        /*
649233237Sjkim         * By definition, if first char after the name is a paren,
650233237Sjkim         * this is a function macro.
651233237Sjkim         */
652233237Sjkim        TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token);
653233237Sjkim        if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(')
654233237Sjkim        {
655233237Sjkim#ifndef MACROS_SUPPORTED
656234623Sjkim            AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n",
657234623Sjkim                Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber);
658234623Sjkim            exit(1);
659233237Sjkim#else
660233237Sjkim            PrAddMacro (Token, Next);
661233237Sjkim#endif
662233237Sjkim        }
663233237Sjkim        else
664233237Sjkim        {
665233237Sjkim            /* Use the remainder of the line for the #define */
666233237Sjkim
667233237Sjkim            Token2 = *Next;
668233237Sjkim            if (Token2)
669233237Sjkim            {
670233237Sjkim                while ((*Token2 == ' ') || (*Token2 == '\t'))
671233237Sjkim                {
672233237Sjkim                    Token2++;
673233237Sjkim                }
674233237Sjkim                End = Token2;
675233237Sjkim                while (*End != '\n')
676233237Sjkim                {
677233237Sjkim                    End++;
678233237Sjkim                }
679233237Sjkim                *End = 0;
680233237Sjkim            }
681233237Sjkim            else
682233237Sjkim            {
683233237Sjkim                Token2 = "";
684233237Sjkim            }
685233237Sjkim#if 0
686233237Sjkim            Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next);
687233237Sjkim            if (!Token2)
688233237Sjkim            {
689233237Sjkim                Token2 = "";
690233237Sjkim            }
691233237Sjkim#endif
692284460Sjkim            DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
693233237Sjkim                "New #define: %s->%s\n",
694233237Sjkim                Gbl_CurrentLineNumber, Token, Token2);
695233237Sjkim
696233237Sjkim            PrAddDefine (Token, Token2, FALSE);
697233237Sjkim        }
698233237Sjkim        break;
699233237Sjkim
700233237Sjkim    case PR_DIRECTIVE_ERROR:
701250838Sjkim
702233237Sjkim        /* Note: No macro expansion */
703233237Sjkim
704233237Sjkim        PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE,
705233237Sjkim            THIS_TOKEN_OFFSET (Token));
706233237Sjkim
707252279Sjkim        Gbl_SourceLine = 0;
708252279Sjkim        Gbl_NextError = Gbl_ErrorLog;
709252279Sjkim        CmCleanupAndExit ();
710252279Sjkim        exit(1);
711250838Sjkim
712233237Sjkim    case PR_DIRECTIVE_INCLUDE:
713250838Sjkim
714233237Sjkim        Token = PrGetNextToken (NULL, " \"<>", Next);
715233237Sjkim        if (!Token)
716233237Sjkim        {
717233237Sjkim            goto SyntaxError;
718233237Sjkim        }
719233237Sjkim
720284460Sjkim        DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
721235945Sjkim            "Start #include file \"%s\"\n", Gbl_CurrentLineNumber,
722233237Sjkim            Token, Gbl_CurrentLineNumber);
723233237Sjkim
724284460Sjkim        PrDoIncludeFile (Token);
725233237Sjkim        break;
726233237Sjkim
727284460Sjkim    case PR_DIRECTIVE_INCLUDEBUFFER:
728284460Sjkim
729284460Sjkim        Token = PrGetNextToken (NULL, " \"<>", Next);
730284460Sjkim        if (!Token)
731284460Sjkim        {
732284460Sjkim            goto SyntaxError;
733284460Sjkim        }
734284460Sjkim
735284460Sjkim        Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
736284460Sjkim        if (!Token2)
737284460Sjkim        {
738284460Sjkim            goto SyntaxError;
739284460Sjkim        }
740284460Sjkim
741284460Sjkim        DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
742284460Sjkim            "Start #includebuffer input from file \"%s\", buffer name %s\n",
743284460Sjkim            Gbl_CurrentLineNumber, Token, Token2);
744284460Sjkim
745284460Sjkim        PrDoIncludeBuffer (Token, Token2);
746284460Sjkim        break;
747284460Sjkim
748234623Sjkim    case PR_DIRECTIVE_LINE:
749250838Sjkim
750234623Sjkim        TokenOffset = Token - Gbl_MainTokenBuffer;
751234623Sjkim
752234623Sjkim        Status = PrResolveIntegerExpression (
753234623Sjkim            &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
754234623Sjkim        if (ACPI_FAILURE (Status))
755234623Sjkim        {
756234623Sjkim            return;
757234623Sjkim        }
758234623Sjkim
759284460Sjkim        DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
760234623Sjkim            "User #line invocation %s\n", Gbl_CurrentLineNumber,
761234623Sjkim            Token);
762234623Sjkim
763234623Sjkim        /* Update local line numbers */
764234623Sjkim
765234623Sjkim        Gbl_CurrentLineNumber = (UINT32) Value;
766234623Sjkim        Gbl_PreviousLineNumber = 0;
767234623Sjkim
768234623Sjkim        /* Emit #line into the preprocessor file */
769234623Sjkim
770234623Sjkim        FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
771234623Sjkim            Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename);
772234623Sjkim        break;
773234623Sjkim
774233237Sjkim    case PR_DIRECTIVE_PRAGMA:
775233237Sjkim
776250838Sjkim        if (!strcmp (Token, "disable"))
777233237Sjkim        {
778250838Sjkim            Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
779250838Sjkim            if (!Token)
780250838Sjkim            {
781250838Sjkim                goto SyntaxError;
782250838Sjkim            }
783250838Sjkim
784250838Sjkim            TokenOffset = Token - Gbl_MainTokenBuffer;
785250838Sjkim            AslDisableException (&Gbl_CurrentLineBuffer[TokenOffset]);
786250838Sjkim        }
787250838Sjkim        else if (!strcmp (Token, "message"))
788250838Sjkim        {
789250838Sjkim            Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next);
790250838Sjkim            if (!Token)
791250838Sjkim            {
792250838Sjkim                goto SyntaxError;
793250838Sjkim            }
794250838Sjkim
795250838Sjkim            TokenOffset = Token - Gbl_MainTokenBuffer;
796250838Sjkim            AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]);
797250838Sjkim        }
798250838Sjkim        else
799250838Sjkim        {
800233237Sjkim            PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA,
801233237Sjkim                THIS_TOKEN_OFFSET (Token));
802233237Sjkim            return;
803233237Sjkim        }
804233237Sjkim
805233237Sjkim        break;
806233237Sjkim
807233237Sjkim    case PR_DIRECTIVE_UNDEF:
808250838Sjkim
809284460Sjkim        DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
810233237Sjkim            "#undef: %s\n", Gbl_CurrentLineNumber, Token);
811233237Sjkim
812233237Sjkim        PrRemoveDefine (Token);
813233237Sjkim        break;
814233237Sjkim
815233237Sjkim    case PR_DIRECTIVE_WARNING:
816250838Sjkim
817252279Sjkim        PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE,
818233237Sjkim            THIS_TOKEN_OFFSET (Token));
819233237Sjkim        break;
820233237Sjkim
821233237Sjkim    default:
822250838Sjkim
823233237Sjkim        /* Should never get here */
824284460Sjkim        DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
825233237Sjkim            "Unrecognized directive: %u\n",
826233237Sjkim            Gbl_CurrentLineNumber, Directive);
827233237Sjkim        break;
828233237Sjkim    }
829233237Sjkim
830233237Sjkim    return;
831233237Sjkim
832233237SjkimSyntaxError:
833233237Sjkim
834233237Sjkim    PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX,
835233237Sjkim        THIS_TOKEN_OFFSET (DirectiveToken));
836233237Sjkim    return;
837233237Sjkim}
838233237Sjkim
839233237Sjkim
840233237Sjkim/*******************************************************************************
841233237Sjkim *
842233237Sjkim * FUNCTION:    PrMatchDirective
843233237Sjkim *
844233237Sjkim * PARAMETERS:  Directive           - Pointer to directive name token
845233237Sjkim *
846233237Sjkim * RETURN:      Index into command array, -1 if not found
847233237Sjkim *
848233237Sjkim * DESCRIPTION: Lookup the incoming directive in the known directives table.
849233237Sjkim *
850233237Sjkim ******************************************************************************/
851233237Sjkim
852233237Sjkimstatic int
853233237SjkimPrMatchDirective (
854233237Sjkim    char                    *Directive)
855233237Sjkim{
856233237Sjkim    int                     i;
857233237Sjkim
858233237Sjkim
859233237Sjkim    if (!Directive || Directive[0] == 0)
860233237Sjkim    {
861233237Sjkim        return (ASL_DIRECTIVE_NOT_FOUND);
862233237Sjkim    }
863233237Sjkim
864233237Sjkim    for (i = 0; Gbl_DirectiveInfo[i].Name; i++)
865233237Sjkim    {
866233237Sjkim        if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive))
867233237Sjkim        {
868233237Sjkim            return (i);
869233237Sjkim        }
870233237Sjkim    }
871233237Sjkim
872233237Sjkim    return (ASL_DIRECTIVE_NOT_FOUND);    /* Command not recognized */
873233237Sjkim}
874252279Sjkim
875252279Sjkim
876252279Sjkim/*******************************************************************************
877252279Sjkim *
878252279Sjkim * FUNCTION:    PrPushDirective
879252279Sjkim *
880252279Sjkim * PARAMETERS:  Directive           - Encoded directive ID
881252279Sjkim *              Argument            - String containing argument to the
882252279Sjkim *                                    directive
883252279Sjkim *
884252279Sjkim * RETURN:      None
885252279Sjkim *
886252279Sjkim * DESCRIPTION: Push an item onto the directive stack. Used for processing
887252279Sjkim *              nested #if/#else type conditional compilation directives.
888252279Sjkim *              Specifically: Used on detection of #if/#ifdef/#ifndef to open
889252279Sjkim *              a block.
890252279Sjkim *
891252279Sjkim ******************************************************************************/
892252279Sjkim
893252279Sjkimstatic void
894252279SjkimPrPushDirective (
895252279Sjkim    int                     Directive,
896252279Sjkim    char                    *Argument)
897252279Sjkim{
898252279Sjkim    DIRECTIVE_INFO          *Info;
899252279Sjkim
900252279Sjkim
901252279Sjkim    /* Allocate and populate a stack info item */
902252279Sjkim
903252279Sjkim    Info = ACPI_ALLOCATE (sizeof (DIRECTIVE_INFO));
904252279Sjkim
905252279Sjkim    Info->Next = Gbl_DirectiveStack;
906252279Sjkim    Info->Directive = Directive;
907252279Sjkim    Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock;
908252279Sjkim    strncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH);
909252279Sjkim
910252279Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
911252279Sjkim        "Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n",
912252279Sjkim        Gbl_CurrentLineNumber, Gbl_IfDepth,
913252279Sjkim        Gbl_IgnoringThisCodeBlock ? "I" : "E",
914252279Sjkim        Gbl_IfDepth * 4, " ",
915252279Sjkim        Gbl_DirectiveInfo[Directive].Name,
916252279Sjkim        Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
917252279Sjkim
918252279Sjkim    /* Push new item */
919252279Sjkim
920252279Sjkim    Gbl_DirectiveStack = Info;
921252279Sjkim    Gbl_IfDepth++;
922252279Sjkim}
923252279Sjkim
924252279Sjkim
925252279Sjkim/*******************************************************************************
926252279Sjkim *
927252279Sjkim * FUNCTION:    PrPopDirective
928252279Sjkim *
929252279Sjkim * PARAMETERS:  None
930252279Sjkim *
931252279Sjkim * RETURN:      Status. Error if the stack is empty.
932252279Sjkim *
933252279Sjkim * DESCRIPTION: Pop an item off the directive stack. Used for processing
934252279Sjkim *              nested #if/#else type conditional compilation directives.
935252279Sjkim *              Specifically: Used on detection of #elif and #endif to remove
936252279Sjkim *              the original #if/#ifdef/#ifndef from the stack and close
937252279Sjkim *              the block.
938252279Sjkim *
939252279Sjkim ******************************************************************************/
940252279Sjkim
941252279Sjkimstatic ACPI_STATUS
942252279SjkimPrPopDirective (
943252279Sjkim    void)
944252279Sjkim{
945252279Sjkim    DIRECTIVE_INFO          *Info;
946252279Sjkim
947252279Sjkim
948252279Sjkim    /* Check for empty stack */
949252279Sjkim
950252279Sjkim    Info = Gbl_DirectiveStack;
951252279Sjkim    if (!Info)
952252279Sjkim    {
953252279Sjkim        return (AE_ERROR);
954252279Sjkim    }
955252279Sjkim
956252279Sjkim    /* Pop one item, keep globals up-to-date */
957252279Sjkim
958252279Sjkim    Gbl_IfDepth--;
959252279Sjkim    Gbl_IgnoringThisCodeBlock = Info->IgnoringThisCodeBlock;
960252279Sjkim    Gbl_DirectiveStack = Info->Next;
961252279Sjkim
962252279Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
963252279Sjkim        "Pr(%.4u) - [%u %s] %*s Popped [#%s %s]: IgnoreFlag now = %s\n",
964252279Sjkim        Gbl_CurrentLineNumber, Gbl_IfDepth,
965252279Sjkim        Gbl_IgnoringThisCodeBlock ? "I" : "E",
966252279Sjkim        Gbl_IfDepth * 4, " ",
967252279Sjkim        Gbl_DirectiveInfo[Info->Directive].Name,
968252279Sjkim        Info->Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE");
969252279Sjkim
970252279Sjkim    ACPI_FREE (Info);
971252279Sjkim    return (AE_OK);
972252279Sjkim}
973252279Sjkim
974252279Sjkim
975252279Sjkim/*******************************************************************************
976252279Sjkim *
977252279Sjkim * FUNCTION:    PrDbgPrint
978252279Sjkim *
979252279Sjkim * PARAMETERS:  Action              - Action being performed
980252279Sjkim *              DirectiveName       - Directive being processed
981252279Sjkim *
982252279Sjkim * RETURN:      None
983252279Sjkim *
984252279Sjkim * DESCRIPTION: Special debug print for directive processing.
985252279Sjkim *
986252279Sjkim ******************************************************************************/
987252279Sjkim
988252279Sjkimstatic void
989252279SjkimPrDbgPrint (
990252279Sjkim    char                    *Action,
991252279Sjkim    char                    *DirectiveName)
992252279Sjkim{
993252279Sjkim
994252279Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Pr(%.4u) - [%u %s] "
995284460Sjkim        "%*s %s #%s, IfDepth %u\n",
996252279Sjkim        Gbl_CurrentLineNumber, Gbl_IfDepth,
997252279Sjkim        Gbl_IgnoringThisCodeBlock ? "I" : "E",
998252279Sjkim        Gbl_IfDepth * 4, " ",
999252279Sjkim        Action, DirectiveName, Gbl_IfDepth);
1000252279Sjkim}
1001284460Sjkim
1002284460Sjkim
1003284460Sjkim/*******************************************************************************
1004284460Sjkim *
1005284460Sjkim * FUNCTION:    PrDoIncludeFile
1006284460Sjkim *
1007284460Sjkim * PARAMETERS:  Pathname                - Name of the input file
1008284460Sjkim *
1009284460Sjkim * RETURN:      None.
1010284460Sjkim *
1011284460Sjkim * DESCRIPTION: Open an include file, from #include.
1012284460Sjkim *
1013284460Sjkim ******************************************************************************/
1014284460Sjkim
1015284460Sjkimstatic void
1016284460SjkimPrDoIncludeFile (
1017284460Sjkim    char                    *Pathname)
1018284460Sjkim{
1019284460Sjkim    char                    *FullPathname;
1020284460Sjkim
1021284460Sjkim
1022284460Sjkim    (void) PrOpenIncludeFile (Pathname, "r", &FullPathname);
1023284460Sjkim}
1024284460Sjkim
1025284460Sjkim
1026284460Sjkim/*******************************************************************************
1027284460Sjkim *
1028284460Sjkim * FUNCTION:    PrDoIncludeBuffer
1029284460Sjkim *
1030284460Sjkim * PARAMETERS:  Pathname                - Name of the input binary file
1031284460Sjkim *              BufferName              - ACPI namepath of the buffer
1032284460Sjkim *
1033284460Sjkim * RETURN:      None.
1034284460Sjkim *
1035284460Sjkim * DESCRIPTION: Create an ACPI buffer object from a binary file. The contents
1036284460Sjkim *              of the file are emitted into the buffer object as ascii
1037284460Sjkim *              hex data. From #includebuffer.
1038284460Sjkim *
1039284460Sjkim ******************************************************************************/
1040284460Sjkim
1041284460Sjkimstatic void
1042284460SjkimPrDoIncludeBuffer (
1043284460Sjkim    char                    *Pathname,
1044284460Sjkim    char                    *BufferName)
1045284460Sjkim{
1046284460Sjkim    char                    *FullPathname;
1047284460Sjkim    FILE                    *BinaryBufferFile;
1048284460Sjkim    UINT32                  i = 0;
1049284460Sjkim    UINT8                   c;
1050284460Sjkim
1051284460Sjkim
1052284460Sjkim    BinaryBufferFile = PrOpenIncludeFile (Pathname, "rb", &FullPathname);
1053284460Sjkim    if (!BinaryBufferFile)
1054284460Sjkim    {
1055284460Sjkim        return;
1056284460Sjkim    }
1057284460Sjkim
1058284460Sjkim    /* Emit "Name (XXXX, Buffer() {" header */
1059284460Sjkim
1060284460Sjkim    FlPrintFile (ASL_FILE_PREPROCESSOR, "Name (%s, Buffer()\n{", BufferName);
1061284460Sjkim
1062284460Sjkim    /* Dump the entire file in ascii hex format */
1063284460Sjkim
1064284460Sjkim    while (fread (&c, 1, 1, BinaryBufferFile))
1065284460Sjkim    {
1066284460Sjkim        if (!(i % 8))
1067284460Sjkim        {
1068284460Sjkim            FlPrintFile (ASL_FILE_PREPROCESSOR, "\n   ", c);
1069284460Sjkim        }
1070284460Sjkim
1071284460Sjkim        FlPrintFile (ASL_FILE_PREPROCESSOR, " 0x%2.2X,", c);
1072284460Sjkim        i++;
1073284460Sjkim    }
1074284460Sjkim
1075284460Sjkim    DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
1076284460Sjkim        "#includebuffer: read %u bytes from %s\n",
1077284460Sjkim        Gbl_CurrentLineNumber, i, FullPathname);
1078284460Sjkim
1079284460Sjkim    /* Close the Name() operator */
1080284460Sjkim
1081284460Sjkim    FlPrintFile (ASL_FILE_PREPROCESSOR, "\n})\n", BufferName);
1082284460Sjkim    fclose (BinaryBufferFile);
1083284460Sjkim}
1084