bool success;
std::tie(success, replacement) = includer.include(name);
if (success) {
- pushInput(new TokenizableString(replacement, this));
+ pushInput(new TokenizableString(directiveLoc, replacement, this));
// At EOF, there's no "current" location anymore.
if (token != EndOfInput) parseContext.setCurrentColumn(0);
// Don't accidentally return EndOfInput, which will end all preprocessing.
virtual int getch() = 0;
virtual void ungetch() = 0;
+ // Will be called when we start reading tokens from this instance
+ virtual void notifyActivated() {}
+ // Will be called when we do not read tokens from this instance anymore
+ virtual void notifyDeleted() {}
protected:
bool done;
TPpContext* pp;
void pushInput(tInput* in)
{
inputStack.push_back(in);
+ in->notifyActivated();
}
void popInput()
{
+ inputStack.back()->notifyDeleted();
delete inputStack.back();
inputStack.pop_back();
}
class TokenizableString : public tInput {
public:
// Copies str, which must be non-empty.
- TokenizableString(const std::string& str, TPpContext* pp)
+ TokenizableString(const TSourceLoc& startLoc, const std::string& str, TPpContext* pp)
: tInput(pp),
str_(str),
strings(str_.data()),
length(str_.size()),
scanner(1, &strings, &length),
- stringInput(pp, scanner) {}
+ prevScanner(nullptr),
+ stringInput(pp, scanner) {
+ scanner.setLine(startLoc.line);
+ scanner.setString(startLoc.string);
+ scanner.setFile(startLoc.name);
+ }
// tInput methods:
int scan(TPpToken* t) override { return stringInput.scan(t); }
int getch() override { return stringInput.getch(); }
void ungetch() override { stringInput.ungetch(); }
+ void notifyActivated() override
+ {
+ prevScanner = pp->parseContext.getScanner();
+ pp->parseContext.setScanner(&scanner);
+ }
+ void notifyDeleted() override { pp->parseContext.setScanner(prevScanner); }
+
private:
// Stores the titular string.
const std::string str_;
size_t length;
// Scans over str_.
TInputScanner scanner;
+ // The previous effective scanner before the scanner in this instance
+ // has been activated.
+ TInputScanner* prevScanner;
// Delegate object implementing the tInput interface.
tStringInput stringInput;
};