Extend the syntax of #line and __FILE__ to support filename strings.

According to the GLSL spec, the second parameter to #line should be
an integer source string number and __FILE__ will be substituted
with the integer source string number currently processed. This
patch extends the syntax of #line and __FILE__. Now #line accepts
as the second parameter a filename string quoted by double quotation
marks. And if such a #line is set, __FILE__ will be substituted with
the currently set filename string. The implementation is done via
introducing a new extension GL_GOOGLE_cpp_style_line_directive using
the extension framework.

The purpose is to support cpp-style #line directives, which is
required by #include.
This commit is contained in:
Lei Zhang 2015-06-25 17:53:54 -04:00
parent c777fc2c4c
commit 5011fbebc3
16 changed files with 176 additions and 19 deletions

View file

@ -612,8 +612,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
int lineRes = 0; // Line number after macro expansion.
int lineToken = 0;
int fileRes = 0; // Source file number after macro expansion.
bool hasFile = false;
int fileRes = 0; // Source file number after macro expansion.
const char* sourceName = nullptr; // Optional source file name.
bool lineErr = false;
bool fileErr = false;
token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
@ -627,14 +628,25 @@ int TPpContext::CPPline(TPpToken* ppToken)
parseContext.setCurrentLine(lineRes);
if (token != '\n') {
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
if (! fileErr)
parseContext.setCurrentString(fileRes);
if (parseContext.extensionTurnedOn(E_GL_GOOGLE_cpp_style_line_directive) && token == PpAtomConstString) {
// We need to save a copy of the string instead of pointing
// to the name field of the token since the name field
// will likely be overwritten by the next token scan.
sourceName = GetAtomString(LookUpAddString(ppToken->name));
parseContext.setCurrentSourceName(sourceName);
hasFile = true;
token = scanToken(ppToken);
} else {
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
if (! fileErr) {
parseContext.setCurrentString(fileRes);
hasFile = true;
}
}
}
}
if (!fileErr && !lineErr) {
parseContext.notifyLineDirective(directiveLoc, lineToken, hasFile, fileRes);
parseContext.notifyLineDirective(directiveLoc, lineToken, hasFile, fileRes, sourceName);
}
token = extraTokenCheck(PpAtomLine, ppToken, token);
@ -952,11 +964,17 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
UngetToken(PpAtomConstInt, ppToken);
return 1;
case PpAtomFileMacro:
ppToken->ival = parseContext.getCurrentLoc().string;
sprintf(ppToken->name, "%d", ppToken->ival);
case PpAtomFileMacro: {
const char* current_file = parseContext.getCurrentLoc().name;
if (parseContext.extensionTurnedOn(E_GL_GOOGLE_cpp_style_line_directive) && current_file != nullptr) {
sprintf(ppToken->name, "\"%s\"", current_file);
} else {
ppToken->ival = parseContext.getCurrentLoc().string;
sprintf(ppToken->name, "%d", ppToken->ival);
}
UngetToken(PpAtomConstInt, ppToken);
return 1;
}
case PpAtomVersionMacro:
ppToken->ival = parseContext.version;