Make the PP report an error on undefined macro in "#if ..." for ES profiles, unless relaxed error checking is requested. Still works as normal CPP on non-ES.

Also, improved error reporting in general for the PP.


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21417 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-05-05 23:46:22 +00:00
parent 465f452749
commit 52ac67e913
11 changed files with 252 additions and 163 deletions

View File

@ -74,7 +74,7 @@ ShBinding FixedAttributeBindings[] = {
ShBindingTable FixedAttributeTable = { 3, FixedAttributeBindings };
static EShLanguage FindLanguage(char *lang);
bool CompileFile(const char *fileName, ShHandle, int, const TBuiltInResource*);
bool CompileFile(const char *fileName, ShHandle, int options, const TBuiltInResource*);
void usage();
void FreeFileData(char **data);
char** ReadFileData(const char *fileName);
@ -143,6 +143,9 @@ int C_DECL main(int argc, char* argv[])
case 'l':
debugOptions |= EDebugOpMemoryLeakMode;
break;
case 'r':
debugOptions |= EDebugOpRelaxedErrors;
break;
case 's':
debugOptions |= EDebugOpSuppressInfolog;
break;
@ -261,9 +264,12 @@ bool CompileFile(const char *fileName, ShHandle compiler, int debugOptions, cons
if (!data)
return false;
EShMessages messages = EShMsgDefault;
if (debugOptions & EDebugOpRelaxedErrors)
messages = (EShMessages)(messages | EShMsgRelaxedErrors);
for (int i = 0; i < ((debugOptions & EDebugOpMemoryLeakMode) ? 100 : 1); ++i) {
for (int j = 0; j < ((debugOptions & EDebugOpMemoryLeakMode) ? 100 : 1); ++j)
ret = ShCompile(compiler, data, OutputMultipleStrings, EShOptNone, resources, debugOptions, 100, false, EShMsgDefault);
ret = ShCompile(compiler, data, OutputMultipleStrings, EShOptNone, resources, debugOptions, 100, false, messages);
#ifdef _WIN32
if (debugOptions & EDebugOpMemoryLeakMode) {
@ -290,7 +296,8 @@ void usage()
"-a: assembly dump (LLVM IR)\n"
"-d: delay end (keeps output up in debugger, WIN32)\n"
"-l: memory leak mode\n"
"-s: silent mode (no info log)\n");
"-s: silent mode (no info log)\n"
"-r: relaxed semantic error checking mode\n");
}
#ifndef _WIN32

View File

@ -32,7 +32,7 @@ sum += 4000.0;
sum += 50000.0;
#endif
#ifndef(OFF)
#ifndef OFF
//yes
sum += 600000.0;
#else
@ -58,6 +58,13 @@ sum += 80000000.0;
sum += 900000000.0;
#endif
#if NEVER_DEFINED
//no
sum += 0.04;
#else
sum += 0.05;
#endif
// sum should be 987600301.7
gl_Position = vec4(sum);
}

View File

