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:
parent
2b19fdf07e
commit
df84ae7f47
3 changed files with 121 additions and 22 deletions
|
@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
if( branchState( type == ppElse ? BRANCH_ELSE : BRANCH_ELIF) ){
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
skipOverConditionalCode(false);
|
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,14 +1763,22 @@ 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( branchState( BRANCH_ELSE ) ){
|
||||||
if (checkelse && nesting == 0) {
|
if (checkelse && nesting == 0) {
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
return;
|
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( branchState( BRANCH_ELIF ) ){
|
||||||
if (checkelse && nesting == 0) {
|
if (checkelse && nesting == 0) {
|
||||||
// check the condition
|
// check the condition
|
||||||
start = bufferPos[bufferStackPos];
|
start = bufferPos[bufferStackPos];
|
||||||
|
@ -1722,14 +1788,25 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
// condition passed, we're good
|
// condition passed, we're good
|
||||||
return;
|
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( branchState( BRANCH_END ) ){
|
||||||
if (nesting > 0) {
|
if (nesting > 0) {
|
||||||
--nesting;
|
--nesting;
|
||||||
} else {
|
} else {
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
//problem, ignore this one.
|
||||||
|
handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION, start, ppKeywords.findKey( buffer, start, len ) );
|
||||||
|
skipToNewLine();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue