Updated the includer interface to allow relative includes.
This plumbs both the current file path and the include depth back up to the includer. This allows the includer to properly support relative paths. This also replaces the string copy that was done during include with a zero-copy method of accomplishing the same thing. This prevents extra copies of entire files.
This commit is contained in:
parent
f2d8a5c53f
commit
a132af5b78
7 changed files with 220 additions and 54 deletions
|
|
@ -611,24 +611,28 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
|||
if (token != '\n' && token != EndOfInput) {
|
||||
parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
|
||||
} else {
|
||||
auto include = includer.include(filename.c_str());
|
||||
std::string sourceName = include.first;
|
||||
std::string replacement = include.second;
|
||||
if (!sourceName.empty()) {
|
||||
if (!replacement.empty()) {
|
||||
TShader::Includer::IncludeResult* res = includer.include(filename.c_str(), TShader::Includer::EIncludeRelative, currentSourceFile.c_str(), includeStack.size() + 1);
|
||||
if (res && !res->file_name.empty()) {
|
||||
if (res->file_data && res->file_length) {
|
||||
const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
|
||||
std::ostringstream content;
|
||||
content << "#line " << forNextLine << " " << "\"" << sourceName << "\"\n";
|
||||
content << replacement << (replacement.back() == '\n' ? "" : "\n");
|
||||
content << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
|
||||
pushInput(new TokenizableString(directiveLoc, content.str(), this));
|
||||
std::ostringstream prologue;
|
||||
std::ostringstream epilogue;
|
||||
prologue << "#line " << forNextLine << " " << "\"" << res->file_name << "\"\n";
|
||||
epilogue << (res->file_data[res->file_length - 1] == '\n'? "" : "\n") << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
|
||||
pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), 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.
|
||||
return '\n';
|
||||
} else {
|
||||
parseContext.ppError(directiveLoc, replacement.c_str(), "#include", "");
|
||||
std::string message =
|
||||
res ? std::string(res->file_data, res->file_length)
|
||||
: std::string("Could not process include directive");
|
||||
parseContext.ppError(directiveLoc, message.c_str(), "#include", "");
|
||||
if (res) {
|
||||
includer.releaseInclude(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue