static char * PrExpandMacros ( char *Line) { char *Token; char *ReplaceString; PR_DEFINE_INFO *DefineInfo; ACPI_SIZE TokenOffset; char *Next; int OffsetAdjust; strcpy (Gbl_ExpressionTokenBuffer, Gbl_CurrentLineBuffer); Token = PrGetNextToken (Gbl_ExpressionTokenBuffer, PR_EXPR_SEPARATORS, &Next); OffsetAdjust = 0; while (Token) { DefineInfo = PrMatchDefine (Token); if (DefineInfo) { if (DefineInfo->Body) { /* This is a macro. TBD: Is this allowed? */ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Matched Macro: %s->%s\n", Gbl_CurrentLineNumber, DefineInfo->Identifier, DefineInfo->Replacement); PrDoMacroInvocation (Gbl_ExpressionTokenBuffer, Token, DefineInfo, &Next); } else { ReplaceString = DefineInfo->Replacement; /* Replace the name in the original line buffer */ TokenOffset = Token - Gbl_ExpressionTokenBuffer + OffsetAdjust; PrReplaceData ( &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), ReplaceString, strlen (ReplaceString)); /* Adjust for length difference between old and new name length */ OffsetAdjust += strlen (ReplaceString) - strlen (Token); DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Matched #define within expression: %s->%s\n", Gbl_CurrentLineNumber, Token, *ReplaceString ? ReplaceString : "(NULL STRING)"); } } Token = PrGetNextToken (NULL, PR_EXPR_SEPARATORS, &Next); } return (Line); }
void PrDoMacroInvocation ( char *TokenBuffer, char *MacroStart, PR_DEFINE_INFO *DefineInfo, char **Next) { PR_MACRO_ARG *Args; char *Token = NULL; UINT32 TokenOffset; UINT32 Length; UINT32 i; /* Take a copy of the macro body for expansion */ strcpy (Gbl_MacroTokenBuffer, DefineInfo->Body); /* Replace each argument within the prototype body */ Args = DefineInfo->Args; if (!Args->Name) { /* This macro has no arguments */ Token = PrGetNextToken (NULL, PR_MACRO_ARGUMENTS, Next); if (!Token) { goto BadInvocation; } TokenOffset = (MacroStart - TokenBuffer); Length = Token - MacroStart + strlen (Token) + 1; PrReplaceData ( &Gbl_CurrentLineBuffer[TokenOffset], Length, Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer)); return; } while (Args->Name) { /* Get the next argument from macro invocation */ Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); if (!Token) { goto BadInvocation; } /* Replace all instances of this argument */ for (i = 0; i < Args->UseCount; i++) { /* Offset zero indicates "arg not used" */ /* TBD: Not really needed now, with UseCount available */ if (Args->Offset[i] == 0) { break; } PrReplaceData ( &Gbl_MacroTokenBuffer[Args->Offset[i]], strlen (Args->Name), Token, strlen (Token)); DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "ExpandArg: %s \n", Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer); } Args++; } /* TBD: need to make sure macro was not invoked with too many arguments */ if (!Token) { return; } /* Replace the entire macro invocation with the expanded macro */ TokenOffset = (MacroStart - TokenBuffer); Length = Token - MacroStart + strlen (Token) + 1; PrReplaceData ( &Gbl_CurrentLineBuffer[TokenOffset], Length, Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer)); return; BadInvocation: PrError (ASL_ERROR, ASL_MSG_INVALID_INVOCATION, THIS_TOKEN_OFFSET (MacroStart)); DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Bad macro invocation: %s \n", Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer); return; }
static void PrPreprocessInputFile ( void) { UINT32 Status; char *Token; char *ReplaceString; PR_DEFINE_INFO *DefineInfo; ACPI_SIZE TokenOffset; char *Next; int OffsetAdjust; PrGetNextLineInit (); /* Scan source line-by-line and process directives. Then write the .i file */ while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) { Gbl_CurrentLineNumber++; Gbl_LogicalLineNumber++; if (Status == ASL_IGNORE_LINE) { goto WriteEntireLine; } /* Need a copy of the input line for strok() */ strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next); OffsetAdjust = 0; /* All preprocessor directives must begin with '#' */ if (Token && (*Token == '#')) { if (strlen (Token) == 1) { Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); } else { Token++; /* Skip leading # */ } /* Execute the directive, do not write line to output file */ PrDoDirective (Token, &Next); continue; } /* * If we are currently within the part of an IF/ELSE block that is * FALSE, ignore the line and do not write it to the output file. * This continues until an #else or #endif is encountered. */ if (Gbl_IgnoringThisCodeBlock) { continue; } /* Match and replace all #defined names within this source line */ while (Token) { DefineInfo = PrMatchDefine (Token); if (DefineInfo) { if (DefineInfo->Body) { /* This is a macro */ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Matched Macro: %s->%s\n", Gbl_CurrentLineNumber, DefineInfo->Identifier, DefineInfo->Replacement); PrDoMacroInvocation (Gbl_MainTokenBuffer, Token, DefineInfo, &Next); } else { ReplaceString = DefineInfo->Replacement; /* Replace the name in the original line buffer */ TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust; PrReplaceData ( &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), ReplaceString, strlen (ReplaceString)); /* Adjust for length difference between old and new name length */ OffsetAdjust += strlen (ReplaceString) - strlen (Token); DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Matched #define: %s->%s\n", Gbl_CurrentLineNumber, Token, *ReplaceString ? ReplaceString : "(NULL STRING)"); } } Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); } Gbl_PreprocessorLineNumber++; WriteEntireLine: /* * Now we can write the possibly modified source line to the * preprocessor file(s). */ FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, strlen (Gbl_CurrentLineBuffer)); } }
static void PrPreprocessInputFile ( void) { UINT32 Offset; char *Token; char *ReplaceString; PR_DEFINE_INFO *DefineInfo; ACPI_SIZE TokenOffset; BOOLEAN IgnoringThisCodeBlock = FALSE; char *Next; int OffsetAdjust; /* Scan line-by-line. Comments and blank lines are skipped by this function */ while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) { /* Need a copy of the input line for strok() */ strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next); OffsetAdjust = 0; /* All preprocessor directives must begin with '#' */ if (Token && (*Token == '#')) { if (strlen (Token) == 1) { Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); } else { Token++; /* Skip leading # */ } /* Execute the directive, do not write line to output file */ PrDoDirective (Token, &Next, &IgnoringThisCodeBlock); continue; } /* * If we are currently within the part of an IF/ELSE block that is * FALSE, ignore the line and do not write it to the output file. * This continues until an #else or #endif is encountered. */ if (IgnoringThisCodeBlock == TRUE) { continue; } /* Match and replace all #defined names within this source line */ while (Token) { DefineInfo = PrMatchDefine (Token); if (DefineInfo) { if (DefineInfo->Body) { /* This is a macro */ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Matched Macro: %s->%s\n", Gbl_CurrentLineNumber, DefineInfo->Identifier, DefineInfo->Replacement); PrDoMacroInvocation (Gbl_MainTokenBuffer, Token, DefineInfo, &Next); } else { ReplaceString = DefineInfo->Replacement; /* Replace the name in the original line buffer */ TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust; PrReplaceData ( &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), ReplaceString, strlen (ReplaceString)); /* Adjust for length difference between old and new name length */ OffsetAdjust += strlen (ReplaceString) - strlen (Token); DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Matched #define: %s->%s\n", Gbl_CurrentLineNumber, Token, *ReplaceString ? ReplaceString : "(NULL STRING)"); } } Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); } #if 0 /* Line prefix */ FlPrintFile (ASL_FILE_PREPROCESSOR, "/* %14s %.5u i:%.5u */ ", Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber); #endif /* * Emit a #line directive if necessary, to keep the line numbers in * the (.i) file synchronized with the original source code file, so * that the correct line number appears in any error messages * generated by the actual compiler. */ if (Gbl_CurrentLineNumber > (Gbl_PreviousLineNumber + 1)) { FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u\n", Gbl_CurrentLineNumber); } Gbl_PreviousLineNumber = Gbl_CurrentLineNumber; Gbl_PreprocessorLineNumber++; /* * Now we can write the possibly modified source line to the * preprocessor (.i) file */ FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, strlen (Gbl_CurrentLineBuffer)); } }