14c52cad2SJung-uk Kim /****************************************************************************** 24c52cad2SJung-uk Kim * 34c52cad2SJung-uk Kim * Module Name: prmacros - Preprocessor #define macro support 44c52cad2SJung-uk Kim * 54c52cad2SJung-uk Kim *****************************************************************************/ 64c52cad2SJung-uk Kim 74c52cad2SJung-uk Kim /* 8*f8146b88SJung-uk Kim * Copyright (C) 2000 - 2016, Intel Corp. 94c52cad2SJung-uk Kim * All rights reserved. 104c52cad2SJung-uk Kim * 114c52cad2SJung-uk Kim * Redistribution and use in source and binary forms, with or without 124c52cad2SJung-uk Kim * modification, are permitted provided that the following conditions 134c52cad2SJung-uk Kim * are met: 144c52cad2SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 154c52cad2SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 164c52cad2SJung-uk Kim * without modification. 174c52cad2SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 184c52cad2SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 194c52cad2SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 204c52cad2SJung-uk Kim * including a substantially similar Disclaimer requirement for further 214c52cad2SJung-uk Kim * binary redistribution. 224c52cad2SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 234c52cad2SJung-uk Kim * of any contributors may be used to endorse or promote products derived 244c52cad2SJung-uk Kim * from this software without specific prior written permission. 254c52cad2SJung-uk Kim * 264c52cad2SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 274c52cad2SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 284c52cad2SJung-uk Kim * Software Foundation. 294c52cad2SJung-uk Kim * 304c52cad2SJung-uk Kim * NO WARRANTY 314c52cad2SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 324c52cad2SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 334c52cad2SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 344c52cad2SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 354c52cad2SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 364c52cad2SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 374c52cad2SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 384c52cad2SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 394c52cad2SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 404c52cad2SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 414c52cad2SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 424c52cad2SJung-uk Kim */ 434c52cad2SJung-uk Kim 444c52cad2SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 454c52cad2SJung-uk Kim #include <contrib/dev/acpica/compiler/dtcompiler.h> 464c52cad2SJung-uk Kim 474c52cad2SJung-uk Kim 484c52cad2SJung-uk Kim #define _COMPONENT ASL_PREPROCESSOR 494c52cad2SJung-uk Kim ACPI_MODULE_NAME ("prmacros") 504c52cad2SJung-uk Kim 514c52cad2SJung-uk Kim 524c52cad2SJung-uk Kim /******************************************************************************* 534c52cad2SJung-uk Kim * 544c52cad2SJung-uk Kim * FUNCTION: PrDumpPredefinedNames 554c52cad2SJung-uk Kim * 564c52cad2SJung-uk Kim * PARAMETERS: None 574c52cad2SJung-uk Kim * 584c52cad2SJung-uk Kim * RETURN: None 594c52cad2SJung-uk Kim * 604c52cad2SJung-uk Kim * DESCRIPTION: Dump the list of #defines. Used as the preprocessor starts, to 614c52cad2SJung-uk Kim * display the names that were defined on the command line. 624c52cad2SJung-uk Kim * Debug information only. 634c52cad2SJung-uk Kim * 644c52cad2SJung-uk Kim ******************************************************************************/ 654c52cad2SJung-uk Kim 664c52cad2SJung-uk Kim void 674c52cad2SJung-uk Kim PrDumpPredefinedNames ( 684c52cad2SJung-uk Kim void) 694c52cad2SJung-uk Kim { 704c52cad2SJung-uk Kim PR_DEFINE_INFO *DefineInfo; 714c52cad2SJung-uk Kim 724c52cad2SJung-uk Kim 734c52cad2SJung-uk Kim DefineInfo = Gbl_DefineList; 744c52cad2SJung-uk Kim while (DefineInfo) 754c52cad2SJung-uk Kim { 764c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 774c52cad2SJung-uk Kim "Predefined #define: %s->%s\n", 784c52cad2SJung-uk Kim 0, DefineInfo->Identifier, DefineInfo->Replacement); 794c52cad2SJung-uk Kim 804c52cad2SJung-uk Kim DefineInfo = DefineInfo->Next; 814c52cad2SJung-uk Kim } 824c52cad2SJung-uk Kim } 834c52cad2SJung-uk Kim 844c52cad2SJung-uk Kim 854c52cad2SJung-uk Kim /******************************************************************************* 864c52cad2SJung-uk Kim * 874c52cad2SJung-uk Kim * FUNCTION: PrAddDefine 884c52cad2SJung-uk Kim * 894c52cad2SJung-uk Kim * PARAMETERS: Identifier - Name to be replaced 904c52cad2SJung-uk Kim * Replacement - Replacement for Identifier 914c52cad2SJung-uk Kim * Persist - Keep define across multiple compiles? 924c52cad2SJung-uk Kim * 934c52cad2SJung-uk Kim * RETURN: A new define_info struct. NULL on error. 944c52cad2SJung-uk Kim * 954c52cad2SJung-uk Kim * DESCRIPTION: Add a new #define to the global list 964c52cad2SJung-uk Kim * 974c52cad2SJung-uk Kim ******************************************************************************/ 984c52cad2SJung-uk Kim 994c52cad2SJung-uk Kim PR_DEFINE_INFO * 1004c52cad2SJung-uk Kim PrAddDefine ( 1014c52cad2SJung-uk Kim char *Identifier, 1024c52cad2SJung-uk Kim char *Replacement, 1034c52cad2SJung-uk Kim BOOLEAN Persist) 1044c52cad2SJung-uk Kim { 1054c52cad2SJung-uk Kim char *IdentifierString; 1064c52cad2SJung-uk Kim char *ReplacementString; 1074c52cad2SJung-uk Kim PR_DEFINE_INFO *DefineInfo; 1084c52cad2SJung-uk Kim 1094c52cad2SJung-uk Kim 1104c52cad2SJung-uk Kim if (!Replacement) 1114c52cad2SJung-uk Kim { 1124c52cad2SJung-uk Kim Replacement = ""; 1134c52cad2SJung-uk Kim } 1144c52cad2SJung-uk Kim 1154c52cad2SJung-uk Kim /* Check for already-defined first */ 1164c52cad2SJung-uk Kim 1174c52cad2SJung-uk Kim DefineInfo = PrMatchDefine (Identifier); 1184c52cad2SJung-uk Kim if (DefineInfo) 1194c52cad2SJung-uk Kim { 1204c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID, 1214c52cad2SJung-uk Kim "#define: name already exists: %s\n", 1224c52cad2SJung-uk Kim Gbl_CurrentLineNumber, Identifier); 1234c52cad2SJung-uk Kim 1244c52cad2SJung-uk Kim /* 1254c52cad2SJung-uk Kim * Name already exists. This is only an error if the target name 1264c52cad2SJung-uk Kim * is different. 1274c52cad2SJung-uk Kim */ 1284c52cad2SJung-uk Kim if (strcmp (Replacement, DefineInfo->Replacement)) 1294c52cad2SJung-uk Kim { 1304c52cad2SJung-uk Kim PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME, 1314c52cad2SJung-uk Kim THIS_TOKEN_OFFSET (Identifier)); 1324c52cad2SJung-uk Kim 1334c52cad2SJung-uk Kim return (NULL); 1344c52cad2SJung-uk Kim } 1354c52cad2SJung-uk Kim 1364c52cad2SJung-uk Kim return (DefineInfo); 1374c52cad2SJung-uk Kim } 1384c52cad2SJung-uk Kim 1394c52cad2SJung-uk Kim /* Copy input strings */ 1404c52cad2SJung-uk Kim 1414c52cad2SJung-uk Kim IdentifierString = UtLocalCalloc (strlen (Identifier) + 1); 1424c52cad2SJung-uk Kim strcpy (IdentifierString, Identifier); 1434c52cad2SJung-uk Kim 1444c52cad2SJung-uk Kim ReplacementString = UtLocalCalloc (strlen (Replacement) + 1); 1454c52cad2SJung-uk Kim strcpy (ReplacementString, Replacement); 1464c52cad2SJung-uk Kim 1474c52cad2SJung-uk Kim /* Init and link new define info struct */ 1484c52cad2SJung-uk Kim 1494c52cad2SJung-uk Kim DefineInfo = UtLocalCalloc (sizeof (PR_DEFINE_INFO)); 1504c52cad2SJung-uk Kim DefineInfo->Replacement = ReplacementString; 1514c52cad2SJung-uk Kim DefineInfo->Identifier = IdentifierString; 1524c52cad2SJung-uk Kim DefineInfo->Persist = Persist; 1534c52cad2SJung-uk Kim 1544c52cad2SJung-uk Kim if (Gbl_DefineList) 1554c52cad2SJung-uk Kim { 1564c52cad2SJung-uk Kim Gbl_DefineList->Previous = DefineInfo; 1574c52cad2SJung-uk Kim } 1584c52cad2SJung-uk Kim 1594c52cad2SJung-uk Kim DefineInfo->Next = Gbl_DefineList; 1604c52cad2SJung-uk Kim Gbl_DefineList = DefineInfo; 1614c52cad2SJung-uk Kim return (DefineInfo); 1624c52cad2SJung-uk Kim } 1634c52cad2SJung-uk Kim 1644c52cad2SJung-uk Kim 1654c52cad2SJung-uk Kim /******************************************************************************* 1664c52cad2SJung-uk Kim * 1674c52cad2SJung-uk Kim * FUNCTION: PrRemoveDefine 1684c52cad2SJung-uk Kim * 1694c52cad2SJung-uk Kim * PARAMETERS: DefineName - Name of define to be removed 1704c52cad2SJung-uk Kim * 1714c52cad2SJung-uk Kim * RETURN: None 1724c52cad2SJung-uk Kim * 1734c52cad2SJung-uk Kim * DESCRIPTION: Implements #undef. Remove a #define if found in the global 1744c52cad2SJung-uk Kim * list. No error if the target of the #undef does not exist, 1754c52cad2SJung-uk Kim * as per the C #undef definition. 1764c52cad2SJung-uk Kim * 1774c52cad2SJung-uk Kim ******************************************************************************/ 1784c52cad2SJung-uk Kim 1794c52cad2SJung-uk Kim void 1804c52cad2SJung-uk Kim PrRemoveDefine ( 1814c52cad2SJung-uk Kim char *DefineName) 1824c52cad2SJung-uk Kim { 1834c52cad2SJung-uk Kim PR_DEFINE_INFO *DefineInfo; 1844c52cad2SJung-uk Kim 1854c52cad2SJung-uk Kim 1864c52cad2SJung-uk Kim /* Match name and delete the node */ 1874c52cad2SJung-uk Kim 1884c52cad2SJung-uk Kim DefineInfo = Gbl_DefineList; 1894c52cad2SJung-uk Kim while (DefineInfo) 1904c52cad2SJung-uk Kim { 1914c52cad2SJung-uk Kim if (!strcmp (DefineName, DefineInfo->Identifier)) 1924c52cad2SJung-uk Kim { 1934c52cad2SJung-uk Kim /* Remove from linked list */ 1944c52cad2SJung-uk Kim 1954c52cad2SJung-uk Kim if (DefineInfo->Previous) 1964c52cad2SJung-uk Kim { 1974c52cad2SJung-uk Kim (DefineInfo->Previous)->Next = DefineInfo->Next; 1984c52cad2SJung-uk Kim } 1994c52cad2SJung-uk Kim else 2004c52cad2SJung-uk Kim { 2014c52cad2SJung-uk Kim Gbl_DefineList = DefineInfo->Next; 2024c52cad2SJung-uk Kim } 2034c52cad2SJung-uk Kim 2044c52cad2SJung-uk Kim if (DefineInfo->Next) 2054c52cad2SJung-uk Kim { 2064c52cad2SJung-uk Kim (DefineInfo->Next)->Previous = DefineInfo->Previous; 2074c52cad2SJung-uk Kim } 2084c52cad2SJung-uk Kim 2094c52cad2SJung-uk Kim free (DefineInfo); 2104c52cad2SJung-uk Kim return; 2114c52cad2SJung-uk Kim } 2124c52cad2SJung-uk Kim 2134c52cad2SJung-uk Kim DefineInfo = DefineInfo->Next; 2144c52cad2SJung-uk Kim } 2154c52cad2SJung-uk Kim 2164c52cad2SJung-uk Kim /* 2174c52cad2SJung-uk Kim * Name was not found. By definition of #undef, this is not 2184c52cad2SJung-uk Kim * an error, however. 2194c52cad2SJung-uk Kim */ 2204c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 2214c52cad2SJung-uk Kim "#undef: could not find %s\n", 2224c52cad2SJung-uk Kim Gbl_CurrentLineNumber, DefineName); 2234c52cad2SJung-uk Kim } 2244c52cad2SJung-uk Kim 2254c52cad2SJung-uk Kim 2264c52cad2SJung-uk Kim /******************************************************************************* 2274c52cad2SJung-uk Kim * 2284c52cad2SJung-uk Kim * FUNCTION: PrMatchDefine 2294c52cad2SJung-uk Kim * 2304c52cad2SJung-uk Kim * PARAMETERS: MatchString - Name associated with the #define 2314c52cad2SJung-uk Kim * 2324c52cad2SJung-uk Kim * RETURN: Matched string if found. NULL otherwise. 2334c52cad2SJung-uk Kim * 2344c52cad2SJung-uk Kim * DESCRIPTION: Find a name in global #define list 2354c52cad2SJung-uk Kim * 2364c52cad2SJung-uk Kim ******************************************************************************/ 2374c52cad2SJung-uk Kim 2384c52cad2SJung-uk Kim PR_DEFINE_INFO * 2394c52cad2SJung-uk Kim PrMatchDefine ( 2404c52cad2SJung-uk Kim char *MatchString) 2414c52cad2SJung-uk Kim { 2424c52cad2SJung-uk Kim PR_DEFINE_INFO *DefineInfo; 2434c52cad2SJung-uk Kim 2444c52cad2SJung-uk Kim 2454c52cad2SJung-uk Kim DefineInfo = Gbl_DefineList; 2464c52cad2SJung-uk Kim while (DefineInfo) 2474c52cad2SJung-uk Kim { 2484c52cad2SJung-uk Kim if (!strcmp (MatchString, DefineInfo->Identifier)) 2494c52cad2SJung-uk Kim { 2504c52cad2SJung-uk Kim return (DefineInfo); 2514c52cad2SJung-uk Kim } 2524c52cad2SJung-uk Kim 2534c52cad2SJung-uk Kim DefineInfo = DefineInfo->Next; 2544c52cad2SJung-uk Kim } 2554c52cad2SJung-uk Kim 2564c52cad2SJung-uk Kim return (NULL); 2574c52cad2SJung-uk Kim } 2584c52cad2SJung-uk Kim 2594c52cad2SJung-uk Kim 2604c52cad2SJung-uk Kim /******************************************************************************* 2614c52cad2SJung-uk Kim * 2624c52cad2SJung-uk Kim * FUNCTION: PrAddMacro 2634c52cad2SJung-uk Kim * 2644c52cad2SJung-uk Kim * PARAMETERS: Name - Start of the macro definition 2654c52cad2SJung-uk Kim * Next - "Next" buffer from GetNextToken 2664c52cad2SJung-uk Kim * 2674c52cad2SJung-uk Kim * RETURN: None 2684c52cad2SJung-uk Kim * 2694c52cad2SJung-uk Kim * DESCRIPTION: Add a new macro to the list of #defines. Handles argument 2704c52cad2SJung-uk Kim * processing. 2714c52cad2SJung-uk Kim * 2724c52cad2SJung-uk Kim ******************************************************************************/ 2734c52cad2SJung-uk Kim 2744c52cad2SJung-uk Kim void 2754c52cad2SJung-uk Kim PrAddMacro ( 2764c52cad2SJung-uk Kim char *Name, 2774c52cad2SJung-uk Kim char **Next) 2784c52cad2SJung-uk Kim { 2794c52cad2SJung-uk Kim char *Token = NULL; 2804c52cad2SJung-uk Kim ACPI_SIZE TokenOffset; 2814c52cad2SJung-uk Kim ACPI_SIZE MacroBodyOffset; 2824c52cad2SJung-uk Kim PR_DEFINE_INFO *DefineInfo; 2834c52cad2SJung-uk Kim PR_MACRO_ARG *Args; 2844c52cad2SJung-uk Kim char *Body; 2854c52cad2SJung-uk Kim char *BodyInSource; 2864c52cad2SJung-uk Kim UINT32 i; 2874c52cad2SJung-uk Kim UINT16 UseCount = 0; 2884c52cad2SJung-uk Kim UINT16 ArgCount = 0; 2894c52cad2SJung-uk Kim UINT32 Depth = 1; 2904c52cad2SJung-uk Kim UINT32 EndOfArgList; 2914c52cad2SJung-uk Kim char BufferChar; 2924c52cad2SJung-uk Kim 2934c52cad2SJung-uk Kim 2944c52cad2SJung-uk Kim /* Find the end of the arguments list */ 2954c52cad2SJung-uk Kim 2964c52cad2SJung-uk Kim TokenOffset = Name - Gbl_MainTokenBuffer + strlen (Name) + 1; 2974c52cad2SJung-uk Kim while (1) 2984c52cad2SJung-uk Kim { 2994c52cad2SJung-uk Kim BufferChar = Gbl_CurrentLineBuffer[TokenOffset]; 3004c52cad2SJung-uk Kim if (BufferChar == '(') 3014c52cad2SJung-uk Kim { 3024c52cad2SJung-uk Kim Depth++; 3034c52cad2SJung-uk Kim } 3044c52cad2SJung-uk Kim else if (BufferChar == ')') 3054c52cad2SJung-uk Kim { 3064c52cad2SJung-uk Kim Depth--; 3074c52cad2SJung-uk Kim } 3084c52cad2SJung-uk Kim else if (BufferChar == 0) 3094c52cad2SJung-uk Kim { 3104c52cad2SJung-uk Kim PrError (ASL_ERROR, ASL_MSG_MACRO_SYNTAX, TokenOffset); 3114c52cad2SJung-uk Kim return; 3124c52cad2SJung-uk Kim } 3134c52cad2SJung-uk Kim 3144c52cad2SJung-uk Kim if (Depth == 0) 3154c52cad2SJung-uk Kim { 3164c52cad2SJung-uk Kim /* Found arg list end */ 3174c52cad2SJung-uk Kim 3184c52cad2SJung-uk Kim EndOfArgList = TokenOffset; 3194c52cad2SJung-uk Kim break; 3204c52cad2SJung-uk Kim } 3214c52cad2SJung-uk Kim 3224c52cad2SJung-uk Kim TokenOffset++; 3234c52cad2SJung-uk Kim } 3244c52cad2SJung-uk Kim 3254c52cad2SJung-uk Kim /* At this point, we know that we have a reasonable argument list */ 3264c52cad2SJung-uk Kim 3274c52cad2SJung-uk Kim Args = UtLocalCalloc (sizeof (PR_MACRO_ARG) * PR_MAX_MACRO_ARGS); 3284c52cad2SJung-uk Kim 3294c52cad2SJung-uk Kim /* Get the macro argument names */ 3304c52cad2SJung-uk Kim 3314c52cad2SJung-uk Kim for (i = 0; i < PR_MAX_MACRO_ARGS; i++) 3324c52cad2SJung-uk Kim { 3334c52cad2SJung-uk Kim Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); 3344c52cad2SJung-uk Kim if (!Token) 3354c52cad2SJung-uk Kim { 3364c52cad2SJung-uk Kim /* This is the case for a NULL macro body */ 3374c52cad2SJung-uk Kim 3384c52cad2SJung-uk Kim BodyInSource = ""; 3394c52cad2SJung-uk Kim goto AddMacroToList; 3404c52cad2SJung-uk Kim } 3414c52cad2SJung-uk Kim 3424c52cad2SJung-uk Kim /* Don't go beyond the argument list */ 3434c52cad2SJung-uk Kim 3444c52cad2SJung-uk Kim TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); 3454c52cad2SJung-uk Kim if (TokenOffset > EndOfArgList) 3464c52cad2SJung-uk Kim { 3474c52cad2SJung-uk Kim break; 3484c52cad2SJung-uk Kim } 3494c52cad2SJung-uk Kim 3504c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 3514c52cad2SJung-uk Kim "Macro arg: %s \n", 3524c52cad2SJung-uk Kim Gbl_CurrentLineNumber, Token); 3534c52cad2SJung-uk Kim 3544c52cad2SJung-uk Kim Args[i].Name = UtLocalCalloc (strlen (Token) + 1); 3554c52cad2SJung-uk Kim strcpy (Args[i].Name, Token); 3564c52cad2SJung-uk Kim 3574c52cad2SJung-uk Kim Args[i].UseCount = 0; 3584c52cad2SJung-uk Kim 3594c52cad2SJung-uk Kim ArgCount++; 3604c52cad2SJung-uk Kim if (ArgCount >= PR_MAX_MACRO_ARGS) 3614c52cad2SJung-uk Kim { 3624c52cad2SJung-uk Kim PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, TokenOffset); 363313a0c13SJung-uk Kim goto ErrorExit; 3644c52cad2SJung-uk Kim } 3654c52cad2SJung-uk Kim } 3664c52cad2SJung-uk Kim 3674c52cad2SJung-uk Kim /* Get the macro body. Token now points to start of body */ 3684c52cad2SJung-uk Kim 3694c52cad2SJung-uk Kim MacroBodyOffset = Token - Gbl_MainTokenBuffer; 3704c52cad2SJung-uk Kim 3714c52cad2SJung-uk Kim /* Match each method arg in the macro body for later use */ 3724c52cad2SJung-uk Kim 3734c52cad2SJung-uk Kim Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); 3744c52cad2SJung-uk Kim while (Token) 3754c52cad2SJung-uk Kim { 3764c52cad2SJung-uk Kim /* Search the macro arg list for matching arg */ 3774c52cad2SJung-uk Kim 3784c52cad2SJung-uk Kim for (i = 0; Args[i].Name && (i < PR_MAX_MACRO_ARGS); i++) 3794c52cad2SJung-uk Kim { 3804c52cad2SJung-uk Kim /* 3814c52cad2SJung-uk Kim * Save argument offset within macro body. This is the mechanism 3824c52cad2SJung-uk Kim * used to expand the macro upon invocation. 3834c52cad2SJung-uk Kim * 3844c52cad2SJung-uk Kim * Handles multiple instances of the same argument 3854c52cad2SJung-uk Kim */ 3864c52cad2SJung-uk Kim if (!strcmp (Token, Args[i].Name)) 3874c52cad2SJung-uk Kim { 3884c52cad2SJung-uk Kim UseCount = Args[i].UseCount; 3894c52cad2SJung-uk Kim 390*f8146b88SJung-uk Kim Args[i].Offset[UseCount] = 391*f8146b88SJung-uk Kim (Token - Gbl_MainTokenBuffer) - MacroBodyOffset; 3924c52cad2SJung-uk Kim 3934c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 3944c52cad2SJung-uk Kim "Macro Arg #%u: %s UseCount %u Offset %u \n", 3954c52cad2SJung-uk Kim Gbl_CurrentLineNumber, i, Token, 3964c52cad2SJung-uk Kim UseCount+1, Args[i].Offset[UseCount]); 3974c52cad2SJung-uk Kim 3984c52cad2SJung-uk Kim Args[i].UseCount++; 3994c52cad2SJung-uk Kim if (Args[i].UseCount >= PR_MAX_ARG_INSTANCES) 4004c52cad2SJung-uk Kim { 4014c52cad2SJung-uk Kim PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, 4024c52cad2SJung-uk Kim THIS_TOKEN_OFFSET (Token)); 4034c52cad2SJung-uk Kim 404313a0c13SJung-uk Kim goto ErrorExit; 4054c52cad2SJung-uk Kim } 4064c52cad2SJung-uk Kim break; 4074c52cad2SJung-uk Kim } 4084c52cad2SJung-uk Kim } 4094c52cad2SJung-uk Kim 4104c52cad2SJung-uk Kim Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); 4114c52cad2SJung-uk Kim } 4124c52cad2SJung-uk Kim 4134c52cad2SJung-uk Kim BodyInSource = &Gbl_CurrentLineBuffer[MacroBodyOffset]; 4144c52cad2SJung-uk Kim 4154c52cad2SJung-uk Kim 4164c52cad2SJung-uk Kim AddMacroToList: 4174c52cad2SJung-uk Kim 4184c52cad2SJung-uk Kim /* Check if name is already defined first */ 4194c52cad2SJung-uk Kim 4204c52cad2SJung-uk Kim DefineInfo = PrMatchDefine (Name); 4214c52cad2SJung-uk Kim if (DefineInfo) 4224c52cad2SJung-uk Kim { 4234c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 4244c52cad2SJung-uk Kim "#define: macro name already exists: %s\n", 4254c52cad2SJung-uk Kim Gbl_CurrentLineNumber, Name); 4264c52cad2SJung-uk Kim 4274c52cad2SJung-uk Kim /* Error only if not exactly the same macro */ 4284c52cad2SJung-uk Kim 4294c52cad2SJung-uk Kim if (strcmp (DefineInfo->Body, BodyInSource) || 4304c52cad2SJung-uk Kim (DefineInfo->ArgCount != ArgCount)) 4314c52cad2SJung-uk Kim { 4324c52cad2SJung-uk Kim PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME, 4334c52cad2SJung-uk Kim THIS_TOKEN_OFFSET (Name)); 4344c52cad2SJung-uk Kim } 4354c52cad2SJung-uk Kim 436313a0c13SJung-uk Kim goto ErrorExit; 4374c52cad2SJung-uk Kim } 4384c52cad2SJung-uk Kim 4394c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 4404c52cad2SJung-uk Kim "Macro body: %s \n", 4414c52cad2SJung-uk Kim Gbl_CurrentLineNumber, BodyInSource); 4424c52cad2SJung-uk Kim 4434c52cad2SJung-uk Kim /* Add macro to the #define list */ 4444c52cad2SJung-uk Kim 4454c52cad2SJung-uk Kim DefineInfo = PrAddDefine (Name, BodyInSource, FALSE); 4464c52cad2SJung-uk Kim if (DefineInfo) 4474c52cad2SJung-uk Kim { 4484c52cad2SJung-uk Kim Body = UtLocalCalloc (strlen (BodyInSource) + 1); 4494c52cad2SJung-uk Kim strcpy (Body, BodyInSource); 4504c52cad2SJung-uk Kim 4514c52cad2SJung-uk Kim DefineInfo->Body = Body; 4524c52cad2SJung-uk Kim DefineInfo->Args = Args; 4534c52cad2SJung-uk Kim DefineInfo->ArgCount = ArgCount; 4544c52cad2SJung-uk Kim } 455313a0c13SJung-uk Kim 456313a0c13SJung-uk Kim return; 457313a0c13SJung-uk Kim 458313a0c13SJung-uk Kim 459313a0c13SJung-uk Kim ErrorExit: 460313a0c13SJung-uk Kim ACPI_FREE (Args); 461313a0c13SJung-uk Kim return; 4624c52cad2SJung-uk Kim } 4634c52cad2SJung-uk Kim 4644c52cad2SJung-uk Kim 4654c52cad2SJung-uk Kim /******************************************************************************* 4664c52cad2SJung-uk Kim * 4674c52cad2SJung-uk Kim * FUNCTION: PrDoMacroInvocation 4684c52cad2SJung-uk Kim * 4694c52cad2SJung-uk Kim * PARAMETERS: TokenBuffer - Current line buffer 4704c52cad2SJung-uk Kim * MacroStart - Start of the macro invocation within 4714c52cad2SJung-uk Kim * the token buffer 4724c52cad2SJung-uk Kim * DefineInfo - Info for this macro 4734c52cad2SJung-uk Kim * Next - "Next" buffer from GetNextToken 4744c52cad2SJung-uk Kim * 4754c52cad2SJung-uk Kim * RETURN: None 4764c52cad2SJung-uk Kim * 4774c52cad2SJung-uk Kim * DESCRIPTION: Expand a macro invocation 4784c52cad2SJung-uk Kim * 4794c52cad2SJung-uk Kim ******************************************************************************/ 4804c52cad2SJung-uk Kim 4814c52cad2SJung-uk Kim void 4824c52cad2SJung-uk Kim PrDoMacroInvocation ( 4834c52cad2SJung-uk Kim char *TokenBuffer, 4844c52cad2SJung-uk Kim char *MacroStart, 4854c52cad2SJung-uk Kim PR_DEFINE_INFO *DefineInfo, 4864c52cad2SJung-uk Kim char **Next) 4874c52cad2SJung-uk Kim { 4884c52cad2SJung-uk Kim PR_MACRO_ARG *Args; 4894c52cad2SJung-uk Kim char *Token = NULL; 4904c52cad2SJung-uk Kim UINT32 TokenOffset; 4914c52cad2SJung-uk Kim UINT32 Length; 4924c52cad2SJung-uk Kim UINT32 i; 4934c52cad2SJung-uk Kim 4944c52cad2SJung-uk Kim 4954c52cad2SJung-uk Kim /* Take a copy of the macro body for expansion */ 4964c52cad2SJung-uk Kim 4974c52cad2SJung-uk Kim strcpy (Gbl_MacroTokenBuffer, DefineInfo->Body); 4984c52cad2SJung-uk Kim 4994c52cad2SJung-uk Kim /* Replace each argument within the prototype body */ 5004c52cad2SJung-uk Kim 5014c52cad2SJung-uk Kim Args = DefineInfo->Args; 5024c52cad2SJung-uk Kim if (!Args->Name) 5034c52cad2SJung-uk Kim { 5044c52cad2SJung-uk Kim /* This macro has no arguments */ 5054c52cad2SJung-uk Kim 5064c52cad2SJung-uk Kim Token = PrGetNextToken (NULL, PR_MACRO_ARGUMENTS, Next); 5074c52cad2SJung-uk Kim if (!Token) 5084c52cad2SJung-uk Kim { 5094c52cad2SJung-uk Kim goto BadInvocation; 5104c52cad2SJung-uk Kim } 5114c52cad2SJung-uk Kim 5124c52cad2SJung-uk Kim TokenOffset = (MacroStart - TokenBuffer); 5134c52cad2SJung-uk Kim Length = Token - MacroStart + strlen (Token) + 1; 5144c52cad2SJung-uk Kim 5154c52cad2SJung-uk Kim PrReplaceData ( 5164c52cad2SJung-uk Kim &Gbl_CurrentLineBuffer[TokenOffset], Length, 5174c52cad2SJung-uk Kim Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer)); 5184c52cad2SJung-uk Kim return; 5194c52cad2SJung-uk Kim } 5204c52cad2SJung-uk Kim 5214c52cad2SJung-uk Kim while (Args->Name) 5224c52cad2SJung-uk Kim { 5234c52cad2SJung-uk Kim /* Get the next argument from macro invocation */ 5244c52cad2SJung-uk Kim 5254c52cad2SJung-uk Kim Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); 5264c52cad2SJung-uk Kim if (!Token) 5274c52cad2SJung-uk Kim { 5284c52cad2SJung-uk Kim goto BadInvocation; 5294c52cad2SJung-uk Kim } 5304c52cad2SJung-uk Kim 5314c52cad2SJung-uk Kim /* Replace all instances of this argument */ 5324c52cad2SJung-uk Kim 5334c52cad2SJung-uk Kim for (i = 0; i < Args->UseCount; i++) 5344c52cad2SJung-uk Kim { 5354c52cad2SJung-uk Kim /* Offset zero indicates "arg not used" */ 5364c52cad2SJung-uk Kim /* TBD: Not really needed now, with UseCount available */ 5374c52cad2SJung-uk Kim 5384c52cad2SJung-uk Kim if (Args->Offset[i] == 0) 5394c52cad2SJung-uk Kim { 5404c52cad2SJung-uk Kim break; 5414c52cad2SJung-uk Kim } 5424c52cad2SJung-uk Kim 5434c52cad2SJung-uk Kim PrReplaceData ( 5444c52cad2SJung-uk Kim &Gbl_MacroTokenBuffer[Args->Offset[i]], strlen (Args->Name), 5454c52cad2SJung-uk Kim Token, strlen (Token)); 5464c52cad2SJung-uk Kim 5474c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 5484c52cad2SJung-uk Kim "ExpandArg: %s \n", 5494c52cad2SJung-uk Kim Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer); 5504c52cad2SJung-uk Kim } 5514c52cad2SJung-uk Kim 5524c52cad2SJung-uk Kim Args++; 5534c52cad2SJung-uk Kim } 5544c52cad2SJung-uk Kim 5554c52cad2SJung-uk Kim /* TBD: need to make sure macro was not invoked with too many arguments */ 5564c52cad2SJung-uk Kim 5574c52cad2SJung-uk Kim if (!Token) 5584c52cad2SJung-uk Kim { 5594c52cad2SJung-uk Kim return; 5604c52cad2SJung-uk Kim } 5614c52cad2SJung-uk Kim 5624c52cad2SJung-uk Kim /* Replace the entire macro invocation with the expanded macro */ 5634c52cad2SJung-uk Kim 5644c52cad2SJung-uk Kim TokenOffset = (MacroStart - TokenBuffer); 5654c52cad2SJung-uk Kim Length = Token - MacroStart + strlen (Token) + 1; 5664c52cad2SJung-uk Kim 5674c52cad2SJung-uk Kim PrReplaceData ( 5684c52cad2SJung-uk Kim &Gbl_CurrentLineBuffer[TokenOffset], Length, 5694c52cad2SJung-uk Kim Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer)); 5704c52cad2SJung-uk Kim 5714c52cad2SJung-uk Kim return; 5724c52cad2SJung-uk Kim 5734c52cad2SJung-uk Kim 5744c52cad2SJung-uk Kim BadInvocation: 5754c52cad2SJung-uk Kim PrError (ASL_ERROR, ASL_MSG_INVALID_INVOCATION, 5764c52cad2SJung-uk Kim THIS_TOKEN_OFFSET (MacroStart)); 5774c52cad2SJung-uk Kim 5784c52cad2SJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 5794c52cad2SJung-uk Kim "Bad macro invocation: %s \n", 5804c52cad2SJung-uk Kim Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer); 5814c52cad2SJung-uk Kim return; 5824c52cad2SJung-uk Kim } 583