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