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 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 * 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 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 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 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