1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

fix bug 70073

This commit is contained in:
Andrew Niefer 2004-08-12 19:44:54 +00:00
parent 2b19fdf07e
commit df84ae7f47
3 changed files with 121 additions and 22 deletions

View file

@ -1822,4 +1822,20 @@ public class Scanner2Test extends BaseScanner2Test
assertTrue( callback.problems.isEmpty() ); assertTrue( callback.problems.isEmpty() );
} }
public void testBug70073() throws Exception
{
StringBuffer buffer = new StringBuffer( "#if CONST \n #endif \n #elif CONST \n int" ); //$NON-NLS-1$
final List problems = new ArrayList();
ISourceElementRequestor requestor = new NullSourceElementRequestor() {
public boolean acceptProblem(IProblem problem)
{
problems.add( problem );
return super.acceptProblem( problem );
}
};
initializeScanner( buffer.toString(), ParserMode.COMPLETE_PARSE, requestor );
validateToken( IToken.t_int );
assertEquals( problems.size(), 1 );
}
} }

View file

@ -120,7 +120,13 @@ public class CharTable extends HashTable {
final public boolean containsKey( char[] key ){ final public boolean containsKey( char[] key ){
return lookup( key ) != -1; return lookup( key ) != -1;
} }
final public char[] findKey( char[] buffer, int start, int len ){
int idx = lookup( buffer, start, len );
if( idx == -1 )
return null;
return keyTable[ idx ];
}
protected int lookup(char[] buffer ){ protected int lookup(char[] buffer ){
return lookup(buffer, 0, buffer.length); return lookup(buffer, 0, buffer.length);
} }

View file

@ -101,6 +101,16 @@ public class Scanner2 implements IScanner, IScannerData {
private int[] bufferLimit = new int[bufferInitialSize]; private int[] bufferLimit = new int[bufferInitialSize];
private int[] bufferLineNums = new int[bufferInitialSize]; private int[] bufferLineNums = new int[bufferInitialSize];
//branch tracking
private int branchStackPos = -1;
private int[] branches = new int[bufferInitialSize];
//states
final static private int BRANCH_IF = 1;
final static private int BRANCH_ELIF = 2;
final static private int BRANCH_ELSE = 3;
final static private int BRANCH_END = 4;
// Utility // Utility
private static String[] emptyStringArray = new String[0]; private static String[] emptyStringArray = new String[0];
private static char[] emptyCharArray = new char[0]; private static char[] emptyCharArray = new char[0];
@ -1113,6 +1123,42 @@ public class Scanner2 implements IScanner, IScannerData {
return newToken( tokenType, result ); return newToken( tokenType, result );
} }
private boolean branchState( int state ){
if( state != BRANCH_IF && branchStackPos == -1 )
return false;
switch( state ){
case BRANCH_IF:
if( ++branchStackPos == branches.length ){
int [] temp = new int [ branches.length << 1 ];
System.arraycopy( branches, 0, temp, 0, branches.length );
}
branches[branchStackPos] = BRANCH_IF;
return true;
case BRANCH_ELIF:
case BRANCH_ELSE:
switch( branches[branchStackPos] ){
case BRANCH_IF:
case BRANCH_ELIF:
branches[branchStackPos] = state;
return true;
default:
return false;
}
case BRANCH_END:
switch( branches[branchStackPos] ){
case BRANCH_IF:
case BRANCH_ELSE:
case BRANCH_ELIF:
--branchStackPos;
return true;
default:
return false;
}
}
return false;
}
private void handlePPDirective(int pos) throws ScannerException, EndOfFileException { private void handlePPDirective(int pos) throws ScannerException, EndOfFileException {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -1169,6 +1215,7 @@ public class Scanner2 implements IScanner, IScannerData {
len = bufferPos[bufferStackPos] - start; len = bufferPos[bufferStackPos] - start;
if( isLimitReached() ) if( isLimitReached() )
handleCompletionOnExpression( CharArrayUtils.extract( buffer, start, len ) ); handleCompletionOnExpression( CharArrayUtils.extract( buffer, start, len ) );
branchState( BRANCH_IF );
if (expressionEvaluator.evaluate(buffer, start, len, definitions) == 0) { if (expressionEvaluator.evaluate(buffer, start, len, definitions) == 0) {
if (dlog != null) dlog.println("#if <FALSE> " + new String(buffer,start+1,len-1)); //$NON-NLS-1$ if (dlog != null) dlog.println("#if <FALSE> " + new String(buffer,start+1,len-1)); //$NON-NLS-1$
skipOverConditionalCode(true); skipOverConditionalCode(true);
@ -1180,14 +1227,23 @@ public class Scanner2 implements IScanner, IScannerData {
case ppElse: case ppElse:
case ppElif: case ppElif:
// Condition must have been true, skip over the rest // Condition must have been true, skip over the rest
skipToNewLine();
skipOverConditionalCode(false); if( branchState( type == ppElse ? BRANCH_ELSE : BRANCH_ELIF) ){
skipToNewLine();
skipOverConditionalCode(false);
} else {
handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION, start, ppKeywords.findKey( buffer, start, len ) );
skipToNewLine();
}
if( isLimitReached() ) if( isLimitReached() )
handleInvalidCompletion(); handleInvalidCompletion();
return; return;
case ppError: case ppError:
throw new ScannerException(null); throw new ScannerException(null);
case ppEndif: case ppEndif:
if( !branchState( BRANCH_END ) )
handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION, start, ppKeywords.findKey( buffer, start, len ) );
break; break;
default: default:
problem = true; problem = true;
@ -1649,6 +1705,8 @@ public class Scanner2 implements IScanner, IScannerData {
skipToNewLine(); skipToNewLine();
branchState( BRANCH_IF );
if ((definitions.get(buffer, idstart, idlen) != null) == positive) { if ((definitions.get(buffer, idstart, idlen) != null) == positive) {
if (dlog != null) dlog.println((positive ? "#ifdef" : "#ifndef") //$NON-NLS-1$ //$NON-NLS-2$ if (dlog != null) dlog.println((positive ? "#ifdef" : "#ifndef") //$NON-NLS-1$ //$NON-NLS-2$
+ " <TRUE> " + new String(buffer, idstart, idlen)); //$NON-NLS-1$ + " <TRUE> " + new String(buffer, idstart, idlen)); //$NON-NLS-1$
@ -1705,31 +1763,50 @@ public class Scanner2 implements IScanner, IScannerData {
case ppIfndef: case ppIfndef:
case ppIf: case ppIf:
++nesting; ++nesting;
branchState( BRANCH_IF );
break; break;
case ppElse: case ppElse:
if (checkelse && nesting == 0) { if( branchState( BRANCH_ELSE ) ){
skipToNewLine(); if (checkelse && nesting == 0) {
return; skipToNewLine();
} return;
}
} else {
//problem, ignore this one.
handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION, start, ppKeywords.findKey( buffer, start, len ) );
skipToNewLine();
}
break; break;
case ppElif: case ppElif:
if (checkelse && nesting == 0) { if( branchState( BRANCH_ELIF ) ){
// check the condition if (checkelse && nesting == 0) {
start = bufferPos[bufferStackPos]; // check the condition
skipToNewLine(); start = bufferPos[bufferStackPos];
len = bufferPos[bufferStackPos] - start; skipToNewLine();
if (expressionEvaluator.evaluate(buffer, start, len, definitions) != 0) len = bufferPos[bufferStackPos] - start;
// condition passed, we're good if (expressionEvaluator.evaluate(buffer, start, len, definitions) != 0)
return; // condition passed, we're good
} return;
}
} else {
//problem, ignore this one.
handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION, start, ppKeywords.findKey( buffer, start, len ) );
skipToNewLine();
}
break; break;
case ppEndif: case ppEndif:
if (nesting > 0) { if( branchState( BRANCH_END ) ){
--nesting; if (nesting > 0) {
} else { --nesting;
skipToNewLine(); } else {
return; skipToNewLine();
} return;
}
} else {
//problem, ignore this one.
handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION, start, ppKeywords.findKey( buffer, start, len ) );
skipToNewLine();
}
break; break;
} }
} }