ERROR: 0:8001: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
ERROR: 0:8001: '#include' : must be followed by a file designation\r
ERROR: 0:8002: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
-ERROR: 0:8002: '#error' : unexpected include directive\r
+ERROR: 0:8002: '#include' : unexpected include directive\r
ERROR: 0:8003: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
ERROR: 0:8003: '#include' : extra content after file designation\r
ERROR: 0:8004: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
-ERROR: 0:8004: '#error' : unexpected include directive\r
+ERROR: 0:8004: '#include' : unexpected include directive\r
ERROR: 10 compilation errors. No code generated.\r
\r
\r
-ERROR: 0:8000: '#include' : must be followed by a file designation \r
-ERROR: 0:8001: '#include' : must be followed by a file designation \r
-ERROR: 0:8002: '#error' : unexpected include directive \r
-ERROR: 0:8003: '#include' : extra content after file designation \r
-ERROR: 0:8004: '#error' : unexpected include directive \r
+ERROR: 0:8000: '#include' : must be followed by a file designation\r
+ERROR: 0:8001: '#include' : must be followed by a file designation\r
+ERROR: 0:8002: '#include' : unexpected include directive\r
+ERROR: 0:8003: '#include' : extra content after file designation\r
+ERROR: 0:8004: '#include' : unexpected include directive\r
ERROR: 5 compilation errors. No code generated.\r
\r
\r
#include <stdarg.h>
#include <stdio.h>
+#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// TODO: handle angle brackets.
parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
} else {
- const char* name = GetAtomString(ppToken->atom);
+ // Make a copy of the name because it will be overwritten by the next token scan.
+ const std::string filename = ppToken->name;
token = scanToken(ppToken);
if (token != '\n' && token != EndOfInput) {
parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
} else {
- if (!inputStack.empty()) ungetChar();
+ std::string sourceName;
std::string replacement;
- bool success;
- std::tie(success, replacement) = includer.include(name);
- if (success) {
- pushInput(new TokenizableString(directiveLoc, replacement, this));
+ std::tie(sourceName, replacement) = includer.include(filename.c_str());
+ if (!sourceName.empty()) {
+ if (!replacement.empty()) {
+ const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
+ std::ostringstream content;
+ content << "#line " << forNextLine << " " << "\"" << sourceName << "\"\n";
+ content << replacement << (replacement.back() == '\n' ? "" : "\n");
+ content << "#line " << directiveLoc.line + forNextLine << " ";
+ if (directiveLoc.name != nullptr) {
+ content << "\"" << directiveLoc.name << "\"";
+ } else {
+ content << directiveLoc.string;
+ }
+ content << "\n";
+ pushInput(new TokenizableString(directiveLoc, content.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(ppToken->loc, "not found", name, "");
+ parseContext.ppError(directiveLoc, replacement.c_str(), "#include", "");
}
}
}
// Interface to #include handlers.
class Includer {
public:
- // On success, returns true and the content that replaces "#include
- // filename". On failure, returns false and an arbitrary string.
- virtual std::pair<bool, std::string> include(const char* filename) const = 0;
+ // On success, returns the full path and content of the file with the given
+ // filename that replaces "#include filename". On failure, returns an empty
+ // string and an error message.
+ virtual std::pair<std::string, std::string> include(const char* filename) const = 0;
};
- // Generates #error as #include content.
+ // Returns an error message for any #include directive.
class ForbidInclude : public Includer {
public:
- std::pair<bool, std::string> include(const char* filename) const override
+ std::pair<std::string, std::string> include(const char* filename) const override
{
- return std::make_pair<bool, std::string>(true, "#error unexpected include directive\n");
+ return std::make_pair<std::string, std::string>("", "unexpected include directive");
}
};