Fix several issues in the preprocessor:
- 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
This commit is contained in:
		
							parent
							
								
									cfe3ba5a18
								
							
						
					
					
						commit
						4d6570a1b3
					
				@ -1,6 +1,7 @@
 | 
				
			|||||||
ERROR: 0:46: 'xyxwx' : illegal vector field selection 
 | 
					ERROR: 0:46: 'xyxwx' : illegal vector field selection 
 | 
				
			||||||
ERROR: 0:46: 'xyxwx' : illegal vector field selection 
 | 
					ERROR: 0:46: 'xyxwx' : illegal vector field selection 
 | 
				
			||||||
ERROR: 2 compilation errors.  No code generated.
 | 
					ERROR: 0:51: '' : missing #endif 
 | 
				
			||||||
 | 
					ERROR: 3 compilation errors.  No code generated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: node is still EOpNull!
 | 
					ERROR: node is still EOpNull!
 | 
				
			||||||
0:4  Sequence
 | 
					0:4  Sequence
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.
 | 
				
			||||||
ERROR: 0:77: '#error' : good1  
 | 
					ERROR: 0:77: '#error' : good1  
 | 
				
			||||||
ERROR: 0:81: '#error' : good2  
 | 
					ERROR: 0:81: '#error' : good2  
 | 
				
			||||||
ERROR: 0:85: '#error' : good3  
 | 
					ERROR: 0:85: '#error' : good3  
 | 
				
			||||||
@ -6,20 +7,42 @@ ERROR: 0:93: '#error' : good5
 | 
				
			|||||||
ERROR: 0:97: '#error' : good6  
 | 
					ERROR: 0:97: '#error' : good6  
 | 
				
			||||||
ERROR: 0:101: 'preprocessor' : expected ')' 
 | 
					ERROR: 0:101: 'preprocessor' : expected ')' 
 | 
				
			||||||
ERROR: 0:101: '#error' : bad1  
 | 
					ERROR: 0:101: '#error' : bad1  
 | 
				
			||||||
WARNING: 0:104: '#if' : unexpected tokens following #if directive - expected a newline 
 | 
					ERROR: 0:104: '#if' : unexpected tokens following directive 
 | 
				
			||||||
ERROR: 0:105: '#error' : bad2  
 | 
					ERROR: 0:105: '#error' : bad2  
 | 
				
			||||||
ERROR: 0:109: 'preprocessor' : expected ')' 
 | 
					ERROR: 0:109: 'preprocessor' : expected ')' 
 | 
				
			||||||
ERROR: 0:109: '#error' : bad3  
 | 
					ERROR: 0:109: '#error' : bad3  
 | 
				
			||||||
WARNING: 0:112: '#if' : unexpected tokens following #if directive - expected a newline 
 | 
					ERROR: 0:112: '#if' : unexpected tokens following directive 
 | 
				
			||||||
ERROR: 0:113: '#error' : bad4  
 | 
					ERROR: 0:113: '#error' : bad4  
 | 
				
			||||||
ERROR: 0:117: 'preprocessor' : expected ')' 
 | 
					ERROR: 0:117: 'preprocessor' : expected ')' 
 | 
				
			||||||
ERROR: 0:117: '#error' : bad5  
 | 
					ERROR: 0:117: '#error' : bad5  
 | 
				
			||||||
WARNING: 0:120: '#if' : unexpected tokens following #if directive - expected a newline 
 | 
					ERROR: 0:120: '#if' : unexpected tokens following directive 
 | 
				
			||||||
ERROR: 0:121: '#error' : bad6  
 | 
					ERROR: 0:121: '#error' : bad6  
 | 
				
			||||||
ERROR: 0:133: '#' : preprocessor directive cannot be preceded by another token 
 | 
					ERROR: 0:122: '#endif' : unexpected tokens following directive 
 | 
				
			||||||
INTERNAL ERROR: 0:133: Unknown PP token
 | 
					ERROR: 0:135: '""' : string literals not supported 
 | 
				
			||||||
ERROR: 0:133: '' :  syntax error
 | 
					ERROR: 0:136: '""' : string literals not supported 
 | 
				
			||||||
ERROR: 17 compilation errors.  No code generated.
 | 
					ERROR: 0:136: 'length' : no matching overloaded function found 
 | 
				
			||||||
 | 
					ERROR: 0:136: '=' :  cannot convert from 'const float' to 'int'
 | 
				
			||||||
 | 
					ERROR: 0:138: ''' : character literals not supported 
 | 
				
			||||||
 | 
					ERROR: 0:138: ''' : character literals not supported 
 | 
				
			||||||
 | 
					ERROR: 0:141: '#define' : reserved built-in name prefix: GL_
 | 
				
			||||||
 | 
					ERROR: 0:142: '#define' : reserved built-in name prefix: GL_
 | 
				
			||||||
 | 
					ERROR: 0:143: '#define' : names containing consecutive underscores are reserved 
 | 
				
			||||||
 | 
					ERROR: 0:144: '#define' : names containing consecutive underscores are reserved 
 | 
				
			||||||
 | 
					ERROR: 0:145: '#define' : names containing consecutive underscores are reserved 
 | 
				
			||||||
 | 
					ERROR: 0:148: '#else' : unexpected tokens following directive 
 | 
				
			||||||
 | 
					ERROR: 0:149: '#else' : #elif after #else 
 | 
				
			||||||
 | 
					ERROR: 0:155: '#else' : unexpected tokens following directive 
 | 
				
			||||||
 | 
					ERROR: 0:158: '#else' : #else after #else 
 | 
				
			||||||
 | 
					ERROR: 0:160: '#endif' : unexpected tokens following directive 
 | 
				
			||||||
 | 
					ERROR: 0:164: '#define' : duplicate macro parameter 
 | 
				
			||||||
 | 
					ERROR: 0:173: '#define' : Macro redefined; different number of arguments: m4
 | 
				
			||||||
 | 
					ERROR: 0:178: '#define' : Macro redefined; different number of arguments: m5
 | 
				
			||||||
 | 
					ERROR: 0:182: '#define' : Macro redefined; different number of arguments: m6
 | 
				
			||||||
 | 
					ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7
 | 
				
			||||||
 | 
					ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8
 | 
				
			||||||
 | 
					ERROR: 0:196: '#define' : Macro redefined; different argument names: m9
 | 
				
			||||||
 | 
					ERROR: 0:206: '' : missing #endif 
 | 
				
			||||||
 | 
					ERROR: 43 compilation errors.  No code generated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: node is still EOpNull!
 | 
					ERROR: node is still EOpNull!
 | 
				
			||||||
0:5  Sequence
 | 
					0:5  Sequence
 | 
				
			||||||
@ -59,7 +82,10 @@ ERROR: node is still EOpNull!
 | 
				
			|||||||
0:65        Constant:
 | 
					0:65        Constant:
 | 
				
			||||||
0:65          0.050000
 | 
					0:65          0.050000
 | 
				
			||||||
0:69      move second child to first child (4-component vector of float)
 | 
					0:69      move second child to first child (4-component vector of float)
 | 
				
			||||||
0:69        'gl_Position' (gl_Position 4-component vector of float)
 | 
					0:69        gl_Position: direct index for structure (gl_Position 4-component vector of float)
 | 
				
			||||||
 | 
					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})
 | 
				
			||||||
 | 
					0:69          Constant:
 | 
				
			||||||
 | 
					0:69            0 (const uint)
 | 
				
			||||||