@ -951,14 +951,14 @@ int PaParseComment(int& lineno, TParseContext& parseContextLocal)
extern "C" {
void CPPDebugLogMsg(const char *msg)
void ShPpDebugLogMsg(const char *msg)
{
TParseContext& pc = *((TParseContext *)cpp->pC);
pc.infoSink.debug.message(EPrefixNone, msg);
}
void CPPWarningToInfoLog(const char *msg)
void ShPpWarningToInfoLog(const char *msg)
{
TParseContext& pc = *((TParseContext *)cpp->pC);
@ -966,20 +966,31 @@ void CPPWarningToInfoLog(const char *msg)
pc.infoSink.info.message(EPrefixWarning, msg, yylineno);
}
void CPPShInfoLogMsg(const char *msg)
void ShPpErrorToInfoLog(const char *msg)
{
TParseContext& pc = *((TParseContext *)cpp->pC);
pc.error(yylineno,"", "",msg,"");
pc.error(yylineno, "", "Preprocessor", msg, "");
GlobalParseContext->recover();
}
void CPPErrorToInfoLog(const char *msg)
// return 1 if error
// return 0 if no error
int ShPpMacrosMustBeDefinedError()
{
TParseContext& pc = *((TParseContext *)cpp->pC);
pc.error(yylineno, "CPP error:", "", msg, "");
GlobalParseContext->recover();
if (pc.profile == EEsProfile) {
if (pc.messages & EShMsgRelaxedErrors)
ShPpWarningToInfoLog("undefined macro in expression not allowed in es profile");
else {
ShPpErrorToInfoLog("undefined macro in expression");
return 1;
}
}
return 0;
}
void SetLineNumber(int line)
@ -1021,12 +1032,12 @@ void HandlePragma(const char **tokens, int numTokens)
if (!strcmp(tokens[0], "optimize")) {
if (numTokens != 4) {
CPPShInfoLogMsg("optimize pragma syntax is incorrect");
ShPpErrorToInfoLog("optimize pragma syntax is incorrect");
return;
}
if (strcmp(tokens[1], "(")) {
CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
ShPpErrorToInfoLog("\"(\" expected after 'optimize' keyword");
return;
}
@ -1035,22 +1046,22 @@ void HandlePragma(const char **tokens, int numTokens)
else if (!strcmp(tokens[2], "off"))
pc.contextPragma.optimize = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
return;
}
if (strcmp(tokens[3], ")")) {
CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
ShPpErrorToInfoLog("\")\" expected to end 'optimize' pragma");
return;
}
} else if (!strcmp(tokens[0], "debug")) {
if (numTokens != 4) {
CPPShInfoLogMsg("debug pragma syntax is incorrect");
ShPpErrorToInfoLog("debug pragma syntax is incorrect");
return;
}
if (strcmp(tokens[1], "(")) {
CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
ShPpErrorToInfoLog("\"(\" expected after 'debug' keyword");
return;
}
@ -1059,12 +1070,12 @@ void HandlePragma(const char **tokens, int numTokens)
else if (!strcmp(tokens[2], "off"))
pc.contextPragma.debug = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'debug' pragma");
return;
}
if (strcmp(tokens[3], ")")) {
CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
ShPpErrorToInfoLog("\")\" expected to end 'debug' pragma");
return;
}
} else {
@ -1153,7 +1164,7 @@ TBehavior GetBehavior(const char* behavior)
else if (!strcmp("warn", behavior))
return EBhWarn;
else {
CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
ShPpErrorToInfoLog((TString("behavior '") + behavior + "' is not supported").c_str());
return EBhDisable;
}
}
@ -1168,7 +1179,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
// special cased for all extension
if (!strcmp(extName, "all")) {
if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
ShPpErrorToInfoLog("extension 'all' cannot have 'require' or 'enable' behavior");
return;
} else {
for (iter = pc.extensionBehavior.begin(); iter != pc.extensionBehavior.end(); ++iter)
@ -1179,7 +1190,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
if (iter == pc.extensionBehavior.end()) {
switch (behaviorVal) {
case EBhRequire:
CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
ShPpErrorToInfoLog((TString("extension '") + extName + "' is not supported").c_str());
break;
case EBhEnable:
case EBhWarn:

View File

@ -470,14 +470,14 @@ static int FindHashLoc(AtomTable *atable, const char *s)
char str[200];
sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
HASH_TABLE_MAX_COLLISIONS);
CPPShInfoLogMsg(str);
ShPpErrorToInfoLog(str);
sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
CPPShInfoLogMsg(str);
ShPpErrorToInfoLog(str);
for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) {
sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
CPPShInfoLogMsg(str);
ShPpErrorToInfoLog(str);
}
}
return -1;
@ -720,14 +720,14 @@ void PrintAtomTable(AtomTable *atable)
for (ii = 0; ii < atable->nextFree; ii++) {
sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
CPPDebugLogMsg(str);
ShPpDebugLogMsg(str);
}
sprintf(str, "Hash table: size=%d, entries=%d, collisions=",
atable->htable.size, atable->htable.entries);
CPPDebugLogMsg(str);
ShPpDebugLogMsg(str);
for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) {
sprintf(str, " %d", atable->htable.counts[ii]);
CPPDebugLogMsg(str);
ShPpDebugLogMsg(str);
}
} // PrintAtomTable

View File

