Fix several issues in the preprocessor:
authorJohn Kessenich <cepheus@frii.com>
Sun, 10 Nov 2013 23:07:36 +0000 (23:07 +0000)
committerJohn Kessenich <cepheus@frii.com>
Sun, 10 Nov 2013 23:07:36 +0000 (23:07 +0000)
 - macro expansion of hexidecimal numbers
 - give errors instead of warnings/silence on extra tokens after #endif, #else, etc.
 - give errors on reserved macro name use, reuse of argument, and redefinition with different whitespace presence
 - detect and give error for all cases of #elif and #else after #else

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23982 e7fa87d3-cd2b-0410-9028-fcbf551c1848

14 files changed:
Test/baseResults/cppComplexExpr.vert.out
Test/baseResults/cppSimple.vert.out
Test/cppComplexExpr.vert
Test/cppSimple.vert
glslang/MachineIndependent/Scan.cpp
glslang/MachineIndependent/Scan.h
glslang/MachineIndependent/ShaderLang.cpp
glslang/MachineIndependent/preprocessor/Pp.cpp
glslang/MachineIndependent/preprocessor/PpAtom.cpp
glslang/MachineIndependent/preprocessor/PpContext.cpp
glslang/MachineIndependent/preprocessor/PpContext.h
glslang/MachineIndependent/preprocessor/PpScanner.cpp
glslang/MachineIndependent/preprocessor/PpTokens.cpp
glslang/MachineIndependent/preprocessor/PpTokens.h

index d59a556..f4550c9 100644 (file)
@@ -1,6 +1,7 @@
 ERROR: 0:46: 'xyxwx' : illegal vector field selection \r
 ERROR: 0:46: 'xyxwx' : illegal vector field selection \r
-ERROR: 2 compilation errors.  No code generated.\r
+ERROR: 0:51: '' : missing #endif \r
+ERROR: 3 compilation errors.  No code generated.\r
 \r
 ERROR: node is still EOpNull!\r
 0:4  Sequence\r
index 89201f1..a0c313c 100644 (file)
@@ -1,3 +1,4 @@
+Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.\r
 ERROR: 0:77: '#error' : good1  \r
 ERROR: 0:81: '#error' : good2  \r
 ERROR: 0:85: '#error' : good3  \r
@@ -6,20 +7,42 @@ ERROR: 0:93: '#error' : good5
 ERROR: 0:97: '#error' : good6  \r
 ERROR: 0:101: 'preprocessor' : expected ')' \r
 ERROR: 0:101: '#error' : bad1  \r
-WARNING: 0:104: '#if' : unexpected tokens following #if directive - expected a newlin\r
+ERROR: 0:104: '#if' : unexpected tokens following directiv\r
 ERROR: 0:105: '#error' : bad2  \r
 ERROR: 0:109: 'preprocessor' : expected ')' \r
 ERROR: 0:109: '#error' : bad3  \r
-WARNING: 0:112: '#if' : unexpected tokens following #if directive - expected a newlin\r
+ERROR: 0:112: '#if' : unexpected tokens following directiv\r
 ERROR: 0:113: '#error' : bad4  \r
 ERROR: 0:117: 'preprocessor' : expected ')' \r
 ERROR: 0:117: '#error' : bad5  \r
-WARNING: 0:120: '#if' : unexpected tokens following #if directive - expected a newlin\r
+ERROR: 0:120: '#if' : unexpected tokens following directiv\r
 ERROR: 0:121: '#error' : bad6  \r
-ERROR: 0:133: '#' : preprocessor directive cannot be preceded by another token \r
-INTERNAL ERROR: 0:133: Unknown PP token\r
-ERROR: 0:133: '' :  syntax error\r
-ERROR: 17 compilation errors.  No code generated.\r
+ERROR: 0:122: '#endif' : unexpected tokens following directive \r
+ERROR: 0:135: '""' : string literals not supported \r
+ERROR: 0:136: '""' : string literals not supported \r
+ERROR: 0:136: 'length' : no matching overloaded function found \r
+ERROR: 0:136: '=' :  cannot convert from 'const float' to 'int'\r
+ERROR: 0:138: ''' : character literals not supported \r
+ERROR: 0:138: ''' : character literals not supported \r
+ERROR: 0:141: '#define' : reserved built-in name prefix: GL_\r
+ERROR: 0:142: '#define' : reserved built-in name prefix: GL_\r
+ERROR: 0:143: '#define' : names containing consecutive underscores are reserved \r
+ERROR: 0:144: '#define' : names containing consecutive underscores are reserved \r
+ERROR: 0:145: '#define' : names containing consecutive underscores are reserved \r
+ERROR: 0:148: '#else' : unexpected tokens following directive \r
+ERROR: 0:149: '#else' : #elif after #else \r
+ERROR: 0:155: '#else' : unexpected tokens following directive \r
+ERROR: 0:158: '#else' : #else after #else \r
+ERROR: 0:160: '#endif' : unexpected tokens following directive \r
+ERROR: 0:164: '#define' : duplicate macro parameter \r
+ERROR: 0:173: '#define' : Macro redefined; different number of arguments: m4\r
+ERROR: 0:178: '#define' : Macro redefined; different number of arguments: m5\r
+ERROR: 0:182: '#define' : Macro redefined; different number of arguments: m6\r
+ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7\r
+ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8\r
+ERROR: 0:196: '#define' : Macro redefined; different argument names: m9\r
+ERROR: 0:206: '' : missing #endif \r
+ERROR: 43 compilation errors.  No code generated.\r
 \r
 ERROR: node is still EOpNull!\r
 0:5  Sequence\r
@@ -59,7 +82,10 @@ ERROR: node is still EOpNull!
 0:65        Constant:\r
 0:65          0.050000\r
 0:69      move second child to first child (4-component vector of float)\r
-0:69        'gl_Position' (gl_Position 4-component vector of float)\r
+0:69        gl_Position: direct index for structure (gl_Position 4-component vector of float)\r
+0:69          '__anon__1' (out block{gl_Position,gl_PointSize,gl_ClipDistance,gl_ClipVertex,gl_FrontColor,gl_BackColor,gl_FrontSecondaryColor,gl_BackSecondaryColor,gl_TexCoord,gl_FogFragCoord})\r
+0:69          Constant:\r
+0:69            0 (const uint)\r
 0:69        Construct vec4 (4-component vector of float)\r
 0:69          'sum' (float)\r
 0:124  Sequence\r