0:69        Construct vec4 (4-component vector of float)
 | 
					0:69        Construct vec4 (4-component vector of float)
 | 
				
			||||||
0:69          'sum' (float)
 | 
					0:69          'sum' (float)
 | 
				
			||||||
0:124  Sequence
 | 
					0:124  Sequence
 | 
				
			||||||
@ -76,17 +102,31 @@ ERROR: node is still EOpNull!
 | 
				
			|||||||
0:126    move second child to first child (int)
 | 
					0:126    move second child to first child (int)
 | 
				
			||||||
0:126      'version' (int)
 | 
					0:126      'version' (int)
 | 
				
			||||||
0:126      Constant:
 | 
					0:126      Constant:
 | 
				
			||||||
0:126        110 (const int)
 | 
					0:126        400 (const int)
 | 
				
			||||||
0:130  Sequence
 | 
					0:130  Sequence
 | 
				
			||||||
0:130    move second child to first child (float)
 | 
					0:130    move second child to first child (float)
 | 
				
			||||||
0:130      'twoPi' (float)
 | 
					0:130      'twoPi' (float)
 | 
				
			||||||
0:130      Constant:
 | 
					0:130      Constant:
 | 
				
			||||||
0:130        6.280000
 | 
					0:130        6.280000
 | 
				
			||||||
 | 
					0:199  Sequence
 | 
				
			||||||
 | 
					0:199    move second child to first child (int)
 | 
				
			||||||
 | 
					0:199      'n' (int)
 | 
				
			||||||
 | 
					0:199      Constant:
 | 
				
			||||||
 | 
					0:199        15 (const int)
 | 
				
			||||||
 | 
					0:202  Sequence
 | 
				
			||||||
 | 
					0:202    move second child to first child (double)
 | 
				
			||||||
 | 
					0:202      'f' (double)
 | 
				
			||||||
 | 
					0:202      Constant:
 | 
				
			||||||
 | 
					0:202        0.000800
 | 
				
			||||||
0:?   Linker Objects
 | 
					0:?   Linker Objects
 | 
				
			||||||
0:?     'sum' (float)
 | 
					0:?     'sum' (float)
 | 
				
			||||||
0:?     'linenumber' (int)
 | 
					0:?     'linenumber' (int)
 | 
				
			||||||
0:?     'filenumber' (int)
 | 
					0:?     'filenumber' (int)
 | 
				
			||||||
0:?     'version' (int)
 | 
					0:?     'version' (int)
 | 
				
			||||||
0:?     'twoPi' (float)
 | 
					0:?     'twoPi' (float)
 | 
				
			||||||