@ -186,7 +186,7 @@ int FreeCPP(void)
int FinalCPP(void)
{
if (cpp->ifdepth)
CPPErrorToInfoLog("#if mismatch");
ShPpErrorToInfoLog("missing #endif");
return 1;
}
@ -200,7 +200,7 @@ static int CPPdefine(yystypepp * yylvalpp)
memset(&mac, 0, sizeof(mac));
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != CPP_IDENTIFIER) {
CPPErrorToInfoLog("#define");
ShPpErrorToInfoLog("#define not followed by macro name");
return token;
}
name = yylvalpp->sc_ident;
@ -210,9 +210,11 @@ static int CPPdefine(yystypepp * yylvalpp)
argc = 0;
do {
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (argc == 0 && token == ')') break;
if (argc == 0 && token == ')')
break;
if (token != CPP_IDENTIFIER) {
CPPErrorToInfoLog("#define");
ShPpErrorToInfoLog("#define: bad argument");
return token;
}
if (argc < MAX_MACRO_ARGS)
@ -220,7 +222,8 @@ static int CPPdefine(yystypepp * yylvalpp)
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
} while (token == ',');
if (token != ')') {
CPPErrorToInfoLog("#define");
ShPpErrorToInfoLog("#define: missing parenthesis");
return token;
}
mac.argc = argc;
@ -245,7 +248,8 @@ static int CPPdefine(yystypepp * yylvalpp)
if (symb) {
if (!symb->details.mac.undef) {
// already defined -- need to make sure they are identical
if (symb->details.mac.argc != mac.argc) goto error;
if (symb->details.mac.argc != mac.argc)
goto error;
for (argc=0; argc < mac.argc; argc++)
if (symb->details.mac.args[argc] != mac.args[argc])
goto error;
@ -259,13 +263,14 @@ static int CPPdefine(yystypepp * yylvalpp)
if (token != old_token || yylvalpp->sc_int != old_lval) {
error:
StoreStr("Macro Redefined");
StoreStr(GetStringOfAtom(atable,name));
message=GetStrfromTStr();
StoreStr(GetStringOfAtom(atable, name));
message = GetStrfromTStr();
DecLineNumber();
CPPShInfoLogMsg(message);
ShPpErrorToInfoLog(message);
IncLineNumber();
ResetTString();
break; }
break;
}
} while (token > 0);
}
//FreeMacro(&symb->details.mac);
@ -275,6 +280,7 @@ static int CPPdefine(yystypepp * yylvalpp)
symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
}
symb->details.mac = mac;
return '\n';
} // CPPdefine
@ -282,21 +288,26 @@ static int CPPundef(yystypepp * yylvalpp)
{
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
Symbol *symb;
if(token == '\n'){
CPPErrorToInfoLog("#undef");
if (token == '\n') {
ShPpErrorToInfoLog("#undef must be followed by macro name");
return token;
}
if (token != CPP_IDENTIFIER)
goto error;
if (token != CPP_IDENTIFIER) {
ShPpErrorToInfoLog("#undef must be followed by macro name");
return token;
}
symb = LookUpSymbol(macros, yylvalpp->sc_ident);
if (symb) {
symb->details.mac.undef = 1;
}
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
error:
CPPErrorToInfoLog("#undef");
ShPpErrorToInfoLog("#undef can only be followed by a single macro name");
}
return token;
} // CPPundef
@ -344,7 +355,7 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp)
// found the #else we are looking for
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
ShPpWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
while (token != '\n')
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
@ -361,7 +372,7 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp)
return CPPif(yylvalpp);
}
} else if((atom == elseAtom) && (!ChkCorrectElseNesting())) {
CPPErrorToInfoLog("#else after a #else");
ShPpErrorToInfoLog("#else after #else");
cpp->CompileError = 1;
}
}; // end while
@ -436,6 +447,7 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
{
int i, val;
Symbol *s;
if (token == CPP_IDENTIFIER) {
if (yylvalpp->sc_ident == definedAtom) {
int needclose = 0;
@ -444,21 +456,46 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
needclose = 1;
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
if (token != CPP_IDENTIFIER)
goto error;
if (token != CPP_IDENTIFIER) {
ShPpErrorToInfoLog("incorrect preprocessor directive");
*err = 1;
*res = 0;
return token;
}
*res = (s = LookUpSymbol(macros, yylvalpp->sc_ident))
? !s->details.mac.undef : 0;
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (needclose) {
if (token != ')')
goto error;
if (token != ')') {
ShPpErrorToInfoLog("missing ')'");
*err = 1;
*res = 0;
return token;
}
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
} else if (MacroExpand(yylvalpp->sc_ident, yylvalpp)) {
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
return eval(token, prec, res, err, yylvalpp);
} else {
goto error;
} else {
int macroReturn = MacroExpand(yylvalpp->sc_ident, yylvalpp);
if (macroReturn == 1) {
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
return eval(token, prec, res, err, yylvalpp);
} else if (macroReturn == -1) {
*res = 0;
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (ShPpMacrosMustBeDefinedError())
*err = 1;
return token;
} else {
ShPpErrorToInfoLog("can't evaluate expression");
*err = 1;
*res = 0;
return token;
}
}
} else if (token == CPP_INTCONSTANT) {
*res = yylvalpp->sc_int;
@ -467,8 +504,13 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
token = eval(token, MIN_PREC, res, err, yylvalpp);
if (!*err) {
if (token != ')')
goto error;
if (token != ')') {
ShPpErrorToInfoLog("expected ')'");
*err = 1;
*res = 0;
return token;
}
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
} else {
@ -481,7 +523,11 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
token = eval(token, UNARY, res, err, yylvalpp);
*res = unop[i].op(*res);
} else {
goto error;
ShPpErrorToInfoLog("bad expression");
*err = 1;
*res = 0;
return token;
}
}
while (!*err) {
@ -497,11 +543,7 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
token = eval(token, binop[i].prec, res, err, yylvalpp);
*res = binop[i].op(val, *res);
}
return token;
error:
CPPErrorToInfoLog("incorrect preprocessor directive");
*err = 1;
*res = 0;
return token;
} // eval
@ -513,12 +555,12 @@ static int CPPif(yystypepp * yylvalpp)
if (!cpp->ifdepth++)
ifloc = *cpp->tokenLoc;
if (cpp->ifdepth > MAX_IF_NESTING){
CPPErrorToInfoLog("max #if nesting depth exceeded");
ShPpErrorToInfoLog("max #if nesting depth exceeded");
return 0;
}
token = eval(token, MIN_PREC, &res, &err, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
ShPpWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
while (token != '\n')
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
@ -533,18 +575,18 @@ static int CPPifdef(int defined, yystypepp * yylvalpp)
{
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
int name = yylvalpp->sc_ident;
if(++cpp->ifdepth >MAX_IF_NESTING){
CPPErrorToInfoLog("max #if nesting depth exceeded");
if(++cpp->ifdepth > MAX_IF_NESTING){
ShPpErrorToInfoLog("max #if nesting depth exceeded");
return 0;
}
cpp->elsetracker++;
if (token != CPP_IDENTIFIER) {
defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef");
defined ? ShPpErrorToInfoLog("#ifdef not followed by macro name") : ShPpErrorToInfoLog("#ifndef not followed by macro name");
} else {
Symbol *s = LookUpSymbol(macros, name);
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
ShPpWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
while (token != '\n')
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
@ -557,9 +599,9 @@ static int CPPifdef(int defined, yystypepp * yylvalpp)
static int CPPline(yystypepp * yylvalpp)
{
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if(token=='\n'){
if (token=='\n') {
DecLineNumber();
CPPErrorToInfoLog("#line");
ShPpErrorToInfoLog("#line must by followed by an integral literal");
IncLineNumber();
return token;
}
@ -573,23 +615,21 @@ static int CPPline(yystypepp * yylvalpp)
SetStringNumber(yylvalpp->sc_int);
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if(token!='\n')
CPPErrorToInfoLog("#line");
ShPpErrorToInfoLog("#line cannot be followed by more than two integral literals");
}
else if (token == '\n'){
else if (token == '\n')
return token;
}
else{
CPPErrorToInfoLog("#line");
}
}
else{
CPPErrorToInfoLog("#line");
}
else
ShPpErrorToInfoLog("#line second argument can only be an integral literal");
} else
ShPpErrorToInfoLog("#line first argument can only be an integral literal");
return token;
}
static int CPPerror(yystypepp * yylvalpp) {
static int CPPerror(yystypepp * yylvalpp)
{
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
const char *message;
@ -597,16 +637,16 @@ static int CPPerror(yystypepp * yylvalpp) {
if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
StoreStr(yylvalpp->symbol_name);
}else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident));
}else {
StoreStr(GetStringOfAtom(atable,token));
StoreStr(GetStringOfAtom(atable, token));
}
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
DecLineNumber();
//store this msg into the shader's information log..set the Compile Error flag!!!!
message=GetStrfromTStr();
CPPShInfoLogMsg(message);
ShPpErrorToInfoLog(message);
ResetTString();
cpp->CompileError=1;
IncLineNumber();
@ -626,7 +666,7 @@ static int CPPpragma(yystypepp * yylvalpp)
if (token=='\n') {
DecLineNumber();
CPPErrorToInfoLog("#pragma");
ShPpErrorToInfoLog("#pragma must be followed by pragma arguments");
IncLineNumber();
return token;
}
@ -656,7 +696,7 @@ static int CPPpragma(yystypepp * yylvalpp)
break;
case -1:
// EOF
CPPShInfoLogMsg("#pragma directive must end with a newline");
ShPpErrorToInfoLog("#pragma directive must end with a newline");
return token;
default:
SrcStrName[0] = token;
@ -685,16 +725,16 @@ static int CPPversion(yystypepp * yylvalpp)
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (cpp->notAVersionToken == 1)
CPPShInfoLogMsg("#version must occur before any other statement in the program");
ShPpErrorToInfoLog("#version must occur before any other statement in the program");
if(token=='\n'){
DecLineNumber();
CPPErrorToInfoLog("#version");
ShPpErrorToInfoLog("#version");
IncLineNumber();
return token;
}
if (token != CPP_INTCONSTANT)
CPPErrorToInfoLog("#version");
ShPpErrorToInfoLog("#version");
yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
@ -714,14 +754,14 @@ static int CPPversion(yystypepp * yylvalpp)
else if (yylvalpp->sc_ident == esAtom)
SetProfile(EEsProfile);
else
CPPErrorToInfoLog("#version profile name");
ShPpErrorToInfoLog("#version profile name");
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token == '\n')
return token;
else
CPPErrorToInfoLog("#version");
ShPpErrorToInfoLog("#version");
}
return token;
@ -735,25 +775,25 @@ static int CPPextension(yystypepp * yylvalpp)
if(token=='\n'){
DecLineNumber();
CPPShInfoLogMsg("extension name not specified");
ShPpErrorToInfoLog("extension name not specified");
IncLineNumber();
return token;
}
if (token != CPP_IDENTIFIER)
CPPErrorToInfoLog("#extension");
ShPpErrorToInfoLog("#extension");
strcpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != ':') {
CPPShInfoLogMsg("':' missing after extension name");
ShPpErrorToInfoLog("':' missing after extension name");
return token;
}
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != CPP_IDENTIFIER) {
CPPShInfoLogMsg("behavior for extension not specified");
ShPpErrorToInfoLog("behavior for extension not specified");
return token;
}
@ -764,7 +804,7 @@ static int CPPextension(yystypepp * yylvalpp)
return token;
}
else{
CPPErrorToInfoLog("#extension");
ShPpErrorToInfoLog("#extension");
}
return token;
} // CPPextension
@ -781,25 +821,25 @@ int readCPPline(yystypepp * yylvalpp)
} else if (yylvalpp->sc_ident == elseAtom) {
if (ChkCorrectElseNesting()) {
if (! cpp->ifdepth) {
CPPErrorToInfoLog("#else mismatch");
ShPpErrorToInfoLog("#else mismatch");
cpp->CompileError = 1;
}
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
ShPpWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
while (token != '\n')
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
}
token = CPPelse(0, yylvalpp);
} else {
CPPErrorToInfoLog("#else after a #else");
ShPpErrorToInfoLog("#else after a #else");
cpp->ifdepth = 0;
cpp->notAVersionToken = 1;
return 0;
}
} else if (yylvalpp->sc_ident == elifAtom) {
if (!cpp->ifdepth){
CPPErrorToInfoLog("#elif mismatch");
ShPpErrorToInfoLog("#elif mismatch");
cpp->CompileError=1;
}
// this token is really a dont care, but we still need to eat the tokens
@ -811,7 +851,7 @@ int readCPPline(yystypepp * yylvalpp)
cpp->elsedepth[cpp->elsetracker] = 0;
--cpp->elsetracker;
if (!cpp->ifdepth){
CPPErrorToInfoLog("#endif mismatch");
ShPpErrorToInfoLog("#endif mismatch");
cpp->CompileError=1;
}
else
@ -837,9 +877,9 @@ int readCPPline(yystypepp * yylvalpp)
token = CPPextension(yylvalpp);
} else {
StoreStr("Invalid Directive");
StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident));
message=GetStrfromTStr();
CPPShInfoLogMsg(message);
ShPpErrorToInfoLog(message);
ResetTString();
}
}
@ -891,7 +931,7 @@ static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp) {
PushEofSrc();
ReadFromTokenStream(a, 0, 0);
while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) {
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp))
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp) == 1)
continue;
RecordToken(n, token, yylvalpp);
}
@ -907,7 +947,7 @@ typedef struct MacroInputSrc {
} MacroInputSrc;
/* macro_scan ---
** return the next token for a macro expanion, handling macro args
** return the next token for a macro expansion, handling macro args
*/
static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) {
MacroInputSrc* in = (MacroInputSrc*)inInput;
@ -931,41 +971,58 @@ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) {
free(in->args);
}
free(in);
return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
} // macro_scan
/* MacroExpand
** check an identifier (atom) to see if it a macro that should be expanded.
** Check an identifier (atom) to see if it is a macro that should be expanded.
** If it is, push an InputSrc that will produce the appropriate expansion
** and return TRUE. If not, return FALSE.
** and return 1.
** If it is, but undefined, it should expand to 0, push an InputSrc that will
** expand to 0 and return -1.
** Otherwise, return 0.
*/
int MacroExpand(int atom, yystypepp * yylvalpp)
{
Symbol *sym = LookUpSymbol(macros, atom);
MacroInputSrc *in;
int i,j, token, depth=0;
Symbol *sym = LookUpSymbol(macros, atom);
MacroInputSrc *in;
int i, j, token;
int depth = 0;
const char *message;
if (atom == __LINE__Atom) {
yylvalpp->sc_int = GetLineNumber();
sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
sprintf(yylvalpp->symbol_name, "%d", yylvalpp->sc_int);
UngetToken(CPP_INTCONSTANT, yylvalpp);
return 1;
}
if (atom == __FILE__Atom) {
yylvalpp->sc_int = GetStringNumber();
sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
sprintf(yylvalpp->symbol_name, "%d", yylvalpp->sc_int);
UngetToken(CPP_INTCONSTANT, yylvalpp);
return 1;
}
if (atom == __VERSION__Atom) {
strcpy(yylvalpp->symbol_name,"100");
strcpy(yylvalpp->symbol_name, "100");
yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
UngetToken(CPP_INTCONSTANT, yylvalpp);
return 1;
}
if (!sym || sym->details.mac.undef) return 0;
if (sym->details.mac.busy) return 0; // no recursive expansions
if (! sym || sym->details.mac.undef)
return -1;
else if (sym->details.mac.busy)
return 0; // no recursive expansions
in = (MacroInputSrc*)malloc(sizeof(*in));
memset(in, 0, sizeof(*in));
in->base.scan = macro_scan;
@ -977,22 +1034,24 @@ int MacroExpand(int atom, yystypepp * yylvalpp)
if (token != '(') {
UngetToken(token, yylvalpp);
yylvalpp->sc_ident = atom;
return 0;
}
in->args = (TokenStream**)malloc(in->mac->argc * sizeof(TokenStream *));
for (i=0; i<in->mac->argc; i++)
in->args[i] = NewTokenStream("macro arg", 0);
i=0;j=0;
do{
do {
depth = 0;
while(1) {
while (1) {
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token <= 0) {
StoreStr("EOF in Macro ");
StoreStr(GetStringOfAtom(atable,atom));
StoreStr(GetStringOfAtom(atable, atom));
message=GetStrfromTStr();
CPPShInfoLogMsg(message);
ShPpErrorToInfoLog(message);
ResetTString();
return 1;
}
if((in->mac->argc==0) && (token!=')')) break;
@ -1009,13 +1068,13 @@ int MacroExpand(int atom, yystypepp * yylvalpp)
break;
}
i++;
}while(i < in->mac->argc);
} while (i < in->mac->argc);
if (i < in->mac->argc) {
StoreStr("Too few args in Macro ");
StoreStr(GetStringOfAtom(atable,atom));
StoreStr(GetStringOfAtom(atable, atom));
message=GetStrfromTStr();
CPPShInfoLogMsg(message);
ShPpErrorToInfoLog(message);
ResetTString();
} else if (token != ')') {
depth=0;
@ -1027,16 +1086,17 @@ int MacroExpand(int atom, yystypepp * yylvalpp)
if (token <= 0) {
StoreStr("EOF in Macro ");
StoreStr(GetStringOfAtom(atable,atom));
StoreStr(GetStringOfAtom(atable, atom));
message=GetStrfromTStr();
CPPShInfoLogMsg(message);
ShPpErrorToInfoLog(message);
ResetTString();
return 1;
}
StoreStr("Too many args in Macro ");
StoreStr(GetStringOfAtom(atable,atom));
StoreStr(GetStringOfAtom(atable, atom));
message=GetStrfromTStr();
CPPShInfoLogMsg(message);
ShPpErrorToInfoLog(message);
ResetTString();
}
for (i=0; i<in->mac->argc; i++) {
@ -1057,6 +1117,7 @@ int MacroExpand(int atom, yystypepp * yylvalpp)
sym->details.mac.busy = 1;
RewindTokenStream(sym->details.mac.body);
cpp->currentInput = &in->base;
return 1;
} // MacroExpand

View File

@ -102,9 +102,11 @@ int MacroExpand(int atom, yystypepp * yylvalpp);
extern "C" {
#endif
void CPPDebugLogMsg(const char *msg); // Prints information into debug log
void CPPShInfoLogMsg(const char*); // Store cpp Err Msg into Sh.Info.Log
void CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log
void ShPpDebugLogMsg(const char *msg); // Prints information into debug log
void ShPpErrorToInfoLog(const char*); // Store cpp Err Msg into Sh.Info.Log
void ShPpWarningToInfoLog(const char *msg); // Prints warning messages into info log
int ShPpMacrosMustBeDefinedError();
void HandlePragma(const char**, int numTokens); // #pragma directive container.
void ResetTString(void); // #error Message as TString.
void StoreStr(const char*); // Store the TString in Parse Context.

View File

@ -258,7 +258,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} else {
CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
ShPpErrorToInfoLog("floating-point literal too long");
len = 1,str_len=1;
}
}
@ -268,7 +268,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
if (ch == 'e' || ch == 'E') {
if (len >= MAX_SYMBOL_NAME_LEN) {
CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
ShPpErrorToInfoLog("floating-point literal too long");
len = 1,str_len=1;
} else {
ExpSign = 1;
@ -289,12 +289,12 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
str[len++]=ch;
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} else {
CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
ShPpErrorToInfoLog("floating-point literal too long");
len = 1,str_len=1;
}
}
} else {
CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
ShPpErrorToInfoLog("bad character in exponent");
}
exp *= ExpSign;
}
@ -303,7 +303,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
if (len == 0) {
yylvalpp->sc_fval = 0.0f;
yylvalpp->sc_dval = 0.0;
strcpy(str,"0.0");
strcpy(str, "0.0");
} else {
if (ch == 'l' || ch == 'L') {
int ch2 = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
@ -315,7 +315,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
str[len++] = ch;
str[len++] = ch2;
} else {
CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
ShPpErrorToInfoLog("floating-point literal too long");
len = 1,str_len=1;
}
}
@ -323,7 +323,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
if (len < MAX_SYMBOL_NAME_LEN)
str[len++] = ch;
else {
CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
ShPpErrorToInfoLog("floating-point literal too long");
len = 1,str_len=1;
}
} else
@ -425,7 +425,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
ival = (ival << 4) | ii;
} else {
if (!AlreadyComplained)
CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
ShPpErrorToInfoLog("hexidecimal literal too long");
AlreadyComplained = 1;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
@ -433,7 +433,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
(ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f'));
} else {
CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
ShPpErrorToInfoLog("bad digit in hexidecimal literal");
}
if (ch == 'u' || ch == 'U')
yylvalpp->symbol_name[len++] = ch;
@ -452,7 +452,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
ival = (ival << 3) | ii;
} else {
if (!AlreadyComplained)
CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
ShPpErrorToInfoLog("octal literal too long");
AlreadyComplained = 1;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
@ -496,7 +496,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
ch = yylvalpp->symbol_name[ii] - '0';
if ((ival > 429496729) || (ival == 429496729 && ch >= 6)) {
if (! AlreadyComplained)
CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
ShPpErrorToInfoLog("integral literal too long");
AlreadyComplained = 1;
}
ival = ival * 10 + ch;
@ -676,14 +676,14 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
while (ch != '*') {
if (ch == '\n') nlcount++;
if (ch == EOF) {
CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
ShPpErrorToInfoLog("EOF in comment");
return -1;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
if (ch == EOF) {
CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
ShPpErrorToInfoLog("EOF in comment");
return -1;
}
} while (ch != '/');
@ -718,7 +718,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
yylvalpp->sc_ident = LookUpAddString(atable, string_val);
return CPP_STRCONSTANT;
} else {
CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
ShPpErrorToInfoLog("end of line in string");
return ERROR_SY;
}
}
@ -727,53 +727,53 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
int yylex_CPP(char* buf, int maxSize)
{
yystypepp yylvalpp;
yystypepp yylvalpp;
int token = '\n';
for(;;) {
char* tokenString = 0;
token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
if(check_EOF(token))
return 0;
if(check_EOF(token))
return 0;
if (token == '#') {
if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
token = readCPPline(&yylvalpp);
token = readCPPline(&yylvalpp);
if(check_EOF(token))
return 0;
continue;
continue;
} else {
CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
ShPpErrorToInfoLog("preprocessor directive cannot be preceded by another token");
return 0;
}
}
cpp->previous_token = token;
// expand macros
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp) == 1) {
cpp->notAVersionToken = 1;
continue;
}
if (token == '\n')
continue;
if (token == CPP_IDENTIFIER) {
cpp->notAVersionToken = 1;
tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
} else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){
cpp->notAVersionToken = 1;
tokenString = yylvalpp.symbol_name;
} else {
} else {
cpp->notAVersionToken = 1;
tokenString = GetStringOfAtom(atable,token);
}
}
if (tokenString) {
if ((signed)strlen(tokenString) >= maxSize) {
cpp->tokensBeforeEOF = 1;
return maxSize;
} else if (strlen(tokenString) > 0) {
strcpy(buf, tokenString);
strcpy(buf, tokenString);
cpp->tokensBeforeEOF = 1;
return (int)strlen(tokenString);
}
@ -790,7 +790,7 @@ int check_EOF(int token)
{
if(token==-1){
if(cpp->ifdepth >0){
CPPErrorToInfoLog("#endif missing!! Compilation stopped");
ShPpErrorToInfoLog("missing #endif");
cpp->CompileError=1;
}
return 1;

View File

@ -111,7 +111,7 @@ typedef struct InputSrc {
int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner.
int ScanFromString(char *); // Start scanning the input from the string mentioned.
int check_EOF(int); // check if we hit a EOF abruptly
void CPPErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log
void ShPpErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log
void SetLineNumber(int);
void SetStringNumber(int);
void IncLineNumber(void);

View File

@ -220,7 +220,7 @@ static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
while (lSymb) {
lrev = GetReversedAtom(atable, lSymb->name);
if (lrev == frev) {
CPPErrorToInfoLog("GetAtomString(atable, fSymb->name)");
ShPpErrorToInfoLog("GetAtomString(atable, fSymb->name)");
break;
} else {
if (lrev > frev) {

View File

@ -470,7 +470,7 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
snprintf(str, maxSize, "%c", token);
break;
}
CPPDebugLogMsg(str);
ShPpDebugLogMsg(str);
}
}

View File

@ -231,7 +231,8 @@ enum TDebugOptions {
EDebugOpLinkMaps = 0x008,
EDebugOpSuppressInfolog = 0x010,
EDebugOpMemoryLeakMode = 0x020,
EDebugOpTexturePrototypes = 0x040
EDebugOpTexturePrototypes = 0x040,
EDebugOpRelaxedErrors = 0x080
};
#ifdef __cplusplus
}