@@ -76,17 +102,31 @@ ERROR: node is still EOpNull!
 0:126    move second child to first child (int)\r
 0:126      'version' (int)\r
 0:126      Constant:\r
-0:126        110 (const int)\r
+0:126        400 (const int)\r
 0:130  Sequence\r
 0:130    move second child to first child (float)\r
 0:130      'twoPi' (float)\r
 0:130      Constant:\r
 0:130        6.280000\r
+0:199  Sequence\r
+0:199    move second child to first child (int)\r
+0:199      'n' (int)\r
+0:199      Constant:\r
+0:199        15 (const int)\r
+0:202  Sequence\r
+0:202    move second child to first child (double)\r
+0:202      'f' (double)\r
+0:202      Constant:\r
+0:202        0.000800\r
 0:?   Linker Objects\r
 0:?     'sum' (float)\r
 0:?     'linenumber' (int)\r
 0:?     'filenumber' (int)\r
 0:?     'version' (int)\r
 0:?     'twoPi' (float)\r
-0:?     'tod' (float)\r
+0:?     'a' (int)\r
+0:?     'n' (int)\r
+0:?     'f' (double)\r
+0:?     'gl_VertexID' (gl_VertexId int)\r
+0:?     'gl_InstanceID' (gl_InstanceId int)\r
 \r
index f14a78d..adbf608 100644 (file)
@@ -46,3 +46,6 @@ float foo()
     return ADD(gl_Position.xyxwx, 3.0)  // ERROR, should be this line number
     return ADD(gl_Position.y, 3.0)
 }
+
+#if 0
+// ERROR, EOF
\ No newline at end of file
index d242de3..f200fbe 100644 (file)
@@ -1,4 +1,4 @@
-#version 110
+#version 400
 
 #define ON
 
@@ -119,7 +119,7 @@ sum += 0.05;
 
 #if ((AA == BB || (AA == CC))))
 #error bad6
-#endif
+#endif extra tokens
 
 int linenumber = __LINE__;
 int filenumber = __FILE__;
@@ -129,5 +129,78 @@ int version = __VERSION__;
 #define TWOPI (2.0 * PI)
 float twoPi = TWOPI;
 
-#define PASTE(a,b) a ## b
-float PASTE(tod, ay) = 17;
+//#define PASTE(a,b) a ## b
+//float PASTE(tod, ay) = 17;
+
+"boo" // ERROR
+int a = length("aoenatuh");  // ERROR
+
+'int';  // ERROR
+
+// ERROR: all the following are reserved
+#define GL_
+#define GL_Macro 1
+#define __M 
+#define M__
+#define ABC__DE abc
+
+#if 4
+#else extra
+#elif
+// ERROR elif after else
+#endif
+
+#if blah
+  #if 0
+  #else extra
+    #ifdef M
+    #else
+    #else
+    // ERROR else after else
+    #endif  extra
+  #endif
+#endif
+
+#define m1(a,a)  // ERROR
+#define m2(a,b)
+
+// okay
+#define m3 (a)
+#define m3 (a)
+
+// ERROR
+#define m4(b)
+#define m4 (b)
+
+// ERROR
+#define m5 (b)
+#define m5(b)
+
+// ERROR
+#define m6(a)
+#define m6
+
+// ERROR (whitespace)
+#define m7 (a)
+#define m7 ( a)
+
+#define m80(a,b) is + exactly m3 the same
+#define m80(a,b) is + exactly m3 the same
+
+// ERROR
+#define m8(a,b) almost + exactly m3 the same
+#define m8(a,b) almost + exactly m3 thee same
+
+// ERROR
+#define m9(a,b,c) aoe
+#define m9(a,d,c) aoe
+
+#define n1 0xf
+int n = n1;
+
+#define f1 .08e-2Lf
+double f = f1;
+
+#if 1
+#else
+// ERROR, missing #endif
\ No newline at end of file
index 4f0d4af..39774a9 100644 (file)
@@ -480,6 +480,8 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
     parserToken = &token;
     TPpToken ppToken;
     tokenText = pp->tokenize(&ppToken);
+    if (tokenText == 0)
+        return 0;
 
     loc = ppToken.loc;
     parserToken->sType.lex.loc = loc;
@@ -531,8 +533,8 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
     case CPP_OR_ASSIGN:             return OR_ASSIGN;
     case CPP_XOR_ASSIGN:            return XOR_ASSIGN;
                                    
-    case CPP_INTCONSTANT:           parserToken->sType.lex.i = ppToken.ival;        return INTCONSTANT;
-    case CPP_UINTCONSTANT:          parserToken->sType.lex.i = ppToken.ival;        return UINTCONSTANT;
+    case CPP_INTCONSTANT:           parserToken->sType.lex.i = ppToken.ival;       return INTCONSTANT;
+    case CPP_UINTCONSTANT:          parserToken->sType.lex.i = ppToken.ival;       return UINTCONSTANT;
     case CPP_FLOATCONSTANT:         parserToken->sType.lex.d = ppToken.dval;       return FLOATCONSTANT;
     case CPP_DOUBLECONSTANT:        parserToken->sType.lex.d = ppToken.dval;       return DOUBLECONSTANT;
     case CPP_IDENTIFIER:            return tokenizeIdentifier();
index fb05037..bd6b80f 100644 (file)
@@ -46,8 +46,8 @@ namespace glslang {
 //
 class TInputScanner {
 public:
-    TInputScanner(int n, const char* const s[], size_t L[], int b = 0) : 
-        numSources(n), sources(s), lengths(L), currentSource(0), currentChar(0), stringBias(b)
+    TInputScanner(int n, const char* const s[], size_t L[], int b = 0, int f = 0) : 
+        numSources(n), sources(s), lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f)
     {
         loc = new TSourceLoc[numSources];
         loc[currentSource].string = -stringBias;
@@ -105,7 +105,7 @@ public:
     void setLine(int newLine) { loc[currentSource].line = newLine; }
     void setString(int newString) { loc[currentSource].string = newString; }
 
-    const TSourceLoc& getSourceLoc() const { return loc[currentSource]; }
+    const TSourceLoc& getSourceLoc() const { return loc[std::max(0, std::min(currentSource, numSources - finale - 1))]; }
 
     void consumeWhiteSpace(bool& foundNonSpaceTab);
     bool consumeComment();
@@ -147,6 +147,7 @@ protected:
     TSourceLoc* loc;  // an array
 
     int stringBias;   // the first string that is the user's string number 0
+    int finale;       // number of internal strings after user's last string
 };
 
 } // end namespace glslang
