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