mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Test case and fix for 157009, scanner skips line.
This commit is contained in:
parent
3541fc9e5a
commit
fdabd9645c
3 changed files with 70 additions and 58 deletions
|
@ -137,7 +137,7 @@ public class AST2BaseTest extends TestCase {
|
||||||
else if ( lang == ParserLanguage.CPP && expectNoProblems )
|
else if ( lang == ParserLanguage.CPP && expectNoProblems )
|
||||||
{
|
{
|
||||||
assertEquals( CPPVisitor.getProblems(tu).length, 0 );
|
assertEquals( CPPVisitor.getProblems(tu).length, 0 );
|
||||||
assertEquals( tu.getPreprocessorProblems().length, 0 );
|
assertEquals( 0, tu.getPreprocessorProblems().length);
|
||||||
}
|
}
|
||||||
if( expectNoProblems )
|
if( expectNoProblems )
|
||||||
assertEquals( 0, tu.getPreprocessorProblems().length );
|
assertEquals( 0, tu.getPreprocessorProblems().length );
|
||||||
|
|
|
@ -647,4 +647,24 @@ public class DOMLocationTests extends AST2BaseTest {
|
||||||
assertSoleLocation( funC, buffer.toString().indexOf("C::C(int ii, double id)\ntry\n: i(f(ii)), d(id)"), "C::C(int ii, double id)\ntry\n: i(f(ii)), d(id)".length() ); //$NON-NLS-1$//$NON-NLS-2$
|
assertSoleLocation( funC, buffer.toString().indexOf("C::C(int ii, double id)\ntry\n: i(f(ii)), d(id)"), "C::C(int ii, double id)\ntry\n: i(f(ii)), d(id)".length() ); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug157009_1() throws Exception {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("#ifndef A\r\n#error X\r\n#else\r\n#error Y\r\n#endif");
|
||||||
|
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, false, false);
|
||||||
|
|
||||||
|
IASTProblem[] problems= tu.getPreprocessorProblems();
|
||||||
|
assertEquals(1, problems.length);
|
||||||
|
assertSoleLocation(problems[0], buffer.indexOf("X"), "X".length() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBug157009_2() throws Exception {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("#ifndef A\n#error X\n#else\n#error Y\n#endif");
|
||||||
|
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, false, false);
|
||||||
|
|
||||||
|
IASTProblem[] problems= tu.getPreprocessorProblems();
|
||||||
|
assertEquals(1, problems.length);
|
||||||
|
assertSoleLocation(problems[0], buffer.indexOf("X"), "X".length() );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2602,7 +2602,6 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (start >= limit || buffer[start] == '\n')
|
if (start >= limit || buffer[start] == '\n')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean problem = false;
|
|
||||||
char c = buffer[start];
|
char c = buffer[start];
|
||||||
if ((c >= 'a' && c <= 'z')) {
|
if ((c >= 'a' && c <= 'z')) {
|
||||||
while (++bufferPos[bufferStackPos] < limit) {
|
while (++bufferPos[bufferStackPos] < limit) {
|
||||||
|
@ -2616,7 +2615,8 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (isLimitReached())
|
if (isLimitReached())
|
||||||
handleCompletionOnPreprocessorDirective(new String(buffer, pos,
|
handleCompletionOnPreprocessorDirective(new String(buffer, pos,
|
||||||
len + 1));
|
len + 1));
|
||||||
|
|
||||||
|
int end;
|
||||||
int type = ppKeywords.get(buffer, start, len);
|
int type = ppKeywords.get(buffer, start, len);
|
||||||
if (type != ppKeywords.undefined) {
|
if (type != ppKeywords.undefined) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -2638,10 +2638,11 @@ abstract class BaseScanner implements IScanner {
|
||||||
case ppIfndef:
|
case ppIfndef:
|
||||||
handlePPIfdef(pos, false);
|
handlePPIfdef(pos, false);
|
||||||
return;
|
return;
|
||||||
case ppIf:
|
case ppIf:
|
||||||
start = bufferPos[bufferStackPos] + 1;
|
start = bufferPos[bufferStackPos]+1;
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
len = bufferPos[bufferStackPos] - start;
|
end= bufferPos[bufferStackPos]+1;
|
||||||
|
len = end - start;
|
||||||
if (isLimitReached())
|
if (isLimitReached())
|
||||||
handleCompletionOnExpression(CharArrayUtils.extract(
|
handleCompletionOnExpression(CharArrayUtils.extract(
|
||||||
buffer, start, len));
|
buffer, start, len));
|
||||||
|
@ -2649,14 +2650,14 @@ abstract class BaseScanner implements IScanner {
|
||||||
|
|
||||||
if (expressionEvaluator.evaluate(buffer, start, len,
|
if (expressionEvaluator.evaluate(buffer, start, len,
|
||||||
definitions,
|
definitions,
|
||||||
getLineNumber(bufferPos[bufferStackPos]),
|
getLineNumber(start),
|
||||||
getCurrentFilename()) == 0) {
|
getCurrentFilename()) == 0) {
|
||||||
processIf(pos, bufferPos[bufferStackPos], false);
|
processIf(pos, end, false);
|
||||||
skipOverConditionalCode(true);
|
skipOverConditionalCode(true);
|
||||||
if (isLimitReached())
|
if (isLimitReached())
|
||||||
handleInvalidCompletion();
|
handleInvalidCompletion();
|
||||||
} else {
|
} else {
|
||||||
processIf(pos, bufferPos[bufferStackPos], true);
|
processIf(pos, end, true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case ppElse:
|
case ppElse:
|
||||||
|
@ -2664,12 +2665,12 @@ abstract class BaseScanner implements IScanner {
|
||||||
// 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)) {
|
if (branchState(type == ppElse ? BRANCH_ELSE : BRANCH_ELIF)) {
|
||||||
|
skipToNewLine();
|
||||||
if (type == ppElse)
|
if (type == ppElse)
|
||||||
processElse(pos, bufferPos[bufferStackPos] + 1,
|
processElse(pos, bufferPos[bufferStackPos] + 1,
|
||||||
false);
|
false);
|
||||||
else
|
else
|
||||||
processElsif(pos, bufferPos[bufferStackPos], false);
|
processElsif(pos, bufferPos[bufferStackPos] + 1, false);
|
||||||
skipToNewLine();
|
|
||||||
skipOverConditionalCode(false);
|
skipOverConditionalCode(false);
|
||||||
} else {
|
} else {
|
||||||
handleProblem(
|
handleProblem(
|
||||||
|
@ -2685,39 +2686,32 @@ abstract class BaseScanner implements IScanner {
|
||||||
skipOverWhiteSpace();
|
skipOverWhiteSpace();
|
||||||
start = bufferPos[bufferStackPos] + 1;
|
start = bufferPos[bufferStackPos] + 1;
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
if (bufferPos[bufferStackPos] - 1 > 0
|
end= bufferPos[bufferStackPos] + 1;
|
||||||
&& buffer[bufferPos[bufferStackPos] - 1] == '\r')
|
|
||||||
len = bufferPos[bufferStackPos] - start - 1;
|
|
||||||
else
|
|
||||||
len = bufferPos[bufferStackPos] - start;
|
|
||||||
handleProblem(IProblem.PREPROCESSOR_POUND_ERROR, start,
|
handleProblem(IProblem.PREPROCESSOR_POUND_ERROR, start,
|
||||||
CharArrayUtils.extract(buffer, start, len));
|
CharArrayUtils.extract(buffer, start, end-start));
|
||||||
processError(pos, pos + len);
|
processError(pos, end);
|
||||||
break;
|
return;
|
||||||
case ppEndif:
|
case ppEndif:
|
||||||
if (!branchState(BRANCH_END))
|
skipToNewLine();
|
||||||
|
if (branchState(BRANCH_END)) {
|
||||||
|
processEndif(pos, bufferPos[bufferStackPos] + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
handleProblem(
|
handleProblem(
|
||||||
IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
|
IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
|
||||||
start, ppKeywords.findKey(buffer, start, len));
|
start, ppKeywords.findKey(buffer, start, len));
|
||||||
processEndif(pos, bufferPos[bufferStackPos] + 1);
|
}
|
||||||
break;
|
return;
|
||||||
case ppPragma:
|
case ppPragma:
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
processPragma(pos, bufferPos[bufferStackPos]);
|
processPragma(pos, bufferPos[bufferStackPos]+1);
|
||||||
break;
|
return;
|
||||||
default:
|
|
||||||
problem = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
problem = true;
|
|
||||||
|
// directive was not handled, create a problem
|
||||||
if (problem)
|
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, start, null);
|
||||||
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, start, null);
|
|
||||||
|
|
||||||
// don't know, chew up to the end of line
|
|
||||||
// includes endif which is immatereal at this point
|
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2871,7 +2865,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
char[] fileNameArray = filename.toCharArray();
|
char[] fileNameArray = filename.toCharArray();
|
||||||
// TODO else we need to do macro processing on the rest of the line
|
// TODO else we need to do macro processing on the rest of the line
|
||||||
endLine = getLineNumber(bufferPos[bufferStackPos]);
|
endLine = getLineNumber(bufferPos[bufferStackPos]);
|
||||||
skipToNewLine(false, true);
|
skipToNewLine();
|
||||||
|
|
||||||
findAndPushInclusion(filename, fileNameArray, local, include_next, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
|
findAndPushInclusion(filename, fileNameArray, local, include_next, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
|
||||||
}
|
}
|
||||||
|
@ -3341,7 +3335,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
|
|
||||||
|
|
||||||
Object definition = definitions.remove(buffer, idstart, idlen);
|
Object definition = definitions.remove(buffer, idstart, idlen);
|
||||||
processUndef(pos, bufferPos[bufferStackPos], CharArrayUtils.extract(buffer, idstart, idlen ), idstart, definition);
|
processUndef(pos, bufferPos[bufferStackPos]+1, CharArrayUtils.extract(buffer, idstart, idlen ), idstart, definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3402,11 +3396,11 @@ abstract class BaseScanner implements IScanner {
|
||||||
branchState(BRANCH_IF);
|
branchState(BRANCH_IF);
|
||||||
|
|
||||||
if ((definitions.get(buffer, idstart, idlen) != null) == positive) {
|
if ((definitions.get(buffer, idstart, idlen) != null) == positive) {
|
||||||
processIfdef(pos, bufferPos[bufferStackPos], positive, true);
|
processIfdef(pos, bufferPos[bufferStackPos]+1, positive, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
processIfdef(pos, bufferPos[bufferStackPos], positive, false);
|
processIfdef(pos, bufferPos[bufferStackPos]+1, positive, false);
|
||||||
// skip over this group
|
// skip over this group
|
||||||
skipOverConditionalCode(true);
|
skipOverConditionalCode(true);
|
||||||
if (isLimitReached())
|
if (isLimitReached())
|
||||||
|
@ -3462,12 +3456,12 @@ abstract class BaseScanner implements IScanner {
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
if (type == ppIfdef)
|
if (type == ppIfdef)
|
||||||
processIfdef(startPos,
|
processIfdef(startPos,
|
||||||
bufferPos[bufferStackPos], true, false);
|
bufferPos[bufferStackPos]+1, true, false);
|
||||||
else if (type == ppIfndef)
|
else if (type == ppIfndef)
|
||||||
processIfdef(startPos,
|
processIfdef(startPos,
|
||||||
bufferPos[bufferStackPos], false, false);
|
bufferPos[bufferStackPos]+1, false, false);
|
||||||
else
|
else
|
||||||
processIf(startPos, bufferPos[bufferStackPos],
|
processIf(startPos, bufferPos[bufferStackPos]+1,
|
||||||
false);
|
false);
|
||||||
break;
|
break;
|
||||||
case ppElse:
|
case ppElse:
|
||||||
|
@ -3475,11 +3469,11 @@ abstract class BaseScanner implements IScanner {
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
if (checkelse && nesting == 0) {
|
if (checkelse && nesting == 0) {
|
||||||
processElse(startPos,
|
processElse(startPos,
|
||||||
bufferPos[bufferStackPos], true);
|
bufferPos[bufferStackPos]+1, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
processElse(startPos,
|
processElse(startPos,
|
||||||
bufferPos[bufferStackPos], false);
|
bufferPos[bufferStackPos]+1, false);
|
||||||
} else {
|
} else {
|
||||||
//problem, ignore this one.
|
//problem, ignore this one.
|
||||||
handleProblem(
|
handleProblem(
|
||||||
|
@ -3495,26 +3489,24 @@ abstract class BaseScanner implements IScanner {
|
||||||
// check the condition
|
// check the condition
|
||||||
start = bufferPos[bufferStackPos] + 1;
|
start = bufferPos[bufferStackPos] + 1;
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
len = bufferPos[bufferStackPos] - start;
|
int end= bufferPos[bufferStackPos] + 1;
|
||||||
|
len= end - start;
|
||||||
if (expressionEvaluator
|
if (expressionEvaluator
|
||||||
.evaluate(
|
.evaluate(
|
||||||
buffer,
|
buffer,
|
||||||
start,
|
start,
|
||||||
len,
|
len,
|
||||||
definitions,
|
definitions,
|
||||||
getLineNumber(bufferPos[bufferStackPos]),
|
getLineNumber(start),
|
||||||
getCurrentFilename()) != 0) {
|
getCurrentFilename()) != 0) {
|
||||||
// condition passed, we're good
|
// condition passed, we're good
|
||||||
processElsif(startPos,
|
processElsif(startPos, end, true);
|
||||||
bufferPos[bufferStackPos], true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
processElsif(startPos,
|
processElsif(startPos, end, false);
|
||||||
bufferPos[bufferStackPos], false);
|
|
||||||
} else {
|
} else {
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
processElsif(startPos,
|
processElsif(startPos, bufferPos[bufferStackPos] + 1, false);
|
||||||
bufferPos[bufferStackPos], false);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//problem, ignore this one.
|
//problem, ignore this one.
|
||||||
|
@ -3573,7 +3565,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (pos + 1 < limit) {
|
if (pos + 1 < limit) {
|
||||||
if (buffer[pos + 1] == '/') {
|
if (buffer[pos + 1] == '/') {
|
||||||
// C++ comment, skip rest of line
|
// C++ comment, skip rest of line
|
||||||
skipToNewLine(true, true);
|
skipToNewLine(true);
|
||||||
return false;
|
return false;
|
||||||
} else if (buffer[pos + 1] == '*') {
|
} else if (buffer[pos + 1] == '*') {
|
||||||
// C comment, find closing */
|
// C comment, find closing */
|
||||||
|
@ -3915,13 +3907,13 @@ abstract class BaseScanner implements IScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void skipToNewLine() {
|
protected void skipToNewLine() {
|
||||||
skipToNewLine(false, false);
|
skipToNewLine(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips everything up to the next newline.
|
* Skips everything up to the next newline.
|
||||||
*/
|
*/
|
||||||
protected void skipToNewLine(boolean insideComment, boolean stopBefore) {
|
protected void skipToNewLine(boolean insideComment) {
|
||||||
char[] buffer = bufferStack[bufferStackPos];
|
char[] buffer = bufferStack[bufferStackPos];
|
||||||
int limit = bufferLimit[bufferStackPos];
|
int limit = bufferLimit[bufferStackPos];
|
||||||
int pos = bufferPos[bufferStackPos];
|
int pos = bufferPos[bufferStackPos];
|
||||||
|
@ -3959,7 +3951,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (escaped) {
|
if (escaped) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bufferPos[bufferStackPos]= stopBefore ? pos-1 : pos;
|
bufferPos[bufferStackPos]= pos-1;
|
||||||
return;
|
return;
|
||||||
case '\r':
|
case '\r':
|
||||||
if (pos+1 < limit && buffer[pos+1] == '\n') {
|
if (pos+1 < limit && buffer[pos+1] == '\n') {
|
||||||
|
@ -3967,7 +3959,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
pos++;
|
pos++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bufferPos[bufferStackPos]= stopBefore ? pos-1 : pos;
|
bufferPos[bufferStackPos]= pos-1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3976,7 +3968,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
}
|
}
|
||||||
escaped = false;
|
escaped = false;
|
||||||
}
|
}
|
||||||
bufferPos[bufferStackPos]= stopBefore ? pos-1 : pos;
|
bufferPos[bufferStackPos]= pos-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected char[] handleFunctionStyleMacro(FunctionStyleMacro macro,
|
protected char[] handleFunctionStyleMacro(FunctionStyleMacro macro,
|
||||||
|
|
Loading…
Add table
Reference in a new issue