1 /****************************************************************************** 2 * 3 * Module Name: prexpress - Preprocessor #if expression support 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 MERCHANTIBILITY 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 <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include <contrib/dev/acpica/compiler/dtcompiler.h> 46 47 48 #define _COMPONENT ASL_PREPROCESSOR 49 ACPI_MODULE_NAME ("prexpress") 50 51 /* Local prototypes */ 52 53 static char * 54 PrExpandMacros ( 55 char *Line); 56 57 58 #ifdef _UNDER_DEVELOPMENT 59 /****************************************************************************** 60 * 61 * FUNCTION: PrUnTokenize 62 * 63 * PARAMETERS: Buffer - Token Buffer 64 * Next - "Next" buffer from GetNextToken 65 * 66 * RETURN: None 67 * 68 * DESCRIPTION: Un-tokenized the current token buffer. The implementation is 69 * to simply set the null inserted by GetNextToken to a blank. 70 * If Next is NULL, there were no tokens found in the Buffer, 71 * so there is nothing to do. 72 * 73 *****************************************************************************/ 74 75 static void 76 PrUnTokenize ( 77 char *Buffer, 78 char *Next) 79 { 80 UINT32 Length = strlen (Buffer); 81 82 83 if (!Next) 84 { 85 return; 86 } 87 88 if (Buffer[Length] != '\n') 89 { 90 Buffer[strlen(Buffer)] = ' '; 91 } 92 } 93 #endif 94 95 96 /****************************************************************************** 97 * 98 * FUNCTION: PrExpandMacros 99 * 100 * PARAMETERS: Line - Pointer into the current line 101 * 102 * RETURN: Updated pointer into the current line 103 * 104 * DESCRIPTION: Expand any macros found in the current line buffer. 105 * 106 *****************************************************************************/ 107 108 static char * 109 PrExpandMacros ( 110 char *Line) 111 { 112 char *Token; 113 char *ReplaceString; 114 PR_DEFINE_INFO *DefineInfo; 115 ACPI_SIZE TokenOffset; 116 char *Next; 117 int OffsetAdjust; 118 119 120 strcpy (Gbl_ExpressionTokenBuffer, Gbl_CurrentLineBuffer); 121 Token = PrGetNextToken (Gbl_ExpressionTokenBuffer, PR_EXPR_SEPARATORS, &Next); 122 OffsetAdjust = 0; 123 124 while (Token) 125 { 126 DefineInfo = PrMatchDefine (Token); 127 if (DefineInfo) 128 { 129 if (DefineInfo->Body) 130 { 131 /* This is a macro. TBD: Is this allowed? */ 132 133 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 134 "Matched Macro: %s->%s\n", 135 Gbl_CurrentLineNumber, DefineInfo->Identifier, 136 DefineInfo->Replacement); 137 138 PrDoMacroInvocation (Gbl_ExpressionTokenBuffer, Token, 139 DefineInfo, &Next); 140 } 141 else 142 { 143 ReplaceString = DefineInfo->Replacement; 144 145 /* Replace the name in the original line buffer */ 146 147 TokenOffset = Token - Gbl_ExpressionTokenBuffer + OffsetAdjust; 148 PrReplaceData ( 149 &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), 150 ReplaceString, strlen (ReplaceString)); 151 152 /* Adjust for length difference between old and new name length */ 153 154 OffsetAdjust += strlen (ReplaceString) - strlen (Token); 155 156 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 157 "Matched #define within expression: %s->%s\n", 158 Gbl_CurrentLineNumber, Token, 159 *ReplaceString ? ReplaceString : "(NULL STRING)"); 160 } 161 } 162 163 Token = PrGetNextToken (NULL, PR_EXPR_SEPARATORS, &Next); 164 } 165 166 return (Line); 167 } 168 169 170 /****************************************************************************** 171 * 172 * FUNCTION: PrIsDefined 173 * 174 * PARAMETERS: Identifier - Name to be resolved 175 * 176 * RETURN: 64-bit boolean integer value 177 * 178 * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0). 179 * 180 *****************************************************************************/ 181 182 UINT64 183 PrIsDefined ( 184 char *Identifier) 185 { 186 UINT64 Value; 187 PR_DEFINE_INFO *DefineInfo; 188 189 190 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 191 "**** Is defined?: %s\n", Gbl_CurrentLineNumber, Identifier); 192 193 Value = 0; /* Default is "Not defined" -- FALSE */ 194 195 DefineInfo = PrMatchDefine (Identifier); 196 if (DefineInfo) 197 { 198 Value = ACPI_UINT64_MAX; /* TRUE */ 199 } 200 201 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 202 "[#if defined %s] resolved to: %8.8X%8.8X\n", 203 Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value)); 204 205 return (Value); 206 } 207 208 209 /****************************************************************************** 210 * 211 * FUNCTION: PrResolveDefine 212 * 213 * PARAMETERS: Identifier - Name to be resolved 214 * 215 * RETURN: A 64-bit boolean integer value 216 * 217 * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0). 218 * 219 *****************************************************************************/ 220 221 UINT64 222 PrResolveDefine ( 223 char *Identifier) 224 { 225 UINT64 Value; 226 PR_DEFINE_INFO *DefineInfo; 227 228 229 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 230 "**** Resolve #define: %s\n", Gbl_CurrentLineNumber, Identifier); 231 232 Value = 0; /* Default is "Not defined" -- FALSE */ 233 234 DefineInfo = PrMatchDefine (Identifier); 235 if (DefineInfo) 236 { 237 Value = ACPI_UINT64_MAX; /* TRUE */ 238 } 239 240 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 241 "[#if defined %s] resolved to: %8.8X%8.8X\n", 242 Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value)); 243 244 return (Value); 245 } 246 247 248 /****************************************************************************** 249 * 250 * FUNCTION: PrResolveIntegerExpression 251 * 252 * PARAMETERS: Line - Pointer to integer expression 253 * ReturnValue - Where the resolved 64-bit integer is 254 * returned. 255 * 256 * RETURN: Status 257 * 258 * DESCRIPTION: Resolve an integer expression to a single value. Supports 259 * both integer constants and labels. 260 * 261 *****************************************************************************/ 262 263 ACPI_STATUS 264 PrResolveIntegerExpression ( 265 char *Line, 266 UINT64 *ReturnValue) 267 { 268 UINT64 Result; 269 char *ExpandedLine; 270 271 272 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 273 "**** Resolve #if: %s\n", Gbl_CurrentLineNumber, Line); 274 275 /* Expand all macros within the expression first */ 276 277 ExpandedLine = PrExpandMacros (Line); 278 279 /* Now we can evaluate the expression */ 280 281 Result = PrEvaluateExpression (ExpandedLine); 282 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 283 "**** Expression Resolved to: %8.8X%8.8X\n", 284 Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Result)); 285 286 *ReturnValue = Result; 287 return (AE_OK); 288 289 #if 0 290 InvalidExpression: 291 292 ACPI_FREE (EvalBuffer); 293 PrError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, 0); 294 return (AE_ERROR); 295 296 297 NormalExit: 298 299 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 300 "**** Expression Resolved to: %8.8X%8.8X\n", 301 Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value1)); 302 303 *ReturnValue = Value1; 304 return (AE_OK); 305 #endif 306 } 307