index 2634138..7a843c4 100644 (file)
@@ -499,7 +499,7 @@ bool CompileDeferred(
     lengths[0] = strlen(strings[0]);
     strings[numStrings + 1] = "\n int;";
     lengths[numStrings + 1] = strlen(strings[numStrings + 1]);
-    TInputScanner fullInput(numStrings + 2, strings, lengths, 1);
+    TInputScanner fullInput(numStrings + 2, strings, lengths, 1, 1);
 
     // Push a new symbol allocation scope that can for the shader's globals.
     symbolTable.push();
index aa2ab67..dd2b68a 100644 (file)
@@ -133,13 +133,10 @@ int TPpContext::FinalCPP()
 {
     mem_FreePool(pool);
 
-    if (ifdepth)
-        parseContext.error(parseContext.getCurrentLoc(), "missing #endif", "#if", "");
-
     return 1;
 }
 
-int TPpContext::CPPdefine(TPpToken * ppToken)
+int TPpContext::CPPdefine(TPpToken* ppToken)
 {
     int token, atom, args[maxMacroArgs], argc;
     MacroSymbol mac;
@@ -147,10 +144,21 @@ int TPpContext::CPPdefine(TPpToken * ppToken)
     memset(&mac, 0, sizeof(mac));
     token = currentInput->scan(this, currentInput, ppToken);
     if (token != CPP_IDENTIFIER) {
-        parseContext.error(ppToken->loc, "must be followed by macro atom", "#define", "");
+        parseContext.error(ppToken->loc, "must be followed by macro name", "#define", "");
         return token;
     }
     atom = ppToken->atom;
+    const char* definedName = GetAtomString(atom);
+    if (ppToken->loc.string >= 0) {
+        // We are in user code; check for reserved name use:
+        // "All macro names containing two consecutive underscores ( __ ) are reserved for future use as predefined 
+        // macro names. All macro names prefixed with "GL_" ("GL" followed by a single underscore) are also 
+        // reserved."
+        if (strncmp(definedName, "GL_", 3) == 0)
+            parseContext.error(ppToken->loc, "reserved built-in name prefix:", "#define", "GL_");
+        else if (strstr(definedName, "__") != 0)
+            parseContext.error(ppToken->loc, "names containing consecutive underscores are reserved", "#define", "");
+    }
     token = currentInput->scan(this, currentInput, ppToken);
     if (token == '(' && !ppToken->ival) {
         // gather arguments
@@ -164,8 +172,21 @@ int TPpContext::CPPdefine(TPpToken * ppToken)
 
                 return token;
             }
-            if (argc < maxMacroArgs)
-                args[argc++] = ppToken->atom;
+            // check for duplication
+            bool duplicate = false;
+            for (int a = 0; a < argc; ++a) {
+                if (args[a] == ppToken->atom) {
+                    parseContext.error(ppToken->loc, "duplicate macro parameter", "#define", "");
+                    duplicate = true;
+                    break;
+                }
+            }
+            if (! duplicate) {
+                if (argc < maxMacroArgs)
+                    args[argc++] = ppToken->atom;
+                else
+                    parseContext.error(ppToken->loc, "too many macro parameters", "#define", "");                    
+            }
             token = currentInput->scan(this, currentInput, ppToken);
         } while (token == ',');
         if (token != ')') {            
@@ -178,41 +199,51 @@ int TPpContext::CPPdefine(TPpToken * ppToken)
         memcpy(mac.args, args, argc * sizeof(int));
         token = currentInput->scan(this, currentInput, ppToken);
     }
-    mac.body = NewTokenStream(GetAtomString(atom), pool);
+    TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
+    mac.body = NewTokenStream(pool);
     while (token != '\n') {
-        while (token == '\\') {
+        if (token == '\\') {
             token = currentInput->scan(this, currentInput, ppToken);
             if (token == '\n')
                 token = currentInput->scan(this, currentInput, ppToken);
-            else
-                RecordToken(mac.body, '\\', ppToken);
         }
         RecordToken(mac.body, token, ppToken);
+        int spaceCandidate = currentInput->getch(this, currentInput, ppToken);
+        if (spaceCandidate == ' ' || spaceCandidate == '\t')
+            RecordToken(mac.body, ' ', 0);
+        else
+            currentInput->ungetch(this, currentInput, spaceCandidate, ppToken);
         token = currentInput->scan(this, currentInput, ppToken);
-    };
+    }
 
     symb = LookUpSymbol(atom);
     if (symb) {
-        if (!symb->mac.undef) {
-            // already defined -- need to make sure they are identical
+        if (! symb->mac.undef) {
+            // Already defined -- need to make sure they are identical:
+            // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
+            // ordering, spelling, and white-space separation, where all white-space separations are considered identical."
             if (symb->mac.argc != mac.argc)
-                goto error;
-            for (argc=0; argc < mac.argc; argc++)
-                if (symb->mac.args[argc] != mac.args[argc])
-                    goto error;
-            RewindTokenStream(symb->mac.body);
-            RewindTokenStream(mac.body);
-            do {
-                int old_lval, old_token;
-                old_token = ReadToken(symb->mac.body, ppToken);
-                old_lval = ppToken->ival;
-                token = ReadToken(mac.body, ppToken);
-                if (token != old_token || ppToken->ival != old_lval) { 
-error:
-                    parseContext.error(ppToken->loc, "Macro Redefined", "#define", GetAtomString(atom));
-                    break; 
+                parseContext.error(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(atom));
+            else {
+                for (argc=0; argc < mac.argc; argc++) {
+                    if (symb->mac.args[argc] != mac.args[argc])
+                        parseContext.error(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(atom));
                 }
-            } while (token > 0);
+                RewindTokenStream(symb->mac.body);
+                RewindTokenStream(mac.body);
+                int newToken;
+                do {
+                    int oldToken;
+                    TPpToken oldPpToken;
+                    TPpToken newPpToken;                    
+                    oldToken = ReadToken(symb->mac.body, &oldPpToken);
+                    newToken = ReadToken(mac.body, &newPpToken);
+                    if (oldToken != newToken || oldPpToken != newPpToken) {
+                        parseContext.error(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(atom));
+                        break; 
+                    }
+                } while (newToken > 0);
+            }
         }
     } else {
         symb = AddSymbol(atom);
@@ -220,7 +251,7 @@ error:
     symb->mac = mac;
 
     return '\n';
-} // CPPdefine
+}
 
 int TPpContext::CPPundef(TPpToken * ppToken)
 {
@@ -246,23 +277,25 @@ int TPpContext::CPPundef(TPpToken * ppToken)
         parseContext.error(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
 
     return token;
-} // CPPundef
+}
 
-/* CPPelse -- skip forward to appropriate spot.  This is actually used
+/* Skip forward to appropriate spot.  This is used both
 ** to skip to a #endif after seeing an #else, AND to skip to a #else,
-** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false
+** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false.
 */
-
-int TPpContext::CPPelse(int matchelse, TPpToken * ppToken)
+int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
 {
     int atom;
     int depth = 0;
     int token = currentInput->scan(this, currentInput, ppToken);
 
-    while (token > 0) {
+    while (token != EOF) {
         if (token != '#') {
-            while (token != '\n')
+            while (token != '\n' && token != EOF)
                 token = currentInput->scan(this, currentInput, ppToken);
+            
+            if (token == EOF)
+                return EOF;
 
             token = currentInput->scan(this, currentInput, ppToken);
             continue;
@@ -277,6 +310,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken * ppToken)
             ifdepth++; 
             elsetracker++;
         } else if (atom == endifAtom) {
+            token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
             elsedepth[elsetracker] = 0;
             --elsetracker;
             if (depth == 0) {
@@ -289,13 +323,8 @@ int TPpContext::CPPelse(int matchelse, TPpToken * ppToken)
             --ifdepth;
         } else if (matchelse && depth == 0) {
             if (atom == elseAtom ) {
+                token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
                 // found the #else we are looking for
-                token = currentInput->scan(this, currentInput, ppToken);
-                if (token != '\n') {
-                    parseContext.warn(ppToken->loc, "#else", "unexpected tokens following #else directive - expected a newline", "");
-                    while (token != '\n')
-                        token = currentInput->scan(this, currentInput, ppToken);
-                } 
                 break;
             } else if (atom == elifAtom) {
                 /* we decrement ifdepth here, because CPPif will increment
@@ -306,11 +335,48 @@ int TPpContext::CPPelse(int matchelse, TPpToken * ppToken)
                     --elsetracker;
                 }
 
-                return CPPif (ppToken);
+                return CPPif(ppToken);
             }
-        } else if ((atom == elseAtom) && (!ChkCorrectElseNesting()))
-            parseContext.error(ppToken->loc, "#else after #else", "#else", "");
-    };  // end while
+        } else if (atom == elseAtom || atom == elifAtom) {
+            if (! ChkCorrectElseNesting()) {
+                if (atom == elseAtom)
+                    parseContext.error(ppToken->loc, "#else after #else", "#else", "");
+                else
+                    parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
+            }
+            if (atom == elseAtom)
+                token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
+        }
+    }
+
+    return token;
+}
+
+int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
+{
+    if (token != '\n') {
+        static const char* message = "unexpected tokens following directive";
+
+        const char* label;
+        if (atom == elseAtom)
+            label = "#else";
+        else if (atom == elifAtom)
+            label = "#elif";
+        else if (atom == endifAtom)
+            label = "#endif";
+        else if (atom == ifAtom)
+            label = "#if";
+        else
+            label = "";
+
+        if (parseContext.messages & EShMsgRelaxedErrors)
+            parseContext.warn(ppToken->loc, message, label, "");
+        else
+            parseContext.error(ppToken->loc, message, label, "");
+
+        while (token != '\n')
+            token = currentInput->scan(this, currentInput, ppToken);
+    }
 
     return token;
 }
@@ -491,7 +557,7 @@ int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken * ppToken
     return token;
 } // eval
 
-int TPpContext::CPPif (TPpToken * ppToken) 
+int TPpContext::CPPif(TPpToken* ppToken) 
 {
     int token = currentInput->scan(this, currentInput, ppToken);
     int res = 0, err = 0;
@@ -503,17 +569,12 @@ int TPpContext::CPPif (TPpToken * ppToken)
         return 0;
     }
     token = eval(token, MIN_PREC, &res, &err, ppToken);
-    if (token != '\n') {
-        parseContext.warn(ppToken->loc, "unexpected tokens following #if directive - expected a newline", "#if", "");
-        while (token != '\n')
-            token = currentInput->scan(this, currentInput, ppToken);
-    } 
-    if (!res && !err) {
+    token = extraTokenCheck(ifAtom, ppToken, token);
+    if (!res && !err)
         token = CPPelse(1, ppToken);
-    }
 
     return token;
-} // CPPif
+}
 
 int TPpContext::CPPifdef(int defined, TPpToken * ppToken)
 {
@@ -540,8 +601,9 @@ int TPpContext::CPPifdef(int defined, TPpToken * ppToken)
         if (((s && !s->mac.undef) ? 1 : 0) != defined)
             token = CPPelse(1, ppToken);
     }
+
     return token;
-} // CPPifdef
+}
 
 // Handle #line
 int TPpContext::CPPline(TPpToken * ppToken) 
@@ -746,15 +808,9 @@ int TPpContext::readCPPline(TPpToken * ppToken)
             token = CPPdefine(ppToken);
         } else if (ppToken->atom == elseAtom) {
             if (ChkCorrectElseNesting()) {
-                if (! ifdepth) {
+                if (! ifdepth)
                     parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
-                }
-                token = currentInput->scan(this, currentInput, ppToken);
-                if (token != '\n') {                     
-                    parseContext.warn(ppToken->loc, "unexpected tokens following #else directive - expected a newline", "#else", "");
-                    while (token != '\n')
-                        token = currentInput->scan(this, currentInput, ppToken);
-                }
+                token = extraTokenCheck(elseAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
                 token = CPPelse(0, ppToken);
             } else {
                 parseContext.error(ppToken->loc, "#else after a #else", "#else", "");
@@ -762,9 +818,8 @@ int TPpContext::readCPPline(TPpToken * ppToken)
                 return 0;
             }
         } else if (ppToken->atom == elifAtom) {
-            if (! ifdepth) {
+            if (! ifdepth)
                 parseContext.error(ppToken->loc, "mismatched statements", "#elif", "");
-            } 
             // this token is really a dont care, but we still need to eat the tokens
             token = currentInput->scan(this, currentInput, ppToken); 
             while (token != '\n')
@@ -777,6 +832,7 @@ int TPpContext::readCPPline(TPpToken * ppToken)
                 parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
             else
                 --ifdepth;
+            token = extraTokenCheck(endifAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
         } else if (ppToken->atom == ifAtom) {
             token = CPPif (ppToken);
         } else if (ppToken->atom == ifdefAtom) {
@@ -800,12 +856,12 @@ int TPpContext::readCPPline(TPpToken * ppToken)
             parseContext.error(ppToken->loc, "Invalid Directive", "#", GetAtomString(ppToken->atom));
         }
     }
-    while (token != '\n' && token != 0 && token != EOF) {
+
+    while (token != '\n' && token != 0 && token != EOF)
         token = currentInput->scan(this, currentInput, ppToken);
-    }
 
     return token;
-} // readCPPline
+}
 
 void TPpContext::FreeMacro(MacroSymbol *s) {
     DeleteTokenStream(s->body);
@@ -843,9 +899,10 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken *
         token = ReadToken(a, ppToken);
         if (token == CPP_IDENTIFIER && LookUpSymbol(ppToken->atom))
             break;
-    } while (token > 0);
-    if (token <= 0) return a;
-    n = NewTokenStream("macro arg", 0);
+    } while (token != EOF);
+    if (token == EOF)
+        return a;
+    n = NewTokenStream(0);
     PushEofSrc();
     ReadFromTokenStream(a, 0, 0);
     while ((token = currentInput->scan(this, currentInput, ppToken)) > 0) {
@@ -855,14 +912,15 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken *
     }
     PopEofSrc();
     DeleteTokenStream(a);
+
     return n;
-} // PrescanMacroArg
+}
 
 //
 // These are called through function pointers
 //
 
-/* macro_scan ---
+/* 
 ** return the next token for a macro expansion, handling macro args 
 */
 int TPpContext::macro_scan(TPpContext* pp, TPpContext::InputSrc* inInput, TPpToken* ppToken) 
@@ -870,7 +928,11 @@ int TPpContext::macro_scan(TPpContext* pp, TPpContext::InputSrc* inInput, TPpTok
     TPpContext::MacroInputSrc* in = (TPpContext::MacroInputSrc*)inInput;
 
     int i;
-    int token = pp->ReadToken(in->mac->body, ppToken);
+    int token;
+    do {
+        token = pp->ReadToken(in->mac->body, ppToken);
+    } while (token == ' ');  // handle white space in macro
+    // TODO: preprocessor:  properly handle whitespace (or lack of it) between tokens when expanding
     if (token == CPP_IDENTIFIER) {
         for (i = in->mac->argc-1; i>=0; i--)
             if (in->mac->args[i] == ppToken->atom) 
@@ -882,7 +944,7 @@ int TPpContext::macro_scan(TPpContext* pp, TPpContext::InputSrc* inInput, TPpTok
         }
     }
 
-    if (token > 0
+    if (token != EOF
         return token;
 
     in->mac->busy = 0;
@@ -895,7 +957,7 @@ int TPpContext::macro_scan(TPpContext* pp, TPpContext::InputSrc* inInput, TPpTok
     free(in);
 
     return pp->currentInput->scan(pp, pp->currentInput, ppToken);
-} // macro_scan
+}
 
 // return a zero, for scanning a macro that was never defined
 int TPpContext::zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken* ppToken) 
@@ -912,7 +974,7 @@ int TPpContext::zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken* ppToken)
     return CPP_INTCONSTANT;
 }
 
-/* MacroExpand
+/*
 ** 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 1.
@@ -983,7 +1045,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
         }
         in->args = (TokenStream**)malloc(in->mac->argc * sizeof(TokenStream *));
         for (i = 0; i < in->mac->argc; i++)
-            in->args[i] = NewTokenStream("macro arg", 0);
+            in->args[i] = NewTokenStream(0);
         i = 0;
         j = 0;
         do {
@@ -1034,15 +1096,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
             in->args[i] = PrescanMacroArg(in->args[i], ppToken);
         }
     }
-#if 0
-    printf("  <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
-        loc.line, GetAtomString(atable, atom));
-    for (i = 0; i<in->mac->argc; i++) {
-        printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
-        DumpTokenStream(stdout, in->args[i]);
-        printf("'\n");
-    }
-#endif
+
     /*retain the input source*/
     in->base.prev = currentInput;
     sym->mac.busy = 1;
@@ -1050,7 +1104,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
     currentInput = &in->base;
 
     return 1;
-} // MacroExpand
+}
 
 int TPpContext::ChkCorrectElseNesting()
 {
index 152f4a4..caf5275 100644 (file)
@@ -150,8 +150,12 @@ const char *TPpContext::GetAtomString(int atom)
         return "<null atom>";
     if (atom < 0)
         return "<EOF>";
-    if ((size_t)atom < stringMap.size())
-        return stringMap[atom]->c_str();
+    if ((size_t)atom < stringMap.size()) {
+        if (stringMap[atom] == 0)
+            return "<invalid atom>";
+        else
+            return stringMap[atom]->c_str();
+    }
 
     return "<invalid atom>";
 }
@@ -163,7 +167,7 @@ int TPpContext::AddAtomFixed(const char *s, int atom)
 {
     TAtomMap::const_iterator it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
     if (stringMap.size() < (size_t)atom + 1)
-        stringMap.resize(atom + 100);
+        stringMap.resize(atom + 100, 0);
     stringMap[atom] = &it->first;
 
     return atom;
index 5290f0e..29af6bb 100644 (file)
@@ -106,9 +106,9 @@ void TPpContext::setInput(TInputScanner& input, bool versionWillBeError)
     StringInputSrc *in = (StringInputSrc *)malloc(sizeof(StringInputSrc));
     memset(in, 0, sizeof(StringInputSrc));
     in->input = &input;
-    in->base.scan = byte_scan;
-    in->base.getch = (int (*)(TPpContext*, InputSrc *, TPpToken *))str_getch;
-    in->base.ungetch = (void (*)(TPpContext*, InputSrc *, int, TPpToken *))str_ungetch;
+    in->base.scan = sourceScan;
+    in->base.getch = (int (*)(TPpContext*, InputSrc *, TPpToken *))sourceGetCh;
+    in->base.ungetch = (void (*)(TPpContext*, InputSrc *, int, TPpToken *))sourceUngetCh;
     in->base.prev = currentInput;
     currentInput = &in->base;
     errorOnVersion = versionWillBeError;
index d130408..22b35be 100644 (file)
@@ -84,7 +84,21 @@ namespace glslang {
 
 class TPpToken {
 public:
-    TPpToken() { loc.line = 0; loc.string = 0; name[0] = 0; }
+    TPpToken() : token(0), ival(0), dval(0.0), atom(0)
+    { 
+        loc.line = 0; 
+        loc.string = 0; 
+        name[0] = 0;
+    }
+
+    bool operator==(const TPpToken& right)
+    {
+        return token == right.token && atom == right.atom &&
+               ival == right.ival && dval == right.dval &&
+               strcmp(name, right.name) == 0;
+    }
+    bool operator!=(const TPpToken& right) { return ! operator==(right); }
+
     static const int maxTokenLength = 1024;
 
     TSourceLoc loc;
@@ -110,6 +124,7 @@ public:
 
     const char* tokenize(TPpToken* ppToken);
 
+    // TODO: preprocessor simplification: this should be a base class, not a set of function pointers
     struct InputSrc {
         struct InputSrc        *prev;
         int                    (*scan)(TPpContext*, struct InputSrc *, TPpToken *);
@@ -127,7 +142,6 @@ public:
 
     struct TokenStream {
         TokenStream *next;
-        char *name;
         TokenBlock *head;
         TokenBlock *current;
     };
@@ -231,6 +245,7 @@ protected:
     int CPPdefine(TPpToken * ppToken);
     int CPPundef(TPpToken * ppToken);
     int CPPelse(int matchelse, TPpToken * ppToken);
+    int extraTokenCheck(int atom, TPpToken* ppToken, int token);
     int eval(int token, int prec, int *res, int *err, TPpToken * ppToken);
     int CPPif (TPpToken * ppToken); 
     int CPPifdef(int defined, TPpToken * ppToken);
@@ -259,28 +274,26 @@ protected:
     //
     // From PpTokens.cpp
     //
-    char* idstr(const char *fstr, MemoryPool *pool);
     TPpContext::TokenBlock* lNewBlock(TokenStream *fTok, MemoryPool *pool);
     void lAddByte(TokenStream *fTok, unsigned char fVal);
     int lReadByte(TokenStream *pTok);
-    TokenStream *NewTokenStream(const char *name, MemoryPool *pool);
+    TokenStream *NewTokenStream(MemoryPool *pool);
     void DeleteTokenStream(TokenStream *pTok);
-    void RecordToken(TokenStream *pTok, int token, TPpToken * ppToken);
+    void RecordToken(TokenStream* pTok, int token, TPpToken* ppToken);
     void RewindTokenStream(TokenStream *pTok);
-    int ReadToken(TokenStream *pTok, TPpToken * ppToken);
+    int ReadToken(TokenStream* pTok, TPpToken* ppToken);
     int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(TPpContext *));
-    void UngetToken(int token, TPpToken * ppToken);
-    void DumpTokenStream(FILE *fp, TokenStream *s, TPpToken * ppToken);
+    void UngetToken(int token, TPpToken* ppToken);
     struct TokenInputSrc {
         InputSrc            base;
-        TokenStream         *tokens;
-        int                 (*final)(TPpContext *);
+        TokenStream *tokens;
+        int (*final)(TPpContext *);
     };
     static int scan_token(TPpContext*, TokenInputSrc *in, TPpToken * ppToken);
     struct UngotToken {
         InputSrc    base;
-        int         token;
-        TPpToken     lval;
+        int token;
+        TPpToken lval;
     };
     static int reget_token(TPpContext *, UngotToken *t, TPpToken * ppToken);
 
@@ -292,12 +305,12 @@ protected:
         TInputScanner* input;
     };
     int InitScanner(TPpContext *cpp);
-    static int str_getch(TPpContext*, StringInputSrc *in);
-    static void str_ungetch(TPpContext*, StringInputSrc *in, int ch, TPpToken *type);
+    static int sourceGetCh(TPpContext*, StringInputSrc *in);
+    static void sourceUngetCh(TPpContext*, StringInputSrc *in, int ch, TPpToken *type);
     int ScanFromString(char *s);
-    int check_EOF(int token);
+    bool check_EOF(int token);
     int lFloatConst(char *str, int len, int ch, TPpToken * ppToken);
-    static int byte_scan(TPpContext*, InputSrc *in, TPpToken * ppToken);
+    static int sourceScan(TPpContext*, InputSrc *in, TPpToken * ppToken);
 
     //
     // From PpAtom.cpp
index b241ff1..57cc502 100644 (file)
@@ -105,7 +105,7 @@ int TPpContext::InitScanner(TPpContext *cpp)
     return 1;
 }
 
-int TPpContext::str_getch(TPpContext* pp, StringInputSrc *in)
+int TPpContext::sourceGetCh(TPpContext* pp, StringInputSrc *in)
 {
     int ch = in->input->get();
 
@@ -115,7 +115,7 @@ int TPpContext::str_getch(TPpContext* pp, StringInputSrc *in)
     return ch;
 }
 
-void TPpContext::str_ungetch(TPpContext* pp, StringInputSrc *in, int ch, TPpToken *type)
+void TPpContext::sourceUngetCh(TPpContext* pp, StringInputSrc *in, int ch, TPpToken *type)
 {
     in->input->unget();
 }
@@ -130,7 +130,7 @@ void TPpContext::str_ungetch(TPpContext* pp, StringInputSrc *in, int ch, TPpToke
 *         letter 'e', or a precision ending (e.g., F or LF).
 */
 
-int TPpContext::lFloatConst(char *str, int len, int ch, TPpToken * ppToken)
+int TPpContext::lFloatConst(char* str, int len, int ch, TPpToken* ppToken)
 {
     bool HasDecimalOrExponent = false;
     int declen, exp, ExpSign;
@@ -241,13 +241,12 @@ int TPpContext::lFloatConst(char *str, int len, int ch, TPpToken * ppToken)
         return CPP_DOUBLECONSTANT;
     else
         return CPP_FLOATCONSTANT;
-} // lFloatConst
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////// Normal Scanner //////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
+}
 
-int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * ppToken)
+//
+// Scanner used to tokenize source stream.
+//
+int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
 {
     char tokenText[TPpToken::maxTokenLength + 1];
     int AlreadyComplained = 0;
@@ -268,8 +267,6 @@ int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * ppToken)
         switch (ch) {
         default:
             return ch; // Single character token
-        case EOF:
-            return EOF;
         case 'A': case 'B': case 'C': case 'D': case 'E':
         case 'F': case 'G': case 'H': case 'I': case 'J':
         case 'K': case 'L': case 'M': case 'N': case 'O':
@@ -704,14 +701,17 @@ int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * ppToken)
             }
         }
     }
-} // byte_scan
+}
 