0:?     'tod' (float)
 | 
					0:?     'a' (int)
 | 
				
			||||||
 | 
					0:?     'n' (int)
 | 
				
			||||||
 | 
					0:?     'f' (double)
 | 
				
			||||||
 | 
					0:?     'gl_VertexID' (gl_VertexId int)
 | 
				
			||||||
 | 
					0:?     'gl_InstanceID' (gl_InstanceId int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -46,3 +46,6 @@ float foo()
 | 
				
			|||||||
    return ADD(gl_Position.xyxwx, 3.0)  // ERROR, should be this line number
 | 
					    return ADD(gl_Position.xyxwx, 3.0)  // ERROR, should be this line number
 | 
				
			||||||
    return ADD(gl_Position.y, 3.0)
 | 
					    return ADD(gl_Position.y, 3.0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					// ERROR, EOF
 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
#version 110
 | 
					#version 400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ON
 | 
					#define ON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -119,7 +119,7 @@ sum += 0.05;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if ((AA == BB || (AA == CC))))
 | 
					#if ((AA == BB || (AA == CC))))
 | 
				
			||||||
#error bad6
 | 
					#error bad6
 | 
				
			||||||
#endif
 | 
					#endif extra tokens
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int linenumber = __LINE__;
 | 
					int linenumber = __LINE__;
 | 
				
			||||||
int filenumber = __FILE__;
 | 
					int filenumber = __FILE__;
 | 
				
			||||||
@ -129,5 +129,78 @@ int version = __VERSION__;
 | 
				
			|||||||
#define TWOPI (2.0 * PI)
 | 
					#define TWOPI (2.0 * PI)
 | 
				
			||||||
float twoPi = TWOPI;
 | 
					float twoPi = TWOPI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PASTE(a,b) a ## b
 | 
					//#define PASTE(a,b) a ## b
 | 
				
			||||||
float PASTE(tod, ay) = 17;
 | 
					//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
 | 
				
			||||||
@ -480,6 +480,8 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
 | 
				
			|||||||
    parserToken = &token;
 | 
					    parserToken = &token;
 | 
				
			||||||
    TPpToken ppToken;
 | 
					    TPpToken ppToken;
 | 
				
			||||||
    tokenText = pp->tokenize(&ppToken);
 | 
					    tokenText = pp->tokenize(&ppToken);
 | 
				
			||||||
 | 
					    if (tokenText == 0)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loc = ppToken.loc;
 | 
					    loc = ppToken.loc;
 | 
				
			||||||
    parserToken->sType.lex.loc = loc;
 | 
					    parserToken->sType.lex.loc = loc;
 | 
				
			||||||
 | 
				
			|||||||
@ -46,8 +46,8 @@ namespace glslang {
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
class TInputScanner {
 | 
					class TInputScanner {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    TInputScanner(int n, const char* const s[], size_t L[], int b = 0) : 
 | 
					    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)
 | 
					        numSources(n), sources(s), lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        loc = new TSourceLoc[numSources];
 | 
					        loc = new TSourceLoc[numSources];
 | 
				
			||||||
        loc[currentSource].string = -stringBias;
 | 
					        loc[currentSource].string = -stringBias;
 | 
				
			||||||
@ -105,7 +105,7 @@ public:
 | 
				
			|||||||
    void setLine(int newLine) { loc[currentSource].line = newLine; }
 | 
					    void setLine(int newLine) { loc[currentSource].line = newLine; }
 | 
				
			||||||
    void setString(int newString) { loc[currentSource].string = newString; }
 | 
					    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);
 | 
					    void consumeWhiteSpace(bool& foundNonSpaceTab);
 | 
				
			||||||
    bool consumeComment();
 | 
					    bool consumeComment();
 | 
				
			||||||
@ -147,6 +147,7 @@ protected:
 | 
				
			|||||||
    TSourceLoc* loc;  // an array
 | 
					    TSourceLoc* loc;  // an array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int stringBias;   // the first string that is the user's string number 0
 | 
					    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
 | 
					} // end namespace glslang
 | 
				
			||||||
 | 
				
			|||||||
@ -499,7 +499,7 @@ bool CompileDeferred(
 | 
				
			|||||||
    lengths[0] = strlen(strings[0]);
 | 
					    lengths[0] = strlen(strings[0]);
 | 
				
			||||||
    strings[numStrings + 1] = "\n int;";
 | 
					    strings[numStrings + 1] = "\n int;";
 | 
				
			||||||
    lengths[numStrings + 1] = strlen(strings[numStrings + 1]);
 | 
					    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.
 | 
					    // Push a new symbol allocation scope that can for the shader's globals.
 | 
				
			||||||
    symbolTable.push();
 | 
					    symbolTable.push();
 | 
				
			||||||
 | 
				
			|||||||
@ -133,9 +133,6 @@ int TPpContext::FinalCPP()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    mem_FreePool(pool);
 | 
					    mem_FreePool(pool);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ifdepth)
 | 
					 | 
				
			||||||
        parseContext.error(parseContext.getCurrentLoc(), "missing #endif", "#if", "");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -147,10 +144,21 @@ int TPpContext::CPPdefine(TPpToken * ppToken)
 | 
				
			|||||||
    memset(&mac, 0, sizeof(mac));
 | 
					    memset(&mac, 0, sizeof(mac));
 | 
				
			||||||
    token = currentInput->scan(this, currentInput, ppToken);
 | 
					    token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
    if (token != CPP_IDENTIFIER) {
 | 
					    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;
 | 
					        return token;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    atom = ppToken->atom;
 | 
					    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);
 | 
					    token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
    if (token == '(' && !ppToken->ival) {
 | 
					    if (token == '(' && !ppToken->ival) {
 | 
				
			||||||
        // gather arguments
 | 
					        // gather arguments
 | 
				
			||||||
@ -164,8 +172,21 @@ int TPpContext::CPPdefine(TPpToken * ppToken)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return token;
 | 
					                return token;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            // 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)
 | 
					                if (argc < maxMacroArgs)
 | 
				
			||||||
                    args[argc++] = ppToken->atom;
 | 
					                    args[argc++] = ppToken->atom;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    parseContext.error(ppToken->loc, "too many macro parameters", "#define", "");                    
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            token = currentInput->scan(this, currentInput, ppToken);
 | 
					            token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
        } while (token == ',');
 | 
					        } while (token == ',');
 | 
				
			||||||
        if (token != ')') {            
 | 
					        if (token != ')') {            
 | 
				
			||||||
@ -178,41 +199,51 @@ int TPpContext::CPPdefine(TPpToken * ppToken)
 | 
				
			|||||||
        memcpy(mac.args, args, argc * sizeof(int));
 | 
					        memcpy(mac.args, args, argc * sizeof(int));
 | 
				
			||||||
        token = currentInput->scan(this, currentInput, ppToken);
 | 
					        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 != '\n') {
 | 
				
			||||||
        while (token == '\\') {
 | 
					        if (token == '\\') {
 | 
				
			||||||
            token = currentInput->scan(this, currentInput, ppToken);
 | 
					            token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
            if (token == '\n')
 | 
					            if (token == '\n')
 | 
				
			||||||
                token = currentInput->scan(this, currentInput, ppToken);
 | 
					                token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                RecordToken(mac.body, '\\', ppToken);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        RecordToken(mac.body, token, 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);
 | 
					        token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
    };
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    symb = LookUpSymbol(atom);
 | 
					    symb = LookUpSymbol(atom);
 | 
				
			||||||
    if (symb) {
 | 
					    if (symb) {
 | 
				
			||||||
        if (! symb->mac.undef) {
 | 
					        if (! symb->mac.undef) {
 | 
				
			||||||
            // already defined -- need to make sure they are identical
 | 
					            // 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)
 | 
					            if (symb->mac.argc != mac.argc)
 | 
				
			||||||
                goto error;
 | 
					                parseContext.error(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(atom));
 | 
				
			||||||
            for (argc=0; argc < mac.argc; argc++)
 | 
					            else {
 | 
				
			||||||
 | 
					                for (argc=0; argc < mac.argc; argc++) {
 | 
				
			||||||
                    if (symb->mac.args[argc] != mac.args[argc])
 | 
					                    if (symb->mac.args[argc] != mac.args[argc])
 | 
				
			||||||
                    goto error;
 | 
					                        parseContext.error(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(atom));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                RewindTokenStream(symb->mac.body);
 | 
					                RewindTokenStream(symb->mac.body);
 | 
				
			||||||
                RewindTokenStream(mac.body);
 | 
					                RewindTokenStream(mac.body);
 | 
				
			||||||
 | 
					                int newToken;
 | 
				
			||||||
                do {
 | 
					                do {
 | 
				
			||||||
                int old_lval, old_token;
 | 
					                    int oldToken;
 | 
				
			||||||
                old_token = ReadToken(symb->mac.body, ppToken);
 | 
					                    TPpToken oldPpToken;
 | 
				
			||||||
                old_lval = ppToken->ival;
 | 
					                    TPpToken newPpToken;                    
 | 
				
			||||||
                token = ReadToken(mac.body, ppToken);
 | 
					                    oldToken = ReadToken(symb->mac.body, &oldPpToken);
 | 
				
			||||||
                if (token != old_token || ppToken->ival != old_lval) { 
 | 
					                    newToken = ReadToken(mac.body, &newPpToken);
 | 
				
			||||||
error:
 | 
					                    if (oldToken != newToken || oldPpToken != newPpToken) {
 | 
				
			||||||
                    parseContext.error(ppToken->loc, "Macro Redefined", "#define", GetAtomString(atom));
 | 
					                        parseContext.error(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(atom));
 | 
				
			||||||
                        break; 
 | 
					                        break; 
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            } while (token > 0);
 | 
					                } while (newToken > 0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        symb = AddSymbol(atom);
 | 
					        symb = AddSymbol(atom);
 | 
				
			||||||
@ -220,7 +251,7 @@ error:
 | 
				
			|||||||
    symb->mac = mac;
 | 
					    symb->mac = mac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return '\n';
 | 
					    return '\n';
 | 
				
			||||||
} // CPPdefine
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int TPpContext::CPPundef(TPpToken * ppToken)
 | 
					int TPpContext::CPPundef(TPpToken * ppToken)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -246,24 +277,26 @@ int TPpContext::CPPundef(TPpToken * ppToken)
 | 
				
			|||||||
        parseContext.error(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
 | 
					        parseContext.error(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return token;
 | 
					    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,
 | 
					** 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 atom;
 | 
				
			||||||
    int depth = 0;
 | 
					    int depth = 0;
 | 
				
			||||||
    int token = currentInput->scan(this, currentInput, ppToken);
 | 
					    int token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (token > 0) {
 | 
					    while (token != EOF) {
 | 
				
			||||||
        if (token != '#') {
 | 
					        if (token != '#') {
 | 
				
			||||||
            while (token != '\n')
 | 
					            while (token != '\n' && token != EOF)
 | 
				
			||||||
                token = currentInput->scan(this, currentInput, ppToken);
 | 
					                token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            if (token == EOF)
 | 
				
			||||||
 | 
					                return EOF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            token = currentInput->scan(this, currentInput, ppToken);
 | 
					            token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -277,6 +310,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken * ppToken)
 | 
				
			|||||||
            ifdepth++; 
 | 
					            ifdepth++; 
 | 
				
			||||||
            elsetracker++;
 | 
					            elsetracker++;
 | 
				
			||||||
        } else if (atom == endifAtom) {
 | 
					        } else if (atom == endifAtom) {
 | 
				
			||||||
 | 
					            token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
 | 
				
			||||||
            elsedepth[elsetracker] = 0;
 | 
					            elsedepth[elsetracker] = 0;
 | 
				
			||||||
            --elsetracker;
 | 
					            --elsetracker;
 | 
				
			||||||
            if (depth == 0) {
 | 
					            if (depth == 0) {
 | 
				
			||||||
@ -289,13 +323,8 @@ int TPpContext::CPPelse(int matchelse, TPpToken * ppToken)
 | 
				
			|||||||
            --ifdepth;
 | 
					            --ifdepth;
 | 
				
			||||||
        } else if (matchelse && depth == 0) {
 | 
					        } else if (matchelse && depth == 0) {
 | 
				
			||||||
            if (atom == elseAtom ) {
 | 
					            if (atom == elseAtom ) {
 | 
				
			||||||
 | 
					                token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
 | 
				
			||||||
                // found the #else we are looking for
 | 
					                // 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;
 | 
					                break;
 | 
				
			||||||
            } else if (atom == elifAtom) {
 | 
					            } else if (atom == elifAtom) {
 | 
				
			||||||
                /* we decrement ifdepth here, because CPPif will increment
 | 
					                /* we decrement ifdepth here, because CPPif will increment
 | 
				
			||||||
@ -308,9 +337,46 @@ int TPpContext::CPPelse(int matchelse, TPpToken * ppToken)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return CPPif(ppToken);
 | 
					                return CPPif(ppToken);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if ((atom == elseAtom) && (!ChkCorrectElseNesting()))
 | 
					        } else if (atom == elseAtom || atom == elifAtom) {
 | 
				
			||||||
 | 
					            if (! ChkCorrectElseNesting()) {
 | 
				
			||||||
 | 
					                if (atom == elseAtom)
 | 
				
			||||||
                    parseContext.error(ppToken->loc, "#else after #else", "#else", "");
 | 
					                    parseContext.error(ppToken->loc, "#else after #else", "#else", "");
 | 
				
			||||||
    };  // end while
 | 
					                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;
 | 
					    return token;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -503,17 +569,12 @@ int TPpContext::CPPif (TPpToken * ppToken)
 | 
				
			|||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    token = eval(token, MIN_PREC, &res, &err, ppToken);
 | 
					    token = eval(token, MIN_PREC, &res, &err, ppToken);
 | 
				
			||||||
    if (token != '\n') {
 | 
					    token = extraTokenCheck(ifAtom, ppToken, token);
 | 
				
			||||||
        parseContext.warn(ppToken->loc, "unexpected tokens following #if directive - expected a newline", "#if", "");
 | 
					    if (!res && !err)
 | 
				
			||||||
        while (token != '\n')
 | 
					 | 
				
			||||||
            token = currentInput->scan(this, currentInput, ppToken);
 | 
					 | 
				
			||||||
    } 
 | 
					 | 
				
			||||||
    if (!res && !err) {
 | 
					 | 
				
			||||||
        token = CPPelse(1, ppToken);
 | 
					        token = CPPelse(1, ppToken);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return token;
 | 
					    return token;
 | 
				
			||||||
} // CPPif
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int TPpContext::CPPifdef(int defined, TPpToken * ppToken)
 | 
					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)
 | 
					        if (((s && !s->mac.undef) ? 1 : 0) != defined)
 | 
				
			||||||
            token = CPPelse(1, ppToken);
 | 
					            token = CPPelse(1, ppToken);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return token;
 | 
					    return token;
 | 
				
			||||||
} // CPPifdef
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Handle #line
 | 
					// Handle #line
 | 
				
			||||||
int TPpContext::CPPline(TPpToken * ppToken) 
 | 
					int TPpContext::CPPline(TPpToken * ppToken) 
 | 
				
			||||||
@ -746,15 +808,9 @@ int TPpContext::readCPPline(TPpToken * ppToken)
 | 
				
			|||||||
            token = CPPdefine(ppToken);
 | 
					            token = CPPdefine(ppToken);
 | 
				
			||||||
        } else if (ppToken->atom == elseAtom) {
 | 
					        } else if (ppToken->atom == elseAtom) {
 | 
				
			||||||
            if (ChkCorrectElseNesting()) {
 | 
					            if (ChkCorrectElseNesting()) {
 | 
				
			||||||
                if (! ifdepth) {
 | 
					                if (! ifdepth)
 | 
				
			||||||
                    parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
 | 
					                    parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
 | 
				
			||||||
                }
 | 
					                token = extraTokenCheck(elseAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
 | 
				
			||||||
                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 = CPPelse(0, ppToken);
 | 
					                token = CPPelse(0, ppToken);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                parseContext.error(ppToken->loc, "#else after a #else", "#else", "");
 | 
					                parseContext.error(ppToken->loc, "#else after a #else", "#else", "");
 | 
				
			||||||
@ -762,9 +818,8 @@ int TPpContext::readCPPline(TPpToken * ppToken)
 | 
				
			|||||||
                return 0;
 | 
					                return 0;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if (ppToken->atom == elifAtom) {
 | 
					        } else if (ppToken->atom == elifAtom) {
 | 
				
			||||||
            if (! ifdepth) {
 | 
					            if (! ifdepth)
 | 
				
			||||||
                parseContext.error(ppToken->loc, "mismatched statements", "#elif", "");
 | 
					                parseContext.error(ppToken->loc, "mismatched statements", "#elif", "");
 | 
				
			||||||
            } 
 | 
					 | 
				
			||||||
            // this token is really a dont care, but we still need to eat the tokens
 | 
					            // this token is really a dont care, but we still need to eat the tokens
 | 
				
			||||||
            token = currentInput->scan(this, currentInput, ppToken); 
 | 
					            token = currentInput->scan(this, currentInput, ppToken); 
 | 
				
			||||||
            while (token != '\n')
 | 
					            while (token != '\n')
 | 
				
			||||||
@ -777,6 +832,7 @@ int TPpContext::readCPPline(TPpToken * ppToken)
 | 
				
			|||||||
                parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
 | 
					                parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                --ifdepth;
 | 
					                --ifdepth;
 | 
				
			||||||
 | 
					            token = extraTokenCheck(endifAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
 | 
				
			||||||
        } else if (ppToken->atom == ifAtom) {
 | 
					        } else if (ppToken->atom == ifAtom) {
 | 
				
			||||||
            token = CPPif (ppToken);
 | 
					            token = CPPif (ppToken);
 | 
				
			||||||
        } else if (ppToken->atom == ifdefAtom) {
 | 
					        } else if (ppToken->atom == ifdefAtom) {
 | 
				
			||||||
@ -800,12 +856,12 @@ int TPpContext::readCPPline(TPpToken * ppToken)
 | 
				
			|||||||
            parseContext.error(ppToken->loc, "Invalid Directive", "#", GetAtomString(ppToken->atom));
 | 
					            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);
 | 
					        token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return token;
 | 
					    return token;
 | 
				
			||||||
} // readCPPline
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TPpContext::FreeMacro(MacroSymbol *s) {
 | 
					void TPpContext::FreeMacro(MacroSymbol *s) {
 | 
				
			||||||
    DeleteTokenStream(s->body);
 | 
					    DeleteTokenStream(s->body);
 | 
				
			||||||
@ -843,9 +899,10 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken *
 | 
				
			|||||||
        token = ReadToken(a, ppToken);
 | 
					        token = ReadToken(a, ppToken);
 | 
				
			||||||
        if (token == CPP_IDENTIFIER && LookUpSymbol(ppToken->atom))
 | 
					        if (token == CPP_IDENTIFIER && LookUpSymbol(ppToken->atom))
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
    } while (token > 0);
 | 
					    } while (token != EOF);
 | 
				
			||||||
    if (token <= 0) return a;
 | 
					    if (token == EOF)
 | 
				
			||||||
    n = NewTokenStream("macro arg", 0);
 | 
					        return a;
 | 
				
			||||||
 | 
					    n = NewTokenStream(0);
 | 
				
			||||||
    PushEofSrc();
 | 
					    PushEofSrc();
 | 
				
			||||||
    ReadFromTokenStream(a, 0, 0);
 | 
					    ReadFromTokenStream(a, 0, 0);
 | 
				
			||||||
    while ((token = currentInput->scan(this, currentInput, ppToken)) > 0) {
 | 
					    while ((token = currentInput->scan(this, currentInput, ppToken)) > 0) {
 | 
				
			||||||
@ -855,14 +912,15 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken *
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    PopEofSrc();
 | 
					    PopEofSrc();
 | 
				
			||||||
    DeleteTokenStream(a);
 | 
					    DeleteTokenStream(a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return n;
 | 
					    return n;
 | 
				
			||||||
} // PrescanMacroArg
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// These are called through function pointers
 | 
					// These are called through function pointers
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* macro_scan ---
 | 
					/* 
 | 
				
			||||||
** return the next token for a macro expansion, handling macro args 
 | 
					** return the next token for a macro expansion, handling macro args 
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
int TPpContext::macro_scan(TPpContext* pp, TPpContext::InputSrc* inInput, TPpToken* ppToken) 
 | 
					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;
 | 
					    TPpContext::MacroInputSrc* in = (TPpContext::MacroInputSrc*)inInput;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int i;
 | 
					    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) {
 | 
					    if (token == CPP_IDENTIFIER) {
 | 
				
			||||||
        for (i = in->mac->argc-1; i>=0; i--)
 | 
					        for (i = in->mac->argc-1; i>=0; i--)
 | 
				
			||||||
            if (in->mac->args[i] == ppToken->atom) 
 | 
					            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;
 | 
					        return token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    in->mac->busy = 0;
 | 
					    in->mac->busy = 0;
 | 
				
			||||||
@ -895,7 +957,7 @@ int TPpContext::macro_scan(TPpContext* pp, TPpContext::InputSrc* inInput, TPpTok
 | 
				
			|||||||
    free(in);
 | 
					    free(in);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return pp->currentInput->scan(pp, pp->currentInput, ppToken);
 | 
					    return pp->currentInput->scan(pp, pp->currentInput, ppToken);
 | 
				
			||||||
} // macro_scan
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// return a zero, for scanning a macro that was never defined
 | 
					// return a zero, for scanning a macro that was never defined
 | 
				
			||||||
int TPpContext::zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken* ppToken) 
 | 
					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;
 | 
					    return CPP_INTCONSTANT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* MacroExpand
 | 
					/*
 | 
				
			||||||
** Check an identifier (atom) to see if it is 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
 | 
					** If it is, push an InputSrc that will produce the appropriate expansion
 | 
				
			||||||
** and return 1.
 | 
					** 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 *));
 | 
					        in->args = (TokenStream**)malloc(in->mac->argc * sizeof(TokenStream *));
 | 
				
			||||||
        for (i = 0; i < in->mac->argc; i++)
 | 
					        for (i = 0; i < in->mac->argc; i++)
 | 
				
			||||||
            in->args[i] = NewTokenStream("macro arg", 0);
 | 
					            in->args[i] = NewTokenStream(0);
 | 
				
			||||||
        i = 0;
 | 
					        i = 0;
 | 
				
			||||||
        j = 0;
 | 
					        j = 0;
 | 
				
			||||||
        do {
 | 
					        do {
 | 
				
			||||||
@ -1034,15 +1096,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
 | 
				
			|||||||
            in->args[i] = PrescanMacroArg(in->args[i], ppToken);
 | 
					            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*/
 | 
					    /*retain the input source*/
 | 
				
			||||||
    in->base.prev = currentInput;
 | 
					    in->base.prev = currentInput;
 | 
				
			||||||
    sym->mac.busy = 1;
 | 
					    sym->mac.busy = 1;
 | 
				
			||||||
@ -1050,7 +1104,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
 | 
				
			|||||||
    currentInput = &in->base;
 | 
					    currentInput = &in->base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
} // MacroExpand
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int TPpContext::ChkCorrectElseNesting()
 | 
					int TPpContext::ChkCorrectElseNesting()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -150,8 +150,12 @@ const char *TPpContext::GetAtomString(int atom)
 | 
				
			|||||||
        return "<null atom>";
 | 
					        return "<null atom>";
 | 
				
			||||||
    if (atom < 0)
 | 
					    if (atom < 0)
 | 
				
			||||||
        return "<EOF>";
 | 
					        return "<EOF>";
 | 
				
			||||||
    if ((size_t)atom < stringMap.size())
 | 
					    if ((size_t)atom < stringMap.size()) {
 | 
				
			||||||
 | 
					        if (stringMap[atom] == 0)
 | 
				
			||||||
 | 
					            return "<invalid atom>";
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
            return stringMap[atom]->c_str();
 | 
					            return stringMap[atom]->c_str();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return "<invalid atom>";
 | 
					    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;
 | 
					    TAtomMap::const_iterator it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
 | 
				
			||||||
    if (stringMap.size() < (size_t)atom + 1)
 | 
					    if (stringMap.size() < (size_t)atom + 1)
 | 
				
			||||||
        stringMap.resize(atom + 100);
 | 
					        stringMap.resize(atom + 100, 0);
 | 
				
			||||||
    stringMap[atom] = &it->first;
 | 
					    stringMap[atom] = &it->first;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return atom;
 | 
					    return atom;
 | 
				
			||||||
 | 
				
			|||||||
@ -106,9 +106,9 @@ void TPpContext::setInput(TInputScanner& input, bool versionWillBeError)
 | 
				
			|||||||
    StringInputSrc *in = (StringInputSrc *)malloc(sizeof(StringInputSrc));
 | 
					    StringInputSrc *in = (StringInputSrc *)malloc(sizeof(StringInputSrc));
 | 
				
			||||||
    memset(in, 0, sizeof(StringInputSrc));
 | 
					    memset(in, 0, sizeof(StringInputSrc));
 | 
				
			||||||
    in->input = &input;
 | 
					    in->input = &input;
 | 
				
			||||||
    in->base.scan = byte_scan;
 | 
					    in->base.scan = sourceScan;
 | 
				
			||||||
    in->base.getch = (int (*)(TPpContext*, InputSrc *, TPpToken *))str_getch;
 | 
					    in->base.getch = (int (*)(TPpContext*, InputSrc *, TPpToken *))sourceGetCh;
 | 
				
			||||||
    in->base.ungetch = (void (*)(TPpContext*, InputSrc *, int, TPpToken *))str_ungetch;
 | 
					    in->base.ungetch = (void (*)(TPpContext*, InputSrc *, int, TPpToken *))sourceUngetCh;
 | 
				
			||||||
    in->base.prev = currentInput;
 | 
					    in->base.prev = currentInput;
 | 
				
			||||||
    currentInput = &in->base;
 | 
					    currentInput = &in->base;
 | 
				
			||||||
    errorOnVersion = versionWillBeError;
 | 
					    errorOnVersion = versionWillBeError;
 | 
				
			||||||
 | 
				
			|||||||
@ -84,7 +84,21 @@ namespace glslang {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class TPpToken {
 | 
					class TPpToken {
 | 
				
			||||||
public:
 | 
					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;
 | 
					    static const int maxTokenLength = 1024;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TSourceLoc loc;
 | 
					    TSourceLoc loc;
 | 
				
			||||||
@ -110,6 +124,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const char* tokenize(TPpToken* ppToken);
 | 
					    const char* tokenize(TPpToken* ppToken);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: preprocessor simplification: this should be a base class, not a set of function pointers
 | 
				
			||||||
    struct InputSrc {
 | 
					    struct InputSrc {
 | 
				
			||||||
        struct InputSrc	*prev;
 | 
					        struct InputSrc	*prev;
 | 
				
			||||||
        int			(*scan)(TPpContext*, struct InputSrc *, TPpToken *);
 | 
					        int			(*scan)(TPpContext*, struct InputSrc *, TPpToken *);
 | 
				
			||||||
@ -127,7 +142,6 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    struct TokenStream {
 | 
					    struct TokenStream {
 | 
				
			||||||
        TokenStream *next;
 | 
					        TokenStream *next;
 | 
				
			||||||
        char *name;
 | 
					 | 
				
			||||||
        TokenBlock *head;
 | 
					        TokenBlock *head;
 | 
				
			||||||
        TokenBlock *current;
 | 
					        TokenBlock *current;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@ -231,6 +245,7 @@ protected:
 | 
				
			|||||||
    int CPPdefine(TPpToken * ppToken);
 | 
					    int CPPdefine(TPpToken * ppToken);
 | 
				
			||||||
    int CPPundef(TPpToken * ppToken);
 | 
					    int CPPundef(TPpToken * ppToken);
 | 
				
			||||||
    int CPPelse(int matchelse, 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 eval(int token, int prec, int *res, int *err, TPpToken * ppToken);
 | 
				
			||||||
    int CPPif (TPpToken * ppToken); 
 | 
					    int CPPif (TPpToken * ppToken); 
 | 
				
			||||||
    int CPPifdef(int defined, TPpToken * ppToken);
 | 
					    int CPPifdef(int defined, TPpToken * ppToken);
 | 
				
			||||||
@ -259,18 +274,16 @@ protected:
 | 
				
			|||||||
    //
 | 
					    //
 | 
				
			||||||
    // From PpTokens.cpp
 | 
					    // From PpTokens.cpp
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    char* idstr(const char *fstr, MemoryPool *pool);
 | 
					 | 
				
			||||||
    TPpContext::TokenBlock* lNewBlock(TokenStream *fTok, MemoryPool *pool);
 | 
					    TPpContext::TokenBlock* lNewBlock(TokenStream *fTok, MemoryPool *pool);
 | 
				
			||||||
    void lAddByte(TokenStream *fTok, unsigned char fVal);
 | 
					    void lAddByte(TokenStream *fTok, unsigned char fVal);
 | 
				
			||||||
    int lReadByte(TokenStream *pTok);
 | 
					    int lReadByte(TokenStream *pTok);
 | 
				
			||||||
    TokenStream *NewTokenStream(const char *name, MemoryPool *pool);
 | 
					    TokenStream *NewTokenStream(MemoryPool *pool);
 | 
				
			||||||
    void DeleteTokenStream(TokenStream *pTok);
 | 
					    void DeleteTokenStream(TokenStream *pTok);
 | 
				
			||||||
    void RecordToken(TokenStream* pTok, int token, TPpToken* ppToken);
 | 
					    void RecordToken(TokenStream* pTok, int token, TPpToken* ppToken);
 | 
				
			||||||
    void RewindTokenStream(TokenStream *pTok);
 | 
					    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 *));
 | 
					    int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(TPpContext *));
 | 
				
			||||||
    void UngetToken(int token, TPpToken* ppToken);
 | 
					    void UngetToken(int token, TPpToken* ppToken);
 | 
				
			||||||
    void DumpTokenStream(FILE *fp, TokenStream *s, TPpToken * ppToken);
 | 
					 | 
				
			||||||
    struct TokenInputSrc {
 | 
					    struct TokenInputSrc {
 | 
				
			||||||
        InputSrc            base;
 | 
					        InputSrc            base;
 | 
				
			||||||
        TokenStream *tokens;
 | 
					        TokenStream *tokens;
 | 
				
			||||||
@ -292,12 +305,12 @@ protected:
 | 
				
			|||||||
        TInputScanner* input;
 | 
					        TInputScanner* input;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    int InitScanner(TPpContext *cpp);
 | 
					    int InitScanner(TPpContext *cpp);
 | 
				
			||||||
    static int str_getch(TPpContext*, StringInputSrc *in);
 | 
					    static int sourceGetCh(TPpContext*, StringInputSrc *in);
 | 
				
			||||||
    static void str_ungetch(TPpContext*, StringInputSrc *in, int ch, TPpToken *type);
 | 
					    static void sourceUngetCh(TPpContext*, StringInputSrc *in, int ch, TPpToken *type);
 | 
				
			||||||
    int ScanFromString(char *s);
 | 
					    int ScanFromString(char *s);
 | 
				
			||||||
    int check_EOF(int token);
 | 
					    bool check_EOF(int token);
 | 
				
			||||||
    int lFloatConst(char *str, int len, int ch, TPpToken * ppToken);
 | 
					    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
 | 
					    // From PpAtom.cpp
 | 
				
			||||||
 | 
				
			|||||||
@ -105,7 +105,7 @@ int TPpContext::InitScanner(TPpContext *cpp)
 | 
				
			|||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int TPpContext::str_getch(TPpContext* pp, StringInputSrc *in)
 | 
					int TPpContext::sourceGetCh(TPpContext* pp, StringInputSrc *in)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ch = in->input->get();
 | 
					    int ch = in->input->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,7 +115,7 @@ int TPpContext::str_getch(TPpContext* pp, StringInputSrc *in)
 | 
				
			|||||||
    return ch;
 | 
					    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();
 | 
					    in->input->unget();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -241,13 +241,12 @@ int TPpContext::lFloatConst(char *str, int len, int ch, TPpToken * ppToken)
 | 
				
			|||||||
        return CPP_DOUBLECONSTANT;
 | 
					        return CPP_DOUBLECONSTANT;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        return CPP_FLOATCONSTANT;
 | 
					        return CPP_FLOATCONSTANT;
 | 
				
			||||||
} // lFloatConst
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
///////////////////////////////////////////////////////////////////////////////////////////////
 | 
					//
 | 
				
			||||||
///////////////////////////////////////// Normal Scanner //////////////////////////////////////
 | 
					// Scanner used to tokenize source stream.
 | 
				
			||||||
///////////////////////////////////////////////////////////////////////////////////////////////
 | 
					//
 | 
				
			||||||
 | 
					int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
 | 
				
			||||||
int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * ppToken)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char tokenText[TPpToken::maxTokenLength + 1];
 | 
					    char tokenText[TPpToken::maxTokenLength + 1];
 | 
				
			||||||
    int AlreadyComplained = 0;
 | 
					    int AlreadyComplained = 0;
 | 
				
			||||||
@ -268,8 +267,6 @@ int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * ppToken)
 | 
				
			|||||||
        switch (ch) {
 | 
					        switch (ch) {
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            return ch; // Single character token
 | 
					            return ch; // Single character token
 | 
				
			||||||
        case EOF:
 | 
					 | 
				
			||||||
            return EOF;
 | 
					 | 
				
			||||||
        case 'A': case 'B': case 'C': case 'D': case 'E':
 | 
					        case 'A': case 'B': case 'C': case 'D': case 'E':
 | 
				
			||||||
        case 'F': case 'G': case 'H': case 'I': case 'J':
 | 
					        case 'F': case 'G': case 'H': case 'I': case 'J':
 | 
				
			||||||
        case 'K': case 'L': case 'M': case 'N': case 'O':
 | 
					        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)
 | 
					const char* TPpContext::tokenize(TPpToken* ppToken)
 | 
				
			||||||
{    
 | 
					{    
 | 
				
			||||||
    int token = '\n';
 | 
					    int token = '\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(;;) {
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        const char* tokenString = 0;
 | 
					        const char* tokenString = 0;
 | 
				
			||||||
        token = currentInput->scan(this, currentInput, ppToken);
 | 
					        token = currentInput->scan(this, currentInput, ppToken);
 | 
				
			||||||
        ppToken->token = token;
 | 
					        ppToken->token = token;
 | 
				
			||||||
@ -742,7 +742,13 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
 | 
				
			|||||||
        else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
 | 
					        else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
 | 
				
			||||||
                 token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
 | 
					                 token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
 | 
				
			||||||
            tokenString = ppToken->name;
 | 
					            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);
 | 
					            tokenString = GetAtomString(token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (tokenString) {
 | 
					        if (tokenString) {
 | 
				
			||||||
@ -752,19 +758,19 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
 | 
				
			|||||||
            return tokenString;
 | 
					            return tokenString;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
} // PpTokenize
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Checks if the token just read is EOF or not.
 | 
					//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 (token == EOF) {
 | 
				
			||||||
        if (ifdepth > 0)
 | 
					        if (ifdepth > 0)
 | 
				
			||||||
            parseContext.error(parseContext.getCurrentLoc(), "missing #endif", "#if", "");
 | 
					            parseContext.error(parseContext.getCurrentLoc(), "missing #endif", "", "");
 | 
				
			||||||
        return 1;
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // end namespace glslang
 | 
					} // end namespace glslang
 | 
				
			||||||
 | 
				
			|||||||
@ -75,9 +75,11 @@ NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
 | 
				
			|||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 | 
					TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 | 
				
			||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					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
 | 
					#ifdef _WIN32
 | 
				
			||||||
#define _CRT_SECURE_NO_WARNINGS
 | 
					#define _CRT_SECURE_NO_WARNINGS
 | 
				
			||||||
#define snprintf sprintf_s
 | 
					#define snprintf sprintf_s
 | 
				
			||||||
@ -94,43 +96,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace glslang {
 | 
					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)
 | 
					TPpContext::TokenBlock* TPpContext::lNewBlock(TokenStream *fTok, MemoryPool *pool)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TokenBlock *lBlock;
 | 
					    TokenBlock *lBlock;
 | 
				
			||||||
@ -152,12 +117,7 @@ TPpContext::TokenBlock* TPpContext::lNewBlock(TokenStream *fTok, MemoryPool *poo
 | 
				
			|||||||
    fTok->current = lBlock;
 | 
					    fTok->current = lBlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return lBlock;
 | 
					    return lBlock;
 | 
				
			||||||
} // lNewBlock
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
* lAddByte()
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
 | 
					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)
 | 
					    if (lBlock->count >= lBlock->max)
 | 
				
			||||||
        lBlock = lNewBlock(fTok, 0);
 | 
					        lBlock = lNewBlock(fTok, 0);
 | 
				
			||||||
    lBlock->data[lBlock->count++] = fVal;
 | 
					    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)
 | 
					int TPpContext::lReadByte(TokenStream *pTok)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TokenBlock *lBlock;
 | 
					    TokenBlock *lBlock;
 | 
				
			||||||
@ -191,16 +148,12 @@ int TPpContext::lReadByte(TokenStream *pTok)
 | 
				
			|||||||
            lval = lBlock->data[lBlock->current++];
 | 
					            lval = lBlock->data[lBlock->current++];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return lval;
 | 
					    return lval;
 | 
				
			||||||
} // lReadByte
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/////////////////////////////////////// Global Functions://////////////////////////////////////
 | 
					//
 | 
				
			||||||
 | 
					// Make a token stream (used for reprocessing macros).
 | 
				
			||||||
/*
 | 
					//
 | 
				
			||||||
* NewTokenStream()
 | 
					TPpContext::TokenStream* TPpContext::NewTokenStream(MemoryPool *pool)
 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TPpContext::TokenStream* TPpContext::NewTokenStream(const char *name, MemoryPool *pool)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TokenStream *pTok;
 | 
					    TokenStream *pTok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -209,17 +162,11 @@ TPpContext::TokenStream* TPpContext::NewTokenStream(const char *name, MemoryPool
 | 
				
			|||||||
    else
 | 
					    else
 | 
				
			||||||
        pTok = (TokenStream*)mem_Alloc(pool, sizeof(TokenStream));
 | 
					        pTok = (TokenStream*)mem_Alloc(pool, sizeof(TokenStream));
 | 
				
			||||||
    pTok->next = NULL;
 | 
					    pTok->next = NULL;
 | 
				
			||||||
    pTok->name = idstr(name, pool);
 | 
					 | 
				
			||||||
    pTok->head = NULL;
 | 
					    pTok->head = NULL;
 | 
				
			||||||
    pTok->current = NULL;
 | 
					    pTok->current = NULL;
 | 
				
			||||||
    lNewBlock(pTok, pool);
 | 
					    lNewBlock(pTok, pool);
 | 
				
			||||||
    return pTok;
 | 
					    return pTok;
 | 
				
			||||||
} // NewTokenStream
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
* DeleteTokenStream()
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TPpContext::DeleteTokenStream(TokenStream *pTok)
 | 
					void TPpContext::DeleteTokenStream(TokenStream *pTok)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -232,17 +179,13 @@ void TPpContext::DeleteTokenStream(TokenStream *pTok)
 | 
				
			|||||||
            free(pBlock);
 | 
					            free(pBlock);
 | 
				
			||||||
            pBlock = nBlock;
 | 
					            pBlock = nBlock;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (pTok->name)
 | 
					 | 
				
			||||||
            free(pTok->name);
 | 
					 | 
				
			||||||
        free(pTok);
 | 
					        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;
 | 
					    const char *s;
 | 
				
			||||||
@ -254,7 +197,6 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken * ppToken)
 | 
				
			|||||||
        lAddByte(pTok, (unsigned char)(token & 0x7f));
 | 
					        lAddByte(pTok, (unsigned char)(token & 0x7f));
 | 
				
			||||||
    switch (token) {
 | 
					    switch (token) {
 | 
				
			||||||
    case CPP_IDENTIFIER:
 | 
					    case CPP_IDENTIFIER:
 | 
				
			||||||
    case CPP_TYPEIDENTIFIER:
 | 
					 | 
				
			||||||
    case CPP_STRCONSTANT:
 | 
					    case CPP_STRCONSTANT:
 | 
				
			||||||
        s = GetAtomString(ppToken->atom);
 | 
					        s = GetAtomString(ppToken->atom);
 | 
				
			||||||
        while (*s)
 | 
					        while (*s)
 | 
				
			||||||
@ -274,33 +216,28 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken * ppToken)
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case '(':
 | 
					    case '(':
 | 
				
			||||||
        lAddByte(pTok, (unsigned char)(ppToken->ival ? 1 : 0));
 | 
					        lAddByte(pTok, (unsigned char)(ppToken->ival ? 1 : 0));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} // RecordToken
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
* RewindTokenStream() - Reset a token stream in preperation for reading.
 | 
					* Reset a token stream in preperation for reading.
 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					 | 
				
			||||||
void TPpContext::RewindTokenStream(TokenStream *pTok)
 | 
					void TPpContext::RewindTokenStream(TokenStream *pTok)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (pTok->head) {
 | 
					    if (pTok->head) {
 | 
				
			||||||
        pTok->current = pTok->head;
 | 
					        pTok->current = pTok->head;
 | 
				
			||||||
        pTok->current->current = 0;
 | 
					        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)
 | 
					int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    //TODO: preprocessor simplification: why is this different than byte_scan
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char tokenText[TPpToken::maxTokenLength + 1];
 | 
					    char tokenText[TPpToken::maxTokenLength + 1];
 | 
				
			||||||
    int ltoken, len;
 | 
					    int ltoken, len;
 | 
				
			||||||
    char ch;
 | 
					    char ch;
 | 
				
			||||||
@ -311,89 +248,56 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
 | 
				
			|||||||
        if (ltoken > 127)
 | 
					        if (ltoken > 127)
 | 
				
			||||||
            ltoken += 128;
 | 
					            ltoken += 128;
 | 
				
			||||||
        switch (ltoken) {
 | 
					        switch (ltoken) {
 | 
				
			||||||
 | 
					        case '(':
 | 
				
			||||||
 | 
					            ppToken->ival = lReadByte(pTok);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case CPP_STRCONSTANT:
 | 
				
			||||||
        case CPP_IDENTIFIER:
 | 
					        case CPP_IDENTIFIER:
 | 
				
			||||||
        case CPP_TYPEIDENTIFIER:
 | 
					        case CPP_FLOATCONSTANT:
 | 
				
			||||||
 | 
					        case CPP_DOUBLECONSTANT:
 | 
				
			||||||
 | 
					        case CPP_INTCONSTANT:
 | 
				
			||||||
 | 
					        case CPP_UINTCONSTANT:
 | 
				
			||||||
            len = 0;
 | 
					            len = 0;
 | 
				
			||||||
            ch = lReadByte(pTok);
 | 
					            ch = lReadByte(pTok);
 | 
				
			||||||
            while ((ch >= 'a' && ch <= 'z') ||
 | 
					            while (ch != 0) {
 | 
				
			||||||
                (ch >= 'A' && ch <= 'Z') ||
 | 
					 | 
				
			||||||
                (ch >= '0' && ch <= '9') ||
 | 
					 | 
				
			||||||
                ch == '_')
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (len < TPpToken::maxTokenLength) {
 | 
					                if (len < TPpToken::maxTokenLength) {
 | 
				
			||||||
                    tokenText[len] = ch;
 | 
					                    tokenText[len] = ch;
 | 
				
			||||||
                    len++;
 | 
					                    len++;
 | 
				
			||||||
                    ch = lReadByte(pTok);
 | 
					                    ch = lReadByte(pTok);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    parseContext.error(ppToken->loc,"name too long", "", "");
 | 
					                    parseContext.error(ppToken->loc, "token too long", "", "");
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            tokenText[len] = '\0';
 | 
					 | 
				
			||||||
            assert(ch == '\0');
 | 
					 | 
				
			||||||
            ppToken->atom = LookUpAddString(tokenText);
 | 
					 | 
				
			||||||
            return CPP_IDENTIFIER;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case CPP_STRCONSTANT:
 | 
					 | 
				
			||||||
            len = 0;
 | 
					 | 
				
			||||||
            while ((ch = lReadByte(pTok)) != 0) {
 | 
					 | 
				
			||||||
                if (len < TPpToken::maxTokenLength)
 | 
					 | 
				
			||||||
                    tokenText[len++] = ch;
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            tokenText[len] = 0;
 | 
					            tokenText[len] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (ltoken) {
 | 
				
			||||||
 | 
					            case CPP_IDENTIFIER:
 | 
				
			||||||
 | 
					            case CPP_STRCONSTANT:
 | 
				
			||||||
                ppToken->atom = LookUpAddString(tokenText);
 | 
					                ppToken->atom = LookUpAddString(tokenText);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case CPP_FLOATCONSTANT:
 | 
					            case CPP_FLOATCONSTANT:
 | 
				
			||||||
            case CPP_DOUBLECONSTANT:
 | 
					            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);
 | 
					                strcpy(ppToken->name, tokenText);
 | 
				
			||||||
                ppToken->dval = atof(ppToken->name);
 | 
					                ppToken->dval = atof(ppToken->name);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case CPP_INTCONSTANT:
 | 
					            case CPP_INTCONSTANT:
 | 
				
			||||||
            case CPP_UINTCONSTANT:
 | 
					            case CPP_UINTCONSTANT:
 | 
				
			||||||
            len = 0;
 | 
					 | 
				
			||||||
            ch = lReadByte(pTok);
 | 
					 | 
				
			||||||
            while ((ch >= '0' && ch <= '9') || ch == 'u' || ch == 'U')
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (len < TPpToken::maxTokenLength) {
 | 
					 | 
				
			||||||
                    tokenText[len] = ch;
 | 
					 | 
				
			||||||
                    len++;
 | 
					 | 
				
			||||||
                    ch = lReadByte(pTok);
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    parseContext.error(ppToken->loc,"integer literal too long", "", "");
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            tokenText[len] = '\0';
 | 
					 | 
				
			||||||
            assert(ch == '\0');
 | 
					 | 
				
			||||||
                strcpy(ppToken->name, tokenText);
 | 
					                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);
 | 
					                    ppToken->ival = atoi(ppToken->name);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
        case '(':
 | 
					            }
 | 
				
			||||||
            ppToken->ival = lReadByte(pTok);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return ltoken;
 | 
					        return ltoken;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return EOF;
 | 
					    return EOF;
 | 
				
			||||||
} // ReadToken
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int TPpContext::scan_token(TPpContext* pp, TokenInputSrc *in, TPpToken * ppToken)
 | 
					int TPpContext::scan_token(TPpContext* pp, TokenInputSrc *in, TPpToken * ppToken)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -434,8 +338,6 @@ int TPpContext::reget_token(TPpContext* pp, UngotToken *t, TPpToken * ppToken)
 | 
				
			|||||||
    return token;
 | 
					    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));
 | 
					    UngotToken *t = (UngotToken *) malloc(sizeof(UngotToken));
 | 
				
			||||||
@ -447,38 +349,4 @@ void TPpContext::UngetToken(int token, TPpToken * ppToken)
 | 
				
			|||||||
    currentInput = &t->base;
 | 
					    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
 | 
					} // end namespace glslang
 | 
				
			||||||
 | 
				
			|||||||
@ -99,7 +99,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			|||||||
#define CPP_OR_OP          276
 | 
					#define CPP_OR_OP          276
 | 
				
			||||||
#define CPP_INC_OP         277
 | 
					#define CPP_INC_OP         277
 | 
				
			||||||
#define CPP_STRCONSTANT    278
 | 
					#define CPP_STRCONSTANT    278
 | 
				
			||||||
#define CPP_TYPEIDENTIFIER 279
 | 
					 | 
				
			||||||
#define CPP_RIGHT_ASSIGN   280
 | 
					#define CPP_RIGHT_ASSIGN   280
 | 
				
			||||||
#define CPP_LEFT_ASSIGN    281
 | 
					#define CPP_LEFT_ASSIGN    281
 | 
				
			||||||
#define CPP_AND_ASSIGN     282
 | 
					#define CPP_AND_ASSIGN     282
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user