diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMPreprocessorInformationTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMPreprocessorInformationTest.java index 4c4ad259e21..aef20526926 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMPreprocessorInformationTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMPreprocessorInformationTest.java @@ -8,12 +8,14 @@ * * Contributors: * Emanuel Graf - initial API and implementation + * Markus Schorn (Wind River Systems) ******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorErrorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorFunctionStyleMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfStatement; @@ -100,7 +102,7 @@ public class DOMPreprocessorInformationTest extends AST2BaseTest { public void testPragmaWithSpaces() throws Exception { String msg = "GCC poison printf sprintf fprintf"; - StringBuffer buffer = new StringBuffer( "# pragma " + msg + "\n" ); //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer( "# pragma " + msg + " \n" ); //$NON-NLS-1$ IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); IASTPreprocessorStatement[] st = tu.getAllPreprocessorStatements(); assertEquals(1, st.length); @@ -111,7 +113,7 @@ public class DOMPreprocessorInformationTest extends AST2BaseTest { public void testElIfWithSpaces() throws Exception { String cond = "2 == 2"; - StringBuffer buffer = new StringBuffer( "#if 1 == 2\n# elif " + cond + "\n#else\n#endif\n" ); //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer( "#if 1 == 2\n# elif " + cond + " \n#else\n#endif\n" ); //$NON-NLS-1$ IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); IASTPreprocessorStatement[] st = tu.getAllPreprocessorStatements(); assertEquals(4, st.length); @@ -122,7 +124,7 @@ public class DOMPreprocessorInformationTest extends AST2BaseTest { public void testIfWithSpaces() throws Exception { String cond = "2 == 2"; - StringBuffer buffer = new StringBuffer( "# if " + cond + "\n#endif\n" ); //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer( "# if " + cond + " \n#endif\n" ); //$NON-NLS-1$ IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); IASTPreprocessorStatement[] st = tu.getAllPreprocessorStatements(); assertEquals(2, st.length); @@ -133,7 +135,7 @@ public class DOMPreprocessorInformationTest extends AST2BaseTest { public void testIfDefWithSpaces() throws Exception{ String cond = "SYMBOL"; - StringBuffer buffer = new StringBuffer( "# ifdef " + cond + "\n#endif\n" ); //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer( "# ifdef " + cond + " \n#endif\n" ); //$NON-NLS-1$ IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); IASTPreprocessorStatement[] st = tu.getAllPreprocessorStatements(); assertEquals(2, st.length); @@ -144,7 +146,7 @@ public class DOMPreprocessorInformationTest extends AST2BaseTest { public void testIfnDefWithSpaces() throws Exception{ String cond = "SYMBOL"; - StringBuffer buffer = new StringBuffer( "# ifndef " + cond + "\n#endif\n" ); //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer( "# ifndef " + cond + "\t\n#endif\n" ); //$NON-NLS-1$ IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); IASTPreprocessorStatement[] st = tu.getAllPreprocessorStatements(); assertEquals(2, st.length); @@ -155,7 +157,7 @@ public class DOMPreprocessorInformationTest extends AST2BaseTest { public void testErrorWithSpaces() throws Exception{ String msg = "Message"; - StringBuffer buffer = new StringBuffer( "# error " + msg + "\n" ); //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer( "# error \t" + msg + " \n" ); //$NON-NLS-1$ IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP, false, false ); IASTPreprocessorStatement[] st = tu.getAllPreprocessorStatements(); assertEquals(1, st.length); @@ -188,4 +190,22 @@ public class DOMPreprocessorInformationTest extends AST2BaseTest { assertEquals("bar", new String(actualParameters[1])); } + // #ifdef xxx + // #elif + // #endif + public void testElifWithoutCondition_bug185324() throws Exception { + StringBuffer code= getContents(1)[0]; + IASTTranslationUnit tu = parse(code.toString(), ParserLanguage.CPP, false, false, true); + IASTPreprocessorStatement[] st = tu.getAllPreprocessorStatements(); + assertEquals(3, st.length); + assertTrue(st[0] instanceof IASTPreprocessorIfdefStatement); + IASTPreprocessorIfdefStatement ifdef = (IASTPreprocessorIfdefStatement) st[0]; + assertEquals("xxx", new String(ifdef.getCondition())); + + assertTrue(st[1] instanceof IASTPreprocessorElifStatement); + IASTPreprocessorElifStatement elif = (IASTPreprocessorElifStatement) st[1]; + assertEquals("", new String(elif.getCondition())); + + assertTrue(st[2] instanceof IASTPreprocessorEndifStatement); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java index 9839663c614..cdf93ecd667 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java @@ -398,15 +398,12 @@ public class DOMScanner extends BaseScanner { */ protected void processIfdef(int startPos, int endPos, boolean positive, boolean taken) { + final char[] condition= extractPreprocessorCondition(bufferStack[bufferStackPos], startPos, endPos); if (positive){ - int startCond = startPos + 7 + countSpaces(startPos); - char[] condition = CharArrayUtils.extract(bufferStack[bufferStackPos], startCond, endPos - startCond); locationMap.encounterPoundIfdef(getGlobalOffset(startPos), getGlobalOffset(endPos), taken, condition); } else{ - int startCond = startPos + 8 + countSpaces(startPos); - char[] condition = CharArrayUtils.extract(bufferStack[bufferStackPos], startCond, endPos - startCond); locationMap.encounterPoundIfndef(getGlobalOffset(startPos), getGlobalOffset(endPos), taken, condition); } @@ -420,8 +417,7 @@ public class DOMScanner extends BaseScanner { * int, boolean) */ protected void processIf(int startPos, int endPos, boolean taken) { - int startCond = startPos + 4 + countSpaces(startPos); - char[] condition = CharArrayUtils.extract(bufferStack[bufferStackPos], startCond, endPos - startCond); + final char[] condition= extractPreprocessorCondition(bufferStack[bufferStackPos], startPos, endPos); locationMap.encounterPoundIf(getGlobalOffset(startPos), getGlobalOffset(endPos), taken, condition); } @@ -433,8 +429,7 @@ public class DOMScanner extends BaseScanner { * int, boolean) */ protected void processElsif(int startPos, int endPos, boolean taken) { - int startCond = startPos + 6 + countSpaces(startPos); - char[] condition = CharArrayUtils.extract(bufferStack[bufferStackPos], startCond, endPos - startCond); + final char[] condition= extractPreprocessorCondition(bufferStack[bufferStackPos], startPos, endPos); locationMap.encounterPoundElif(getGlobalOffset(startPos), getGlobalOffset(endPos), taken, condition); } @@ -471,8 +466,7 @@ public class DOMScanner extends BaseScanner { * int) */ protected void processError(int startPos, int endPos) { - int start = startPos+7 + countSpaces(startPos); - char[] msg = CharArrayUtils.extract(bufferStack[bufferStackPos], start, endPos- start); + final char[] msg= extractPreprocessorCondition(bufferStack[bufferStackPos], startPos, endPos); locationMap.encounterPoundError(getGlobalOffset(startPos), getGlobalOffset(endPos), msg); } @@ -481,21 +475,64 @@ public class DOMScanner extends BaseScanner { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processWarning(int, int) */ protected void processWarning(int startPos, int endPos) { - int start = startPos+9 + countSpaces(startPos); - char[] msg = CharArrayUtils.extract(bufferStack[bufferStackPos], start, endPos - start); + final char[] msg= extractPreprocessorCondition(bufferStack[bufferStackPos], startPos, endPos); locationMap.encounterPoundWarning(getGlobalOffset(startPos), getGlobalOffset(endPos), msg); } - private int countSpaces(int startPos) { - int spaces = 0; - while(bufferStack[bufferStackPos][startPos + spaces + 1] == ' ' || bufferStack[bufferStackPos][startPos + spaces + 1] == '\t' ) { - ++spaces; + private char[] extractPreprocessorCondition(final char[] buffer, int from, int to) { + if (buffer[from] == '#') { + from= skipWhiteSpace(buffer, from+1, to); + from= skipNonWhiteSpace(buffer, from, to); + from= skipWhiteSpace(buffer, from, to); + to= reverseSkipWhiteSpace(buffer, to-1, from-1)+1; + return CharArrayUtils.extract(buffer, from, to-from); } - return spaces; + return CharArrayUtils.EMPTY; } - /* + + private int skipWhiteSpace(char[] buffer, int from, int to) { + while (from < to) { + char c= buffer[from]; + switch(c) { + case ' ': case '\r': case '\n': case '\t': + break; + default: + return from; + } + from++; + } + return from; + } + + private int skipNonWhiteSpace(char[] buffer, int from, int to) { + while (from < to) { + char c= buffer[from]; + switch(c) { + case ' ': case '\r': case '\n': case '\t': + return from; + } + from++; + } + return from; + } + + private int reverseSkipWhiteSpace(char[] buffer, int from, int to) { + while (from > to) { + char c= buffer[from]; + switch(c) { + case ' ': case '\r': case '\n': case '\t': + break; + default: + return from; + } + from--; + } + return from; + } + + /* * (non-Javadoc) * * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processEndif(int, @@ -512,8 +549,7 @@ public class DOMScanner extends BaseScanner { * int) */ protected void processPragma(int startPos, int endPos) { - int startCond = startPos + 8 + countSpaces(startPos); - char[] msg = CharArrayUtils.extract(bufferStack[bufferStackPos], startCond, endPos - (startCond)); + final char[] msg= extractPreprocessorCondition(bufferStack[bufferStackPos], startPos, endPos); locationMap.encounterPoundPragma(getGlobalOffset(startPos), getGlobalOffset(endPos), msg); }