+//
+// Return string pointer to next token.
+// Return 0 when no more tokens.
+//
 const char* TPpContext::tokenize(TPpToken* ppToken)
 {    
     int token = '\n';
 
     for(;;) {
-
         const char* tokenString = 0;
         token = currentInput->scan(this, currentInput, ppToken);
         ppToken->token = token;
@@ -742,7 +742,13 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
         else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
                  token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
             tokenString = ppToken->name;
-        else
+        else if (token == CPP_STRCONSTANT) {
+            parseContext.error(ppToken->loc, "string literals not supported", "\"\"", "");
+            tokenString = 0;
+        } else if (token == '\'') {
+            parseContext.error(ppToken->loc, "character literals not supported", "\'", "");
+            tokenString = 0;
+        } else
             tokenString = GetAtomString(token);
 
         if (tokenString) {
@@ -752,19 +758,19 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
             return tokenString;
         }
     }
-
-    return 0;
-} // PpTokenize
+}
 
 //Checks if the token just read is EOF or not.
-int TPpContext::check_EOF(int token)
+bool TPpContext::check_EOF(int token)
 {
     if (token == EOF) {
         if (ifdepth > 0)
-            parseContext.error(parseContext.getCurrentLoc(), "missing #endif", "#if", "");
-        return 1;
+            parseContext.error(parseContext.getCurrentLoc(), "missing #endif", "", "");
+
+        return true;
     }
-    return 0;
+
+    return false;
 }
 
 } // end namespace glslang
