mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
bug 73652: [Scanner] Macro replacement confusion
This commit is contained in:
parent
440ada9bab
commit
645b3306eb
2 changed files with 113 additions and 6 deletions
|
@ -1737,14 +1737,48 @@ public class Scanner2Test extends BaseScanner2Test
|
|||
StringWriter writer = new StringWriter();
|
||||
writer.write( "#define DoSuperMethodA IDoSuperMethodA\n" ); //$NON-NLS-1$
|
||||
writer.write( "#define IDoSuperMethodA(a,b,c) IIntuition->IDoSuperMethodA(a,b,c)\n" ); //$NON-NLS-1$
|
||||
writer.write( "void hang(void)\n" ); //$NON-NLS-1$
|
||||
writer.write( "{\n" ); //$NON-NLS-1$
|
||||
writer.write( "DoSuperMethodA(0,0,0);\n" ); //$NON-NLS-1$
|
||||
writer.write( "}\n" ); //$NON-NLS-1$
|
||||
|
||||
initializeScanner( writer.toString() );
|
||||
fullyTokenize();
|
||||
|
||||
validateIdentifier( "IIntuition" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tARROW );
|
||||
validateIdentifier( "IDoSuperMethodA" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tLPAREN );
|
||||
validateInteger( "0" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tCOMMA );
|
||||
validateInteger( "0" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tCOMMA );
|
||||
validateInteger( "0" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tRPAREN );
|
||||
validateToken( IToken.tSEMI );
|
||||
validateEOF();
|
||||
}
|
||||
|
||||
public void testBug73652_2() throws Exception{
|
||||
StringWriter writer = new StringWriter();
|
||||
writer.write( "#define DoSuperMethodA DoSuperMethodB //doobalie\n" ); //$NON-NLS-1$
|
||||
writer.write( "#define DoSuperMethodB DoSuperMethodC /*oogalie*/ \n" ); //$NON-NLS-1$
|
||||
writer.write( "#define DoSuperMethodC IDoSuperMethodA \\\n\n" ); //$NON-NLS-1$
|
||||
writer.write( "#define IDoSuperMethodA(a,b,c) IIntuition->IDoSuperMethodA(a,b,c)\n" ); //$NON-NLS-1$
|
||||
writer.write( "DoSuperMethodA (0,0,0);\n" ); //$NON-NLS-1$
|
||||
|
||||
initializeScanner( writer.toString() );
|
||||
|
||||
validateIdentifier( "IIntuition" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tARROW );
|
||||
validateIdentifier( "IDoSuperMethodA" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tLPAREN );
|
||||
validateInteger( "0" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tCOMMA );
|
||||
validateInteger( "0" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tCOMMA );
|
||||
validateInteger( "0" ); //$NON-NLS-1$
|
||||
validateToken( IToken.tRPAREN );
|
||||
validateToken( IToken.tSEMI );
|
||||
validateEOF();
|
||||
|
||||
}
|
||||
public void testBug72997() throws Exception
|
||||
{
|
||||
initializeScanner( "'\\\\'"); //$NON-NLS-1$
|
||||
|
|
|
@ -2139,6 +2139,51 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
return encounteredMultiLineComment;
|
||||
}
|
||||
|
||||
private int indexOfNextNonWhiteSpace( char[] buffer, int start, int limit ) {
|
||||
if( start < 0 || start >= buffer.length || limit > buffer.length )
|
||||
return -1;
|
||||
|
||||
int pos = start + 1;
|
||||
while( pos < limit ) {
|
||||
switch (buffer[pos++]) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
continue;
|
||||
case '/':
|
||||
if( pos < limit) {
|
||||
if( buffer[pos] == '/') {
|
||||
// C++ comment, skip rest of line
|
||||
while( ++pos < limit ){
|
||||
switch( buffer[pos] ){
|
||||
case '\\' : ++pos; break;
|
||||
case '\n' : break;
|
||||
}
|
||||
}
|
||||
} else if (buffer[pos] == '*') {
|
||||
// C comment, find closing */
|
||||
while( ++pos < limit ){
|
||||
if( buffer[pos] == '*' && pos + 1 < limit && buffer[pos+1] == '/' )
|
||||
{
|
||||
pos += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case '\\':
|
||||
if (pos < limit && (buffer[pos] == '\n' || buffer[pos] == '\r') ) {
|
||||
++pos;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// fell out of switch without continuing, we're done
|
||||
return --pos;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
private void skipOverNonWhiteSpace(){
|
||||
skipOverNonWhiteSpace( false );
|
||||
}
|
||||
|
@ -2367,8 +2412,36 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
skipOverWhiteSpace();
|
||||
}
|
||||
|
||||
if (++bufferPos[bufferStackPos] >= limit
|
||||
|| buffer[bufferPos[bufferStackPos]] != '(' )
|
||||
if( ++bufferPos[bufferStackPos] >= limit ){
|
||||
//allow a macro boundary cross here, but only if the caller was prepared to accept a bufferStackPos change
|
||||
if( pushContext )
|
||||
{
|
||||
int idx = -1;
|
||||
int stackpPos = bufferStackPos;
|
||||
while( bufferData[stackpPos] != null && bufferData[stackpPos] instanceof MacroData ){
|
||||
stackpPos--;
|
||||
if( stackpPos < 0 ) return emptyCharArray;
|
||||
idx = indexOfNextNonWhiteSpace( bufferStack[stackpPos], bufferPos[stackpPos], bufferLimit[stackpPos] );
|
||||
if( idx >= bufferLimit[stackpPos] ) continue;
|
||||
if( idx > 0 && bufferStack[stackpPos][idx] == '(' ) break;
|
||||
return emptyCharArray;
|
||||
}
|
||||
if( idx == -1 )
|
||||
return emptyCharArray;
|
||||
|
||||
MacroData data = (MacroData) bufferData[stackpPos+1];
|
||||
for( int i = bufferStackPos; i > stackpPos; i-- )
|
||||
popContext();
|
||||
|
||||
bufferPos[bufferStackPos] = idx;
|
||||
buffer = bufferStack[bufferStackPos];
|
||||
limit = bufferLimit[bufferStackPos];
|
||||
start = data.startOffset;
|
||||
} else {
|
||||
return emptyCharArray;
|
||||
}
|
||||
}
|
||||
if( buffer[bufferPos[bufferStackPos]] != '(' )
|
||||
return emptyCharArray;
|
||||
|
||||
char[][] arglist = macro.arglist;
|
||||
|
|
Loading…
Add table
Reference in a new issue