xref: /freebsd/sys/contrib/dev/acpica/compiler/prmacros.c (revision 59c8e88e72633afbc47a4ace0d2170d00d51f7dc)
1 /******************************************************************************
2  *
3  * Module Name: prmacros - Preprocessor #define macro support
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
153 
154 #define _COMPONENT          ASL_PREPROCESSOR
155         ACPI_MODULE_NAME    ("prmacros")
156 
157 
158 /*******************************************************************************
159  *
160  * FUNCTION:    PrDumpPredefinedNames
161  *
162  * PARAMETERS:  None
163  *
164  * RETURN:      None
165  *
166  * DESCRIPTION: Dump the list of #defines. Used as the preprocessor starts, to
167  *              display the names that were defined on the command line.
168  *              Debug information only.
169  *
170  ******************************************************************************/
171 
172 void
173 PrDumpPredefinedNames (
174     void)
175 {
176     PR_DEFINE_INFO          *DefineInfo;
177 
178 
179     DefineInfo = AslGbl_DefineList;
180     while (DefineInfo)
181     {
182         DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
183             "Predefined #define: %s->%s\n",
184             0, DefineInfo->Identifier, DefineInfo->Replacement);
185 
186         DefineInfo = DefineInfo->Next;
187     }
188 }
189 
190 
191 /*******************************************************************************
192  *
193  * FUNCTION:    PrAddDefine
194  *
195  * PARAMETERS:  Identifier          - Name to be replaced
196  *              Replacement         - Replacement for Identifier
197  *              Persist             - Keep define across multiple compiles?
198  *
199  * RETURN:      A new define_info struct. NULL on error.
200  *
201  * DESCRIPTION: Add a new #define to the global list
202  *
203  ******************************************************************************/
204 
205 PR_DEFINE_INFO *
206 PrAddDefine (
207     char                    *Identifier,
208     char                    *Replacement,
209     BOOLEAN                 Persist)
210 {
211     char                    *IdentifierString;
212     char                    *ReplacementString;
213     PR_DEFINE_INFO          *DefineInfo;
214 
215 
216     if (!Replacement)
217     {
218         Replacement = "";
219     }
220 
221     /* Check for already-defined first */
222 
223     DefineInfo = PrMatchDefine (Identifier);
224     if (DefineInfo)
225     {
226         DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
227             "#define: name already exists: %s\n",
228             AslGbl_CurrentLineNumber, Identifier);
229 
230         /*
231          * Name already exists. This is only an error if the target name
232          * is different.
233          */
234         if (strcmp (Replacement, DefineInfo->Replacement))
235         {
236             PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME,
237                 THIS_TOKEN_OFFSET (Identifier));
238 
239             return (NULL);
240         }
241 
242         return (DefineInfo);
243     }
244 
245     /* Copy input strings */
246 
247     IdentifierString = UtLocalCalloc (strlen (Identifier) + 1);
248     strcpy (IdentifierString, Identifier);
249 
250     ReplacementString = UtLocalCalloc (strlen (Replacement) + 1);
251     strcpy (ReplacementString, Replacement);
252 
253     /* Init and link new define info struct */
254 
255     DefineInfo = UtLocalCalloc (sizeof (PR_DEFINE_INFO));
256     DefineInfo->Replacement = ReplacementString;
257     DefineInfo->Identifier = IdentifierString;
258     DefineInfo->Persist = Persist;
259 
260     if (AslGbl_DefineList)
261     {
262         AslGbl_DefineList->Previous = DefineInfo;
263     }
264 
265     DefineInfo->Next = AslGbl_DefineList;
266     AslGbl_DefineList = DefineInfo;
267     return (DefineInfo);
268 }
269 
270 
271 /*******************************************************************************
272  *
273  * FUNCTION:    PrRemoveDefine
274  *
275  * PARAMETERS:  DefineName          - Name of define to be removed
276  *
277  * RETURN:      None
278  *
279  * DESCRIPTION: Implements #undef. Remove a #define if found in the global
280  *              list. No error if the target of the #undef does not exist,
281  *              as per the C #undef definition.
282  *
283  ******************************************************************************/
284 
285 void
286 PrRemoveDefine (
287     char                    *DefineName)
288 {
289     PR_DEFINE_INFO          *DefineInfo;
290 
291 
292     /* Match name and delete the node */
293 
294     DefineInfo = AslGbl_DefineList;
295     while (DefineInfo)
296     {
297         if (!strcmp (DefineName, DefineInfo->Identifier))
298         {
299             /* Remove from linked list */
300 
301             if (DefineInfo->Previous)
302             {
303                 (DefineInfo->Previous)->Next = DefineInfo->Next;
304             }
305             else
306             {
307                 AslGbl_DefineList = DefineInfo->Next;
308             }
309 
310             if (DefineInfo->Next)
311             {
312                 (DefineInfo->Next)->Previous = DefineInfo->Previous;
313             }
314 
315             free (DefineInfo);
316             return;
317         }
318 
319         DefineInfo = DefineInfo->Next;
320     }
321 
322     /*
323      * Name was not found. By definition of #undef, this is not
324      * an error, however.
325      */
326     DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
327         "#undef: could not find %s\n",
328         AslGbl_CurrentLineNumber, DefineName);
329 }
330 
331 
332 /*******************************************************************************
333  *
334  * FUNCTION:    PrMatchDefine
335  *
336  * PARAMETERS:  MatchString         - Name associated with the #define
337  *
338  * RETURN:      Matched string if found. NULL otherwise.
339  *
340  * DESCRIPTION: Find a name in global #define list
341  *
342  ******************************************************************************/
343 
344 PR_DEFINE_INFO *
345 PrMatchDefine (
346     char                    *MatchString)
347 {
348     PR_DEFINE_INFO          *DefineInfo;
349 
350 
351     DefineInfo = AslGbl_DefineList;
352     while (DefineInfo)
353     {
354         if (!strcmp (MatchString, DefineInfo->Identifier))
355         {
356             return (DefineInfo);
357         }
358 
359         DefineInfo = DefineInfo->Next;
360     }
361 
362     return (NULL);
363 }
364 
365 
366 /*******************************************************************************
367  *
368  * FUNCTION:    PrAddMacro
369  *
370  * PARAMETERS:  Name                - Start of the macro definition
371  *              Next                - "Next" buffer from GetNextToken
372  *
373  * RETURN:      None
374  *
375  * DESCRIPTION: Add a new macro to the list of #defines. Handles argument
376  *              processing.
377  *
378  ******************************************************************************/
379 
380 void
381 PrAddMacro (
382     char                    *Name,
383     char                    **Next)
384 {
385     char                    *Token = NULL;
386     ACPI_SIZE               TokenOffset;
387     ACPI_SIZE               MacroBodyOffset;
388     PR_DEFINE_INFO          *DefineInfo;
389     PR_MACRO_ARG            *Args;
390     char                    *Body;
391     char                    *BodyInSource;
392     UINT32                  i;
393     UINT16                  UseCount = 0;
394     UINT16                  ArgCount = 0;
395     UINT32                  Depth = 1;
396     /*UINT32                  Depth = 1;*/
397     UINT32                  EndOfArgList;
398     char                    BufferChar;
399 
400     /* Find the end of the arguments list */
401 
402     TokenOffset = Name - AslGbl_MainTokenBuffer + strlen (Name) + 1;
403     while (1)
404     {
405         BufferChar = AslGbl_CurrentLineBuffer[TokenOffset];
406         if (BufferChar == '(')
407         {
408             Depth++;
409         }
410         else if (BufferChar == ')')
411         {
412             Depth--;
413         }
414         else if (BufferChar == 0)
415         {
416             PrError (ASL_ERROR, ASL_MSG_MACRO_SYNTAX, TokenOffset);
417             return;
418         }
419 
420         if (Depth == 0)
421         {
422             /* Found arg list end */
423 
424             EndOfArgList = TokenOffset;
425             break;
426         }
427 
428         TokenOffset++;
429     }
430 
431     /* At this point, we know that we have a reasonable argument list */
432 
433     Args = UtLocalCalloc (sizeof (PR_MACRO_ARG) * PR_MAX_MACRO_ARGS);
434 
435     /* Get the macro argument names */
436 
437     for (i = 0; i < PR_MAX_MACRO_ARGS; i++)
438     {
439         Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next);
440 
441         if (!Token)
442         {
443             /* This is the case for a NULL macro body */
444 
445             BodyInSource = "";
446             goto AddMacroToList;
447         }
448 
449         /* Don't go beyond the argument list */
450 
451         TokenOffset = Token - AslGbl_MainTokenBuffer + strlen (Token);
452         if (TokenOffset > EndOfArgList)
453         {
454             break;
455         }
456 
457         DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
458             "Macro param: %s \n",
459             AslGbl_CurrentLineNumber, Token);
460 
461         Args[i].Name = UtLocalCalloc (strlen (Token) + 1);
462         strcpy (Args[i].Name, Token);
463 
464         Args[i].UseCount = 0;
465         ArgCount++;
466         if (ArgCount >= PR_MAX_MACRO_ARGS)
467         {
468             PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, TokenOffset);
469             goto ErrorExit;
470         }
471     }
472 
473     /* Get the macro body. Token now points to start of body */
474 
475     MacroBodyOffset = Token - AslGbl_MainTokenBuffer;
476 
477     /* Match each method arg in the macro body for later use */
478 
479     while (Token)
480     {
481         /* Search the macro arg list for matching arg */
482 
483         for (i = 0; ((i < PR_MAX_MACRO_ARGS) && Args[i].Name); i++)
484         {
485             /*
486              * Save argument offset within macro body. This is the mechanism
487              * used to expand the macro upon invocation.
488              *
489              * Handles multiple instances of the same argument
490              */
491             if (!strcmp (Token, Args[i].Name))
492             {
493                 UseCount = Args[i].UseCount;
494 
495                 Args[i].Offset[UseCount] =
496                     (Token - AslGbl_MainTokenBuffer) - MacroBodyOffset;
497 
498 
499                 DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
500                     "Macro Arg #%u: %s UseCount %u Offset %u \n",
501                     AslGbl_CurrentLineNumber, i, Token,
502                     UseCount+1, Args[i].Offset[UseCount]);
503 
504                 Args[i].UseCount++;
505 
506                 if (Args[i].UseCount >= PR_MAX_ARG_INSTANCES)
507                 {
508                     PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS,
509                         THIS_TOKEN_OFFSET (Token));
510 
511                     goto ErrorExit;
512                 }
513                 break;
514             }
515         }
516 
517         Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next);
518     }
519 
520     BodyInSource = &AslGbl_CurrentLineBuffer[MacroBodyOffset];
521 
522 
523 AddMacroToList:
524 
525     /* Check if name is already defined first */
526 
527     DefineInfo = PrMatchDefine (Name);
528     if (DefineInfo)
529     {
530         DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
531             "#define: macro name already exists: %s\n",
532             AslGbl_CurrentLineNumber, Name);
533 
534         /* Error only if not exactly the same macro */
535 
536         if (strcmp (DefineInfo->Body, BodyInSource) ||
537             (DefineInfo->ArgCount != ArgCount))
538         {
539             PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME,
540                 THIS_TOKEN_OFFSET (Name));
541         }
542 
543         goto ErrorExit;
544     }
545 
546     DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
547         "Macro body: %s \n",
548         AslGbl_CurrentLineNumber, BodyInSource);
549 
550     /* Add macro to the #define list */
551 
552     DefineInfo = PrAddDefine (Name, BodyInSource, FALSE);
553     if (DefineInfo)
554     {
555         Body = UtLocalCalloc (strlen (BodyInSource) + 1);
556         strcpy (Body, BodyInSource);
557 
558         DefineInfo->Body = Body;
559         DefineInfo->Args = Args;
560         DefineInfo->ArgCount = ArgCount;
561     }
562 
563     return;
564 
565 
566 ErrorExit:
567     ACPI_FREE (Args);
568     return;
569 }
570 
571 
572 /*******************************************************************************
573  *
574  * FUNCTION:    PrDoMacroInvocation
575  *
576  * PARAMETERS:  TokenBuffer         - Current line buffer
577  *              MacroStart          - Start of the macro invocation within
578  *                                    the token buffer
579  *              DefineInfo          - Info for this macro
580  *              Next                - "Next" buffer from GetNextToken
581  *
582  * RETURN:      None
583  *
584  * DESCRIPTION: Expand a macro invocation
585  *
586  ******************************************************************************/
587 
588 void
589 PrDoMacroInvocation (
590     char                    *TokenBuffer,
591     char                    *MacroStart,
592     PR_DEFINE_INFO          *DefineInfo,
593     char                    **Next)
594 {
595     PR_MACRO_ARG            *Args;
596     char                    *Token = NULL;
597     UINT32                  TokenOffset;
598     UINT32                  Length;
599     UINT32                  i;
600     UINT32                  Diff1;
601     UINT32                  Diff2;
602 
603     /* Take a copy of the macro body for expansion */
604 
605     strcpy (AslGbl_MacroTokenBuffer, DefineInfo->Body);
606 
607     /* Replace each argument within the prototype body */
608 
609     Args = DefineInfo->Args;
610     if (!Args->Name)
611     {
612         /* This macro has no arguments */
613 
614         Token = PrGetNextToken (NULL, PR_MACRO_ARGUMENTS, Next);
615 
616         if (!Token)
617         {
618             goto BadInvocation;
619         }
620 
621         TokenOffset = (MacroStart - TokenBuffer);
622         Length = Token - MacroStart + strlen (Token) + 1;
623 
624         PrReplaceData (
625             &AslGbl_CurrentLineBuffer[TokenOffset], Length,
626             AslGbl_MacroTokenBuffer, strlen (AslGbl_MacroTokenBuffer));
627         return;
628     }
629 
630     while (Args->Name)
631     {
632         /* Get the next argument from macro invocation */
633 
634         Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next);
635         if (!Token)
636         {
637             goto BadInvocation;
638         }
639 
640         /*
641          * Avoid optimizing using just 1 signed int due to specific
642          * non-portable implementations of signed ints
643          */
644         Diff1 = strlen (Args->Name) > strlen (Token) ? strlen (Args->Name) -
645             strlen (Token) : 0;
646 
647         Diff2 = strlen (Args->Name) < strlen (Token) ? strlen (Token) -
648             strlen (Args->Name) : 0;
649 
650         /* Replace all instances of this argument */
651 
652         for (i = 0; i < Args->UseCount; i++)
653         {
654             /*
655              * To test the output of the preprocessed macro function that
656              * is passed to the compiler
657              */
658 
659              /*
660               * fprintf (stderr, "Current token = %s \t Current arg_name = %s \
661               * \t strlen (Token) = %u \t strlen (Args->Name) = %u \t Offset = %u \
662               * \t UseCount = %u \t", Token, Args->Name, strlen (Token), \
663               *     strlen (Args->Name), Args->Offset[i], Args->UseCount);
664               */
665 
666             AslGbl_MacroTokenReplaceBuffer = (char *) calloc ((strlen (AslGbl_MacroTokenBuffer)), sizeof (char));
667 
668             PrReplaceResizeSubstring (Args, Diff1, Diff2, i, Token);
669 
670             DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
671                 "ExpandArg: %s \n",
672                 AslGbl_CurrentLineNumber, AslGbl_MacroTokenBuffer);
673         }
674 
675         Args++;
676     }
677 
678     if (!Token)
679     {
680         return;
681     }
682 
683     /* Replace the entire macro invocation with the expanded macro */
684 
685     TokenOffset = (MacroStart - TokenBuffer);
686     Length = Token - MacroStart + strlen (Token) + 1;
687 
688     PrReplaceData (
689         &AslGbl_CurrentLineBuffer[TokenOffset], Length,
690         AslGbl_MacroTokenBuffer, strlen (AslGbl_MacroTokenBuffer));
691 
692     return;
693 
694 BadInvocation:
695     PrError (ASL_ERROR, ASL_MSG_INVALID_INVOCATION,
696         THIS_TOKEN_OFFSET (MacroStart));
697 
698     DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
699         "Bad macro invocation: %s \n",
700         AslGbl_CurrentLineNumber, AslGbl_MacroTokenBuffer);
701     return;
702 }
703