index 6451e3e..88505c0 100644 (file)
@@ -75,9 +75,11 @@ NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
 TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \****************************************************************************/
+
 //
-// tokens.c
+// For recording and playing back the stream of tokens in a macro definition.
 //
+
 #ifdef _WIN32
 #define _CRT_SECURE_NO_WARNINGS
 #define snprintf sprintf_s
@@ -94,43 +96,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 namespace glslang {
 
-///////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-* idstr()
-* Copy a string to a malloc'ed block and convert it into something suitable
-* for an ID
-*
-*/
-
-char* TPpContext::idstr(const char *fstr, MemoryPool *pool)
-{
-    size_t len;
-    char *str, *t;
-    const char *f;
-
-    len = strlen(fstr);
-    if (!pool)
-        str = (char *) malloc(len + 1);
-    else
-        str = (char *) mem_Alloc(pool, len + 1);
-
-    for (f=fstr, t=str; *f; f++) {
-        if (isalnum(*f)) *t++ = *f;
-        else if (*f == '.' || *f == '/') *t++ = '_';
-    }
-    *t = 0;
-    return str;
-} // idstr
-
-
-/*
-* lNewBlock()
-*
-*/
-
 TPpContext::TokenBlock* TPpContext::lNewBlock(TokenStream *fTok, MemoryPool *pool)
 {
     TokenBlock *lBlock;
@@ -152,12 +117,7 @@ TPpContext::TokenBlock* TPpContext::lNewBlock(TokenStream *fTok, MemoryPool *poo
     fTok->current = lBlock;
 
     return lBlock;
-} // lNewBlock
-
-/*
-* lAddByte()
-*
-*/
+}
 
 void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
 {
@@ -166,14 +126,11 @@ void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
     if (lBlock->count >= lBlock->max)
         lBlock = lNewBlock(fTok, 0);
     lBlock->data[lBlock->count++] = fVal;
-} // lAddByte
-
+}
 
 /*
-* lReadByte() - Get the next byte from a stream.
-*
+* Get the next byte from a stream.
 */
