1233237Sjkim/******************************************************************************
2233237Sjkim *
3233237Sjkim * Module Name: prexpress - Preprocessor #if expression support
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
44233250Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45233250Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
46233237Sjkim
47233237Sjkim
48233237Sjkim#define _COMPONENT          ASL_PREPROCESSOR
49233237Sjkim        ACPI_MODULE_NAME    ("prexpress")
50233237Sjkim
51233237Sjkim/* Local prototypes */
52233237Sjkim
53233237Sjkimstatic char *
54233237SjkimPrExpandMacros (
55233237Sjkim    char                    *Line);
56233237Sjkim
57233237Sjkim
58233237Sjkim#ifdef _UNDER_DEVELOPMENT
59233237Sjkim/******************************************************************************
60233237Sjkim *
61233237Sjkim * FUNCTION:    PrUnTokenize
62233237Sjkim *
63233237Sjkim * PARAMETERS:  Buffer              - Token Buffer
64233237Sjkim *              Next                - "Next" buffer from GetNextToken
65233237Sjkim *
66233237Sjkim * RETURN:      None
67233237Sjkim *
68233237Sjkim * DESCRIPTION: Un-tokenized the current token buffer. The implementation is
69233237Sjkim *              to simply set the null inserted by GetNextToken to a blank.
70233237Sjkim *              If Next is NULL, there were no tokens found in the Buffer,
71233237Sjkim *              so there is nothing to do.
72233237Sjkim *
73233237Sjkim *****************************************************************************/
74233237Sjkim
75233237Sjkimstatic void
76233237SjkimPrUnTokenize (
77233237Sjkim    char                    *Buffer,
78233237Sjkim    char                    *Next)
79233237Sjkim{
80233237Sjkim    UINT32                  Length = strlen (Buffer);
81233237Sjkim
82233237Sjkim
83233237Sjkim    if (!Next)
84233237Sjkim    {
85233237Sjkim        return;
86233237Sjkim    }
87233237Sjkim    if (Buffer[Length] != '\n')
88233237Sjkim    {
89233237Sjkim        Buffer[strlen(Buffer)] = ' ';
90233237Sjkim    }
91233237Sjkim}
92233237Sjkim#endif
93233237Sjkim
94233237Sjkim
95233237Sjkim/******************************************************************************
96233237Sjkim *
97233237Sjkim * FUNCTION:    PrExpandMacros
98233237Sjkim *
99233237Sjkim * PARAMETERS:  Line                - Pointer into the current line
100233237Sjkim *
101233237Sjkim * RETURN:      Updated pointer into the current line
102233237Sjkim *
103233237Sjkim * DESCRIPTION: Expand any macros found in the current line buffer.
104233237Sjkim *
105233237Sjkim *****************************************************************************/
106233237Sjkim
107233237Sjkimstatic char *
108233237SjkimPrExpandMacros (
109233237Sjkim    char                    *Line)
110233237Sjkim{
111233237Sjkim    char                    *Token;
112233237Sjkim    char                    *ReplaceString;
113233237Sjkim    PR_DEFINE_INFO          *DefineInfo;
114233237Sjkim    ACPI_SIZE               TokenOffset;
115233237Sjkim    char                    *Next;
116233237Sjkim    int                     OffsetAdjust;
117233237Sjkim
118233237Sjkim
119233237Sjkim    strcpy (Gbl_ExpressionTokenBuffer, Gbl_CurrentLineBuffer);
120233237Sjkim    Token = PrGetNextToken (Gbl_ExpressionTokenBuffer, PR_EXPR_SEPARATORS, &Next);
121233237Sjkim    OffsetAdjust = 0;
122233237Sjkim
123233237Sjkim    while (Token)
124233237Sjkim    {
125233237Sjkim        DefineInfo = PrMatchDefine (Token);
126233237Sjkim        if (DefineInfo)
127233237Sjkim        {
128233237Sjkim            if (DefineInfo->Body)
129233237Sjkim            {
130233237Sjkim                /* This is a macro. TBD: Is this allowed? */
131233237Sjkim
132233237Sjkim                DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
133233237Sjkim                    "Matched Macro: %s->%s\n",
134233237Sjkim                    Gbl_CurrentLineNumber, DefineInfo->Identifier,
135233237Sjkim                    DefineInfo->Replacement);
136233237Sjkim
137233237Sjkim                PrDoMacroInvocation (Gbl_ExpressionTokenBuffer, Token,
138233237Sjkim                    DefineInfo, &Next);
139233237Sjkim            }
140233237Sjkim            else
141233237Sjkim            {
142233237Sjkim                ReplaceString = DefineInfo->Replacement;
143233237Sjkim
144233237Sjkim                /* Replace the name in the original line buffer */
145233237Sjkim
146233237Sjkim                TokenOffset = Token - Gbl_ExpressionTokenBuffer + OffsetAdjust;
147233237Sjkim                PrReplaceData (
148233237Sjkim                    &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token),
149233237Sjkim                    ReplaceString, strlen (ReplaceString));
150233237Sjkim
151233237Sjkim                /* Adjust for length difference between old and new name length */
152233237Sjkim
153233237Sjkim                OffsetAdjust += strlen (ReplaceString) - strlen (Token);
154233237Sjkim
155233237Sjkim                DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
156233237Sjkim                    "Matched #define within expression: %s->%s\n",
157233237Sjkim                    Gbl_CurrentLineNumber, Token,
158233237Sjkim                    *ReplaceString ? ReplaceString : "(NULL STRING)");
159233237Sjkim            }
160233237Sjkim        }
161233237Sjkim
162233237Sjkim        Token = PrGetNextToken (NULL, PR_EXPR_SEPARATORS, &Next);
163233237Sjkim    }
164233237Sjkim
165233237Sjkim    return (Line);
166233237Sjkim}
167233237Sjkim
168233237Sjkim
169233237Sjkim/******************************************************************************
170233237Sjkim *
171233237Sjkim * FUNCTION:    PrIsDefined
172233237Sjkim *
173233237Sjkim * PARAMETERS:  Identifier          - Name to be resolved
174233237Sjkim *
175233237Sjkim * RETURN:      64-bit boolean integer value
176233237Sjkim *
177233237Sjkim * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
178233237Sjkim *
179233237Sjkim *****************************************************************************/
180233237Sjkim
181233237SjkimUINT64
182233237SjkimPrIsDefined (
183233237Sjkim    char                    *Identifier)
184233237Sjkim{
185233237Sjkim    UINT64                  Value;
186233237Sjkim    PR_DEFINE_INFO          *DefineInfo;
187233237Sjkim
188233237Sjkim
189233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
190233237Sjkim        "**** Is defined?:  %s\n", Gbl_CurrentLineNumber, Identifier);
191233237Sjkim
192233237Sjkim    Value = 0; /* Default is "Not defined" -- FALSE */
193233237Sjkim
194233237Sjkim    DefineInfo = PrMatchDefine (Identifier);
195233237Sjkim    if (DefineInfo)
196233237Sjkim    {
197233237Sjkim        Value = ACPI_UINT64_MAX; /* TRUE */
198233237Sjkim    }
199233237Sjkim
200233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
201233237Sjkim        "[#if defined %s] resolved to: %8.8X%8.8X\n",
202233237Sjkim        Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
203233237Sjkim
204233237Sjkim    return (Value);
205233237Sjkim}
206233237Sjkim
207233237Sjkim
208233237Sjkim/******************************************************************************
209233237Sjkim *
210233237Sjkim * FUNCTION:    PrResolveDefine
211233237Sjkim *
212233237Sjkim * PARAMETERS:  Identifier          - Name to be resolved
213233237Sjkim *
214233237Sjkim * RETURN:      A 64-bit boolean integer value
215233237Sjkim *
216233237Sjkim * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
217233237Sjkim *
218233237Sjkim *****************************************************************************/
219233237Sjkim
220233237SjkimUINT64
221233237SjkimPrResolveDefine (
222233237Sjkim    char                    *Identifier)
223233237Sjkim{
224233237Sjkim    UINT64                  Value;
225233237Sjkim    PR_DEFINE_INFO          *DefineInfo;
226233237Sjkim
227233237Sjkim
228233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
229233237Sjkim        "**** Resolve #define:  %s\n", Gbl_CurrentLineNumber, Identifier);
230233237Sjkim
231233237Sjkim    Value = 0; /* Default is "Not defined" -- FALSE */
232233237Sjkim
233233237Sjkim    DefineInfo = PrMatchDefine (Identifier);
234233237Sjkim    if (DefineInfo)
235233237Sjkim    {
236233237Sjkim        Value = ACPI_UINT64_MAX; /* TRUE */
237233237Sjkim    }
238233237Sjkim
239233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
240233237Sjkim        "[#if defined %s] resolved to: %8.8X%8.8X\n",
241233237Sjkim        Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
242233237Sjkim
243233237Sjkim    return (Value);
244233237Sjkim}
245233237Sjkim
246233237Sjkim
247233237Sjkim/******************************************************************************
248233237Sjkim *
249233237Sjkim * FUNCTION:    PrResolveIntegerExpression
250233237Sjkim *
251233237Sjkim * PARAMETERS:  Line                - Pointer to integer expression
252233237Sjkim *              ReturnValue         - Where the resolved 64-bit integer is
253233237Sjkim *                                    returned.
254233237Sjkim *
255233237Sjkim * RETURN:      Status
256233237Sjkim *
257233237Sjkim * DESCRIPTION: Resolve an integer expression to a single value. Supports
258233237Sjkim *              both integer constants and labels.
259233237Sjkim *
260233237Sjkim *****************************************************************************/
261233237Sjkim
262233237SjkimACPI_STATUS
263233237SjkimPrResolveIntegerExpression (
264233237Sjkim    char                    *Line,
265233237Sjkim    UINT64                  *ReturnValue)
266233237Sjkim{
267233237Sjkim    UINT64                  Result;
268233237Sjkim    char                    *ExpandedLine;
269233237Sjkim
270233237Sjkim
271233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
272233237Sjkim        "**** Resolve #if:  %s\n", Gbl_CurrentLineNumber, Line);
273233237Sjkim
274233237Sjkim    /* Expand all macros within the expression first */
275233237Sjkim
276233237Sjkim    ExpandedLine = PrExpandMacros (Line);
277233237Sjkim
278233237Sjkim    /* Now we can evaluate the expression */
279233237Sjkim
280233237Sjkim    Result = PrEvaluateExpression (ExpandedLine);
281233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
282233237Sjkim        "**** Expression Resolved to: %8.8X%8.8X\n",
283233237Sjkim        Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Result));
284233237Sjkim
285233237Sjkim    *ReturnValue = Result;
286233237Sjkim    return (AE_OK);
287233237Sjkim
288233237Sjkim#if 0
289233237SjkimInvalidExpression:
290233237Sjkim
291233237Sjkim    ACPI_FREE (EvalBuffer);
292233237Sjkim    PrError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, 0);
293233237Sjkim    return (AE_ERROR);
294233237Sjkim
295233237Sjkim
296233237SjkimNormalExit:
297233237Sjkim
298233237Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
299233237Sjkim        "**** Expression Resolved to: %8.8X%8.8X\n",
300233237Sjkim        Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value1));
301233237Sjkim
302233237Sjkim    *ReturnValue = Value1;
303233237Sjkim    return (AE_OK);
304233237Sjkim#endif
305233237Sjkim}
306