xref: /freebsd/sys/contrib/dev/acpica/compiler/prmacros.c (revision f8146b882bc156c1d8ddf14bbea67253ebc064bb)
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