-
 int TPpContext::lReadByte(TokenStream *pTok)
 {
     TokenBlock *lBlock;
@@ -191,16 +148,12 @@ int TPpContext::lReadByte(TokenStream *pTok)
             lval = lBlock->data[lBlock->current++];
     }
     return lval;
-} // lReadByte
-
-/////////////////////////////////////// Global Functions://////////////////////////////////////
-
-/*
-* NewTokenStream()
-*
-*/
+}
 
-TPpContext::TokenStream* TPpContext::NewTokenStream(const char *name, MemoryPool *pool)
+//
+// Make a token stream (used for reprocessing macros).
+//
+TPpContext::TokenStream* TPpContext::NewTokenStream(MemoryPool *pool)
 {
     TokenStream *pTok;
 
@@ -209,17 +162,11 @@ TPpContext::TokenStream* TPpContext::NewTokenStream(const char *name, MemoryPool
     else
         pTok = (TokenStream*)mem_Alloc(pool, sizeof(TokenStream));
     pTok->next = NULL;
-    pTok->name = idstr(name, pool);
     pTok->head = NULL;
     pTok->current = NULL;
     lNewBlock(pTok, pool);
     return pTok;
-} // NewTokenStream
-
-/*
-* DeleteTokenStream()
-*
-*/
+}
 
 void TPpContext::DeleteTokenStream(TokenStream *pTok)
 {
@@ -232,18 +179,14 @@ void TPpContext::DeleteTokenStream(TokenStream *pTok)
             free(pBlock);
             pBlock = nBlock;
         }
-        if (pTok->name)
-            free(pTok->name);
         free(pTok);
     }
-} // DeleteTokenStream
+}
 
 /*
-* RecordToken() - Add a token to the end of a list for later playback or printout.
-*
+* Add a token to the end of a list for later playback.
 */
-
-void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken * ppToken)
+void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
 {
     const char *s;
     char *str = NULL;
@@ -254,7 +197,6 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken * ppToken)
         lAddByte(pTok, (unsigned char)(token & 0x7f));
     switch (token) {
     case CPP_IDENTIFIER:
-    case CPP_TYPEIDENTIFIER:
     case CPP_STRCONSTANT:
         s = GetAtomString(ppToken->atom);
         while (*s)
@@ -274,33 +216,28 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken * ppToken)
         break;
     case '(':
         lAddByte(pTok, (unsigned char)(ppToken->ival ? 1 : 0));
+        break;
     default:
         break;
     }
-} // RecordToken
+}
 
 /*
-* RewindTokenStream() - Reset a token stream in preperation for reading.
-*
+* Reset a token stream in preperation for reading.
 */
-
 void TPpContext::RewindTokenStream(TokenStream *pTok)
 {
     if (pTok->head) {
         pTok->current = pTok->head;
         pTok->current->current = 0;
     }
-} // RewindTokenStream
+}
 
 /*
-* ReadToken() - Read the next token from a stream.
-*
+* Read the next token from a token stream (not the source stream, but stream used to hold a tokenized macro).
 */
