// Macro-expand a macro argument 'arg' to create 'expandedArg'. // Does not replace 'arg'. // Returns nullptr if no expanded argument is created. TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay) { // expand the argument TokenStream* expandedArg = new TokenStream; pushInput(new tMarkerInput(this)); pushTokenStreamInput(arg); int token; while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) { token = tokenPaste(token, *ppToken); if (token == tMarkerInput::marker || token == EndOfInput) break; if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0) continue; expandedArg->putToken(token, ppToken); } if (token == EndOfInput) { // MacroExpand ate the marker, so had bad input, recover delete expandedArg; expandedArg = nullptr; } else { // remove the marker popInput(); } return expandedArg; }
// Macro-expand a macro argument 'arg' to create 'expandedArg'. // Does not replace 'arg'. // Returns nullptr if no expanded argument is created. TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay) { // expand the argument TokenStream* expandedArg = new TokenStream; pushInput(new tMarkerInput(this)); pushTokenStreamInput(arg); int token; while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) { token = tokenPaste(token, *ppToken); if (token == PpAtomIdentifier) { switch (MacroExpand(ppToken, false, newLineOkay)) { case MacroExpandNotStarted: break; case MacroExpandError: // toss the rest of the pushed-input argument by scanning until tMarkerInput while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) ; break; case MacroExpandStarted: case MacroExpandUndef: continue; } } if (token == tMarkerInput::marker || token == EndOfInput) break; expandedArg->putToken(token, ppToken); } if (token != tMarkerInput::marker) { // Error, or MacroExpand ate the marker, so had bad input, recover delete expandedArg; expandedArg = nullptr; } return expandedArg; }