1 /******************************************************************************
2 *
3 * Module Name: prexpress - Preprocessor #if expression support
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "aslcompiler.h"
45
46 #define _COMPONENT ASL_PREPROCESSOR
47 ACPI_MODULE_NAME ("prexpress")
48
49 /* Local prototypes */
50
51 static char *
52 PrExpandMacros (
53 char *Line);
54
55
56 #ifdef _UNDER_DEVELOPMENT
57 /******************************************************************************
58 *
59 * FUNCTION: PrUnTokenize
60 *
61 * PARAMETERS: Buffer - Token Buffer
62 * Next - "Next" buffer from GetNextToken
63 *
64 * RETURN: None
65 *
66 * DESCRIPTION: Un-tokenized the current token buffer. The implementation is
67 * to simply set the null inserted by GetNextToken to a blank.
68 * If Next is NULL, there were no tokens found in the Buffer,
69 * so there is nothing to do.
70 *
71 *****************************************************************************/
72
73 static void
PrUnTokenize(char * Buffer,char * Next)74 PrUnTokenize (
75 char *Buffer,
76 char *Next)
77 {
78 UINT32 Length = strlen (Buffer);
79
80
81 if (!Next)
82 {
83 return;
84 }
85
86 if (Buffer[Length] != '\n')
87 {
88 Buffer[strlen(Buffer)] = ' ';
89 }
90 }
91 #endif
92
93
94 /******************************************************************************
95 *
96 * FUNCTION: PrExpandMacros
97 *
98 * PARAMETERS: Line - Pointer into the current line
99 *
100 * RETURN: Updated pointer into the current line
101 *
102 * DESCRIPTION: Expand any macros found in the current line buffer.
103 *
104 *****************************************************************************/
105
106 static char *
PrExpandMacros(char * Line)107 PrExpandMacros (
108 char *Line)
109 {
110 char *Token;
111 char *ReplaceString;
112 PR_DEFINE_INFO *DefineInfo;
113 ACPI_SIZE TokenOffset;
114 char *Next;
115 int OffsetAdjust;
116
117
118 strcpy (AslGbl_ExpressionTokenBuffer, AslGbl_CurrentLineBuffer);
119 Token = PrGetNextToken (AslGbl_ExpressionTokenBuffer, PR_EXPR_SEPARATORS, &Next);
120 OffsetAdjust = 0;
121
122 while (Token)
123 {
124 DefineInfo = PrMatchDefine (Token);
125 if (DefineInfo)
126 {
127 if (DefineInfo->Body)
128 {
129 /* This is a macro. TBD: Is this allowed? */
130
131 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
132 "Matched Macro: %s->%s\n",
133 AslGbl_CurrentLineNumber, DefineInfo->Identifier,
134 DefineInfo->Replacement);
135
136 PrDoMacroInvocation (AslGbl_ExpressionTokenBuffer, Token,
137 DefineInfo, &Next);
138 }
139 else
140 {
141 ReplaceString = DefineInfo->Replacement;
142
143 /* Replace the name in the original line buffer */
144
145 TokenOffset = Token - AslGbl_ExpressionTokenBuffer + OffsetAdjust;
146 PrReplaceData (
147 &AslGbl_CurrentLineBuffer[TokenOffset], strlen (Token),
148 ReplaceString, strlen (ReplaceString));
149
150 /* Adjust for length difference between old and new name length */
151
152 OffsetAdjust += strlen (ReplaceString) - strlen (Token);
153
154 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
155 "Matched #define within expression: %s->%s\n",
156 AslGbl_CurrentLineNumber, Token,
157 *ReplaceString ? ReplaceString : "(NULL STRING)");
158 }
159 }
160
161 Token = PrGetNextToken (NULL, PR_EXPR_SEPARATORS, &Next);
162 }
163
164 return (Line);
165 }
166
167
168 /******************************************************************************
169 *
170 * FUNCTION: PrIsDefined
171 *
172 * PARAMETERS: Identifier - Name to be resolved
173 *
174 * RETURN: 64-bit boolean integer value
175 *
176 * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
177 *
178 *****************************************************************************/
179
180 UINT64
PrIsDefined(char * Identifier)181 PrIsDefined (
182 char *Identifier)
183 {
184 UINT64 Value;
185 PR_DEFINE_INFO *DefineInfo;
186
187
188 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
189 "**** Is defined?: %s\n", AslGbl_CurrentLineNumber, Identifier);
190
191 Value = 0; /* Default is "Not defined" -- FALSE */
192
193 DefineInfo = PrMatchDefine (Identifier);
194 if (DefineInfo)
195 {
196 Value = ACPI_UINT64_MAX; /* TRUE */
197 }
198
199 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
200 "[#if defined %s] resolved to: %8.8X%8.8X\n",
201 AslGbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
202
203 return (Value);
204 }
205
206
207 /******************************************************************************
208 *
209 * FUNCTION: PrResolveDefine
210 *
211 * PARAMETERS: Identifier - Name to be resolved
212 *
213 * RETURN: A 64-bit boolean integer value
214 *
215 * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
216 *
217 *****************************************************************************/
218
219 UINT64
PrResolveDefine(char * Identifier)220 PrResolveDefine (
221 char *Identifier)
222 {
223 UINT64 Value;
224 PR_DEFINE_INFO *DefineInfo;
225
226
227 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
228 "**** Resolve #define: %s\n", AslGbl_CurrentLineNumber, Identifier);
229
230 Value = 0; /* Default is "Not defined" -- FALSE */
231
232 DefineInfo = PrMatchDefine (Identifier);
233 if (DefineInfo)
234 {
235 Value = ACPI_UINT64_MAX; /* TRUE */
236 }
237
238 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
239 "[#if defined %s] resolved to: %8.8X%8.8X\n",
240 AslGbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
241
242 return (Value);
243 }
244
245
246 /******************************************************************************
247 *
248 * FUNCTION: PrResolveIntegerExpression
249 *
250 * PARAMETERS: Line - Pointer to integer expression
251 * ReturnValue - Where the resolved 64-bit integer is
252 * returned.
253 *
254 * RETURN: Status
255 *
256 * DESCRIPTION: Resolve an integer expression to a single value. Supports
257 * both integer constants and labels.
258 *
259 *****************************************************************************/
260
261 ACPI_STATUS
PrResolveIntegerExpression(char * Line,UINT64 * ReturnValue)262 PrResolveIntegerExpression (
263 char *Line,
264 UINT64 *ReturnValue)
265 {
266 UINT64 Result;
267 char *ExpandedLine;
268
269
270 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
271 "**** Resolve #if: %s\n", AslGbl_CurrentLineNumber, Line);
272
273 /* Expand all macros within the expression first */
274
275 ExpandedLine = PrExpandMacros (Line);
276
277 /* Now we can evaluate the expression */
278
279 Result = PrEvaluateExpression (ExpandedLine);
280 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
281 "**** Expression Resolved to: %8.8X%8.8X\n",
282 AslGbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Result));
283
284 *ReturnValue = Result;
285 return (AE_OK);
286
287 #if 0
288 InvalidExpression:
289
290 ACPI_FREE (EvalBuffer);
291 PrError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, 0);
292 return (AE_ERROR);
293
294
295 NormalExit:
296
297 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
298 "**** Expression Resolved to: %8.8X%8.8X\n",
299 AslGbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value1));
300
301 *ReturnValue = Value1;
302 return (AE_OK);
303 #endif
304 }
305