-
 int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
 {
-    //TODO: preprocessor simplification: why is this different than byte_scan
-
     char tokenText[TPpToken::maxTokenLength + 1];
     int ltoken, len;
     char ch;
@@ -311,89 +248,56 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
         if (ltoken > 127)
             ltoken += 128;
         switch (ltoken) {
-        case CPP_IDENTIFIER:
-        case CPP_TYPEIDENTIFIER:
-            len = 0;
-            ch = lReadByte(pTok);
-            while ((ch >= 'a' && ch <= 'z') ||
-                (ch >= 'A' && ch <= 'Z') ||
-                (ch >= '0' && ch <= '9') ||
-                ch == '_')
-            {
-                if (len < TPpToken::maxTokenLength) {
-                    tokenText[len] = ch;
-                    len++;
-                    ch = lReadByte(pTok);
-                } else {
-                    parseContext.error(ppToken->loc,"name too long", "", "");
-                    break;
-                }
-            }
-            tokenText[len] = '\0';
-            assert(ch == '\0');
-            ppToken->atom = LookUpAddString(tokenText);
-            return CPP_IDENTIFIER;
+        case '(':
+            ppToken->ival = lReadByte(pTok);
             break;
         case CPP_STRCONSTANT:
-            len = 0;
-            while ((ch = lReadByte(pTok)) != 0) {
-                if (len < TPpToken::maxTokenLength)
-                    tokenText[len++] = ch;
-                else
-                    break;
-            }
-
-            tokenText[len] = 0;
-            ppToken->atom = LookUpAddString(tokenText);
-            break;
+        case CPP_IDENTIFIER:
         case CPP_FLOATCONSTANT:
         case CPP_DOUBLECONSTANT:
-            len = 0;
-            ch = lReadByte(pTok);
-            while ((ch >= '0' && ch <= '9') || ch=='e' || ch=='E' || ch=='.' || ch=='+' || ch=='-' || ch=='l' || ch=='L' || ch=='f'|| ch=='F')
-            {
-                if (len < TPpToken::maxTokenLength) {
-                    tokenText[len] = ch;
-                    len++;
-                    ch = lReadByte(pTok);
-                } else {
-                    parseContext.error(ppToken->loc,"float literal too long", "", "");
-                    break;
-                }
-            }
-            tokenText[len] = '\0';
-            assert(ch == '\0');
-            strcpy(ppToken->name, tokenText);
-            ppToken->dval = atof(ppToken->name);
-            break;
         case CPP_INTCONSTANT:
         case CPP_UINTCONSTANT:
             len = 0;
             ch = lReadByte(pTok);
-            while ((ch >= '0' && ch <= '9') || ch == 'u' || ch == 'U')
-            {
+            while (ch != 0) {
                 if (len < TPpToken::maxTokenLength) {
                     tokenText[len] = ch;
                     len++;
                     ch = lReadByte(pTok);
                 } else {
-                    parseContext.error(ppToken->loc,"integer literal too long", "", "");
+                    parseContext.error(ppToken->loc, "token too long", "", "");
                     break;
                 }
             }
-            tokenText[len] = '\0';
-            assert(ch == '\0');
-            strcpy(ppToken->name,tokenText);
-            ppToken->ival = atoi(ppToken->name);
-            break;
-        case '(':
-            ppToken->ival = lReadByte(pTok);
-            break;
+            tokenText[len] = 0;
+
+            switch (ltoken) {
+            case CPP_IDENTIFIER:
+            case CPP_STRCONSTANT:
+                ppToken->atom = LookUpAddString(tokenText);
+                break;
+            case CPP_FLOATCONSTANT:
+            case CPP_DOUBLECONSTANT:
+                strcpy(ppToken->name, tokenText);
+                ppToken->dval = atof(ppToken->name);
+                break;
+            case CPP_INTCONSTANT:
+            case CPP_UINTCONSTANT:
+                strcpy(ppToken->name, tokenText);
+                if (len > 0 && tokenText[0] == '0') {
+                    if (len > 1 && tokenText[1] == 'x' || tokenText[1] == 'X')
+                        ppToken->ival = strtol(ppToken->name, 0, 16);
+                    else
+                        ppToken->ival = strtol(ppToken->name, 0, 8);
+                } else
+                    ppToken->ival = atoi(ppToken->name);
+                break;
+            }
         }
         return ltoken;
     }
     return EOF;
-} // ReadToken
+}
 
 int TPpContext::scan_token(TPpContext* pp, TokenInputSrc *in, TPpToken * ppToken)
 {
@@ -434,9 +338,7 @@ int TPpContext::reget_token(TPpContext* pp, UngotToken *t, TPpToken * ppToken)
     return token;
 }
 
-typedef int (*scanFnPtr_t);
-
-void TPpContext::UngetToken(int token, TPpToken * ppToken)
+void TPpContext::UngetToken(int token, TPpToken* ppToken)
 {
     UngotToken *t = (UngotToken *) malloc(sizeof(UngotToken));
     memset(t, 0, sizeof(UngotToken));
@@ -447,38 +349,4 @@ void TPpContext::UngetToken(int token, TPpToken * ppToken)
     currentInput = &t->base;
 }
 
-
-void TPpContext::DumpTokenStream(FILE *fp, TokenStream *s, TPpToken * ppToken) 
-{
-    int token;
-
-    if (fp == 0) fp = stdout;
-    RewindTokenStream(s);
-    while ((token = ReadToken(s, ppToken)) > 0) {
-        switch (token) {
-        case CPP_IDENTIFIER:
-        case CPP_TYPEIDENTIFIER:
-            printf("%s ", GetAtomString(ppToken->atom));
-            break;
-        case CPP_STRCONSTANT:
-            printf("\"%s\"", GetAtomString(ppToken->atom));
-            break;
-        case CPP_FLOATCONSTANT:
-        case CPP_DOUBLECONSTANT:
-            printf("%g9.6 ", ppToken->dval);
-            break;
-        case CPP_INTCONSTANT:
-        case CPP_UINTCONSTANT:
-            printf("%d ", ppToken->ival);
-            break;
-        default:
-            if (token >= 127)
-                printf("%s ", GetAtomString(token));
-            else
-                printf("%c", token);
-            break;
-        }
-    }
-}
-
 } // end namespace glslang
index fa044eb..ae00abb 100644 (file)
@@ -99,7 +99,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define CPP_OR_OP          276
 #define CPP_INC_OP         277
 #define CPP_STRCONSTANT    278
-#define CPP_TYPEIDENTIFIER 279
 #define CPP_RIGHT_ASSIGN   280
 #define CPP_LEFT_ASSIGN    281
 #define CPP_AND_ASSIGN     282