mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
adding a bunch of tests for CPreprocessor, bug 213239
This commit is contained in:
parent
da6d9d1a66
commit
0d7a561440
3 changed files with 785 additions and 30 deletions
|
@ -12,6 +12,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
|
@ -34,6 +35,8 @@ import org.eclipse.cdt.internal.core.parser.ParserException;
|
|||
|
||||
public class DOMLocationMacroTests extends AST2BaseTest {
|
||||
|
||||
final ParserLanguage[] languages = new ParserLanguage[] { ParserLanguage.C, ParserLanguage.CPP };
|
||||
|
||||
public DOMLocationMacroTests() {
|
||||
}
|
||||
|
||||
|
@ -46,9 +49,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
StringBuffer buffer = new StringBuffer( "#define ABC D\n" ); //$NON-NLS-1$
|
||||
buffer.append( "int ABC;"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTPreprocessorObjectStyleMacroDefinition ABC = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
|
||||
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
|
||||
IASTDeclarator d = var.getDeclarators()[0];
|
||||
|
@ -73,9 +75,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
StringBuffer buffer = new StringBuffer( "#define ABC * D\n" ); //$NON-NLS-1$
|
||||
buffer.append( "int ABC;"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTPreprocessorObjectStyleMacroDefinition ABC = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
|
||||
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
|
||||
IASTDeclarator d = var.getDeclarators()[0];
|
||||
|
@ -121,9 +122,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
StringBuffer buffer = new StringBuffer( "#define XYZ const\n"); //$NON-NLS-1$
|
||||
buffer.append( "XYZ int var;"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTPreprocessorObjectStyleMacroDefinition defXYZ = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
|
||||
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
|
||||
IASTSimpleDeclSpecifier declSpec = (IASTSimpleDeclSpecifier) var.getDeclSpecifier();
|
||||
|
@ -152,9 +152,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
buffer.append( "int C_PO var;"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
|
||||
IASTPreprocessorMacroDefinition XYZ = macroDefinitions[0];
|
||||
IASTPreprocessorMacroDefinition PO = macroDefinitions[1];
|
||||
|
@ -188,9 +187,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
buffer.append( "XYZ IT C_PO C_PO V;"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTPreprocessorObjectStyleMacroDefinition XYZ = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
|
||||
// IASTPreprocessorObjectStyleMacroDefinition PO = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[1];
|
||||
IASTPreprocessorObjectStyleMacroDefinition C_PO = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[2];
|
||||
|
@ -239,9 +237,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
buffer.append( "_PTR _EXFUN(memchr,(const _PTR, int, size_t));\n"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p, true, true);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i], true, true);
|
||||
final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
|
||||
IASTPreprocessorObjectStyleMacroDefinition _PTR = (IASTPreprocessorObjectStyleMacroDefinition) macroDefinitions[0];
|
||||
IASTPreprocessorFunctionStyleMacroDefinition _EXFUN = (IASTPreprocessorFunctionStyleMacroDefinition) macroDefinitions[2];
|
||||
|
@ -282,9 +279,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
buffer.append( "#define ABC ghi\n"); //$NON-NLS-1$
|
||||
buffer.append( "int ABC;\n"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTPreprocessorMacroDefinition [] macros = tu.getMacroDefinitions();
|
||||
assertEquals( macros.length, 2 );
|
||||
IASTPreprocessorObjectStyleMacroDefinition ABC1 = (IASTPreprocessorObjectStyleMacroDefinition) macros[0];
|
||||
|
@ -318,9 +314,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
StringBuffer buffer = new StringBuffer( "#define MACRO mm\n"); //$NON-NLS-1$
|
||||
buffer.append( "int MACRO;\n"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTPreprocessorObjectStyleMacroDefinition MACRO = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
|
||||
IASTName macro_name = MACRO.getName();
|
||||
IMacroBinding binding = (IMacroBinding) macro_name.resolveBinding();
|
||||
|
@ -341,9 +336,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
buffer.append( "#define MYAPI API\n"); //$NON-NLS-1$
|
||||
buffer.append( "MYAPI void func() {}" ); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTFunctionDefinition f = (IASTFunctionDefinition) tu.getDeclarations()[0];
|
||||
assertNotNull( f.getFileLocation() );
|
||||
}
|
||||
|
@ -356,9 +350,8 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
buffer.append( "int var= FUNCTION(1);"); //$NON-NLS-1$
|
||||
String code = buffer.toString();
|
||||
|
||||
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
|
||||
: null) {
|
||||
IASTTranslationUnit tu = parse(code, p);
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
|
||||
IASTInitializerExpression initializer= (IASTInitializerExpression)var.getDeclarators()[0].getInitializer();
|
||||
IASTExpression expr= initializer.getExpression();
|
||||
|
@ -372,5 +365,119 @@ public class DOMLocationMacroTests extends AST2BaseTest {
|
|||
assertEquals("FUNCTION(1)".length(), expLocations[0].getNodeLength());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void assertMacroLocation(IASTDeclaration decl, int index, int length) {
|
||||
IASTSimpleDeclaration var = (IASTSimpleDeclaration) decl;
|
||||
IASTInitializerExpression initializer= (IASTInitializerExpression)var.getDeclarators()[0].getInitializer();
|
||||
IASTExpression expr= initializer.getExpression();
|
||||
assertNotNull(expr.getFileLocation());
|
||||
IASTNodeLocation [] locations = expr.getNodeLocations();
|
||||
assertEquals(1, locations.length);
|
||||
IASTMacroExpansion macroExpansion = (IASTMacroExpansion) locations[0];
|
||||
IASTNodeLocation[] expLocations= macroExpansion.getExpansionLocations();
|
||||
assertEquals(1, expLocations.length);
|
||||
IASTFileLocation fileLocation = expLocations[0].asFileLocation();
|
||||
assertEquals(index, fileLocation.getNodeOffset());
|
||||
assertEquals(length, fileLocation.getNodeLength());
|
||||
}
|
||||
|
||||
private void assertExpressionLocation(IASTDeclaration decl, int index, int length) {
|
||||
IASTSimpleDeclaration var = (IASTSimpleDeclaration) decl;
|
||||
IASTInitializerExpression initializer= (IASTInitializerExpression)var.getDeclarators()[0].getInitializer();
|
||||
IASTExpression expr= initializer.getExpression();
|
||||
IASTFileLocation fileLocation = expr.getFileLocation();
|
||||
assertNotNull(fileLocation);
|
||||
assertEquals(index, fileLocation.getNodeOffset());
|
||||
assertEquals(length, fileLocation.getNodeLength());
|
||||
}
|
||||
|
||||
|
||||
public void testBug186257() throws Exception {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("typedef char STR; \n"); //$NON-NLS-1$
|
||||
sb.append("#define Nullstr Null(STR*) \n"); //$NON-NLS-1$
|
||||
sb.append("#define Null(x) ((x)NULL) \n"); //$NON-NLS-1$
|
||||
sb.append("int x = Nullstr; \n"); //$NON-NLS-1$
|
||||
sb.append("int y = whatever; \n"); //$NON-NLS-1$
|
||||
String code = sb.toString();
|
||||
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTDeclaration[] decls = tu.getDeclarations();
|
||||
assertMacroLocation(decls[1], code.indexOf("Nullstr;"), "Nullstr".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertExpressionLocation(decls[2], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testArgumentExpansion() throws Exception {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("#define ADD(a,b, c) (a) + (b) + (c) \n"); //$NON-NLS-1$
|
||||
sb.append("#define ONEYONENOE 111111 \n"); //$NON-NLS-1$
|
||||
sb.append("#define TWO 2 \n"); //$NON-NLS-1$
|
||||
sb.append("#define THREE 3 \n"); //$NON-NLS-1$
|
||||
sb.append("int x = ADD(ONEYONENOE,TWO, THREE); \n"); //$NON-NLS-1$
|
||||
sb.append("int y = whatever; \n"); //$NON-NLS-1$
|
||||
String code = sb.toString();
|
||||
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTDeclaration[] decls = tu.getDeclarations();
|
||||
assertMacroLocation(decls[0], code.indexOf("ADD(ONEYONENOE,TWO, THREE)"), "ADD(ONEYONENOE,TWO, THREE)".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testArgumentCapture() throws Exception {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("#define add(x,y) x + y \n"); //$NON-NLS-1$
|
||||
sb.append("#define add2 add(x, \n"); //$NON-NLS-1$
|
||||
sb.append("int x = add2 z); \n"); //$NON-NLS-1$
|
||||
sb.append("int y = whatever; \n"); //$NON-NLS-1$
|
||||
String code = sb.toString();
|
||||
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTDeclaration[] decls = tu.getDeclarations();
|
||||
assertMacroLocation(decls[0], code.indexOf("add2 z);"), "add2 z)".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testFunctionMacroNotCalled() throws Exception {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("#define FUNCTION(x) x \n"); //$NON-NLS-1$
|
||||
sb.append("#define YO FUNCTION \n"); //$NON-NLS-1$
|
||||
sb.append("int x = YO; \n"); //$NON-NLS-1$
|
||||
sb.append("int y = whatever; \n"); //$NON-NLS-1$
|
||||
String code = sb.toString();
|
||||
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTDeclaration[] decls = tu.getDeclarations();
|
||||
assertMacroLocation(decls[0], code.indexOf("YO;"), "YO".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
public void testBuildFunctionMacroName() throws Exception {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("#define FUN1(x) x \n"); //$NON-NLS-1$
|
||||
sb.append("#define FUN1(x) x \n"); //$NON-NLS-1$
|
||||
sb.append("#define MAKEFUN(num) FUN ## num \n"); //$NON-NLS-1$
|
||||
sb.append("int x = MAKEFUN(1)(z); \n"); //$NON-NLS-1$
|
||||
sb.append("int y = whatever; \n"); //$NON-NLS-1$
|
||||
String code = sb.toString();
|
||||
|
||||
for(int i = 0; i < languages.length; i++) {
|
||||
IASTTranslationUnit tu = parse(code, languages[i]);
|
||||
IASTDeclaration[] decls = tu.getDeclarations();
|
||||
assertMacroLocation(decls[0], code.indexOf("MAKEFUN(1)(z);"), "MAKEFUN(1)(z)".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,9 +11,13 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.scanner;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -65,5 +69,23 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
|
|||
validateProblem(0, IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, "bar.h");
|
||||
validateProblemCount(1);
|
||||
}
|
||||
|
||||
// #define D
|
||||
// #if defined D
|
||||
// x;
|
||||
// #endif
|
||||
// #if defined(D)
|
||||
// y;
|
||||
// #endif
|
||||
public void testBug186047() throws Exception {
|
||||
initializeScanner();
|
||||
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tSEMI);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.scanner;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
|
@ -575,4 +578,627 @@ public class PreprocessorTests extends PreprocessorTestsBase {
|
|||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
// #define FOO 5
|
||||
// # define BAR 10
|
||||
// int x = FOO + BAR;
|
||||
public void testSimpleObjectLike1() throws Exception {
|
||||
initializeScanner();
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateInteger("5");
|
||||
validateToken(IToken.tPLUS);
|
||||
validateInteger("10");
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
// #define FOO BAR
|
||||
// # define BAR 10
|
||||
// int x = BAR;
|
||||
public void testSimpleObjectLike2() throws Exception {
|
||||
initializeScanner();
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateInteger("10");
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
// #define MAX(a, b) (a) > (b) ? (a) : (b)
|
||||
// int max = MAX(x, y);
|
||||
public void testSimpleFunctionLike1() throws Exception {
|
||||
// int max = (x) > (y) ? (x) : (y);
|
||||
initializeScanner();
|
||||
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("max");
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tGT);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tQUESTION);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tCOLON);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
// #define ADD(a, b) (a) + (b)
|
||||
// #define ADDPART(a) ADD(a
|
||||
// int sum = ADDPART (x) , y);
|
||||
public void testSimpleFunctionLike2() throws Exception {
|
||||
// int sum = (x) + (y) ;
|
||||
initializeScanner();
|
||||
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("sum");
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
// #define ADD(a, b) (a) + (b)
|
||||
// int sum = ADD(x+1,y+1);
|
||||
public void testSimpleFunctionLike3() throws Exception {
|
||||
// int sum = (x+1) + (y+1) ;
|
||||
initializeScanner();
|
||||
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("sum");
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tPLUS);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tPLUS);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
// #define ADD(a, b) (a) + (b)
|
||||
// int sum = ADD(f(x,y),z+1);
|
||||
public void testSimpleFunctionLike4() throws Exception {
|
||||
// int sum = (f(x,y)) + (z+1) ;
|
||||
initializeScanner();
|
||||
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("sum");
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("f");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("z");
|
||||
validateToken(IToken.tPLUS);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
// #define hash_hash # ## #
|
||||
// #define mkstr(a) # a
|
||||
// #define in_between(a) mkstr(a)
|
||||
// #define join(c, d) in_between(c hash_hash d)
|
||||
// char p[] = join(x, y);
|
||||
public void testSpecHashHashExample() throws Exception {
|
||||
// char p[] = "x ## y" ;
|
||||
initializeScanner();
|
||||
|
||||
validateToken(IToken.t_char);
|
||||
validateIdentifier("p");
|
||||
validateToken(IToken.tLBRACKET);
|
||||
validateToken(IToken.tRBRACKET);
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateString("x ## y");
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
private static StringBuffer getExample3Defines() {
|
||||
return new StringBuffer()
|
||||
.append("#define x 3 \n")
|
||||
.append("#define f(a) f(x * (a)) \n")
|
||||
.append("#undef x \n")
|
||||
.append("#define x 2 \n")
|
||||
.append("#define g f \n")
|
||||
.append("#define z z[0] \n")
|
||||
.append("#define h g(~ \n")
|
||||
.append("#define m(a) a(w) \n")
|
||||
.append("#define w 0,1 \n")
|
||||
.append("#define t(a) a \n")
|
||||
.append("#define p() int \n")
|
||||
.append("#define q(x) x \n")
|
||||
.append("#define r(x,y) x ## y \n")
|
||||
.append("#define str(x) # x \n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testSpecExample3_1() throws Exception {
|
||||
StringBuffer sb = getExample3Defines();
|
||||
sb.append("f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); \n");
|
||||
|
||||
// f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateIdentifier("f");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tSTAR);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tPLUS);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateIdentifier("f");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tSTAR);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("f");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tSTAR);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("z");
|
||||
validateToken(IToken.tLBRACKET);
|
||||
validateInteger("0");
|
||||
validateToken(IToken.tRBRACKET);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tMOD);
|
||||
validateIdentifier("f");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tSTAR);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("0");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateIdentifier("t");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
public void _testSpecExample3_2() throws Exception {
|
||||
StringBuffer sb = getExample3Defines();
|
||||
sb.append("g(x+(3,4)-w) | h 5) & m (f)^m(m); \n");
|
||||
|
||||
// f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); //47
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateIdentifier("g");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tSTAR);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tPLUS);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("3");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("4");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tMINUS);
|
||||
validateInteger("0");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tBITOR);
|
||||
validateIdentifier("f");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tSTAR);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateToken(IToken.tBITCOMPLEMENT);
|
||||
validateInteger("5");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tAMPER);
|
||||
validateIdentifier("f");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("0");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tXOR);
|
||||
validateIdentifier("m");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateInteger("0");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testSpecExample3_3() throws Exception {
|
||||
StringBuffer sb = getExample3Defines();
|
||||
sb.append("p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; \n");
|
||||
|
||||
// int i[] = { 1, 23, 4, 5, };
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("i");
|
||||
validateToken(IToken.tLBRACKET);
|
||||
validateToken(IToken.tRBRACKET);
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateToken(IToken.tLBRACE);
|
||||
validateInteger("1");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("23");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("4");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("5");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateToken(IToken.tRBRACE);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
public void testSpecExample3_4() throws Exception {
|
||||
StringBuffer sb = getExample3Defines();
|
||||
sb.append("char c[2][6] = { str(hello), str() }; \n"); //31
|
||||
|
||||
// char c[2][6] = { "hello", "" }; //15
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateToken(IToken.t_char);
|
||||
validateIdentifier("c");
|
||||
validateToken(IToken.tLBRACKET);
|
||||
validateInteger("2");
|
||||
validateToken(IToken.tRBRACKET);
|
||||
validateToken(IToken.tLBRACKET);
|
||||
validateInteger("6");
|
||||
validateToken(IToken.tRBRACKET);
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateToken(IToken.tLBRACE);
|
||||
validateString("hello");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateString("");
|
||||
validateToken(IToken.tRBRACE);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
private static StringBuffer getExample4Defines() {
|
||||
return new StringBuffer()
|
||||
.append("#define str(s) # s \n")
|
||||
.append("#define xstr(s) str(s) \n")
|
||||
.append("#define debug(s, t) printf(\"x\" # s \"= %d, x\" # t \"= %s\", \\ \n")
|
||||
.append("x ## s, x ## t) \n")
|
||||
.append("#define INCFILE(n) vers ## n \n")
|
||||
.append("#define glue(a, b) a ## b \n")
|
||||
.append("#define xglue(a, b) glue(a, b) \n")
|
||||
.append("#define HIGHLOW \"hello\" \n")
|
||||
.append("#define LOW LOW \", world\" \n");
|
||||
}
|
||||
|
||||
|
||||
public void testSpecExample4_1() throws Exception {
|
||||
StringBuffer sb = getExample4Defines();
|
||||
sb.append("debug(1, 2); \n"); //31
|
||||
|
||||
// printf("x1= %d, x2= %s", x1, x2); // 9
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateIdentifier("printf");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateString("x1= %d, x2= %s");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateIdentifier("x1");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateIdentifier("x2");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
public void testSpecExample4_2() throws Exception {
|
||||
StringBuffer sb = getExample4Defines();
|
||||
sb.append("fputs(str(strncmp(\"abc\\0d\", \"abc\", '\\4') // this goes away \n");
|
||||
sb.append("== 0) str(: @\\n), s); \n");
|
||||
|
||||
// fputs( "strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n", s); // 7
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateIdentifier("fputs");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateString("strncmp(\\\"abc\\\\0d\\\", \\\"abc\\\", '\\\\4') == 0: @\\n");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateIdentifier("s");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
public void testSpecExample4_3() throws Exception {
|
||||
StringBuffer sb = getExample4Defines();
|
||||
sb.append("xglue(HIGH, LOW) \n");
|
||||
|
||||
// "hello, world"
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateString("hello, world");
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
public void testSpecExample4_4() throws Exception {
|
||||
StringBuffer sb = getExample4Defines();
|
||||
sb.append("glue(HIGH, LOW); \n");
|
||||
|
||||
// "hello";
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateString("hello");
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
// #define t(x,y,z) x ## y ## z
|
||||
// int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), t(10,,), t(,11,), t(,,12), t(,,) };
|
||||
public void testSpecExample5() throws Exception {
|
||||
// int j[] = {123, 45, 67, 89, 10, 11, 12, };
|
||||
initializeScanner();
|
||||
|
||||
validateToken(IToken.t_int);
|
||||
validateIdentifier("j");
|
||||
validateToken(IToken.tLBRACKET);
|
||||
validateToken(IToken.tRBRACKET);
|
||||
validateToken(IToken.tASSIGN);
|
||||
validateToken(IToken.tLBRACE);
|
||||
validateInteger("123");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("45");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("67");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("89");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("10");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("11");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateInteger("12");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateToken(IToken.tRBRACE);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
public StringBuffer getExample7Defines() {
|
||||
return new StringBuffer()
|
||||
.append("#define debug(...) fprintf(stderr, __VA_ARGS__) \n ")
|
||||
.append("#define showlist(...) puts(#__VA_ARGS__)\n ")
|
||||
.append("#define report(test, ...) ((test)?puts(#test):\\ \n ")
|
||||
.append("printf(__VA_ARGS__)) \n ");
|
||||
}
|
||||
|
||||
|
||||
public void testSpecExample7_1() throws Exception {
|
||||
StringBuffer sb = getExample7Defines();
|
||||
sb.append("debug(\"Flag\"); \n");
|
||||
|
||||
// fprintf(stderr, "Flag" ); //7
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateIdentifier("fprintf");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("stderr");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateString("Flag");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
public void testSpecExample7_2() throws Exception {
|
||||
StringBuffer sb = getExample7Defines();
|
||||
sb.append("debug(\"X = %d\\n\", x); \n");
|
||||
|
||||
// fprintf(stderr, "X = %d\n", x ); //9
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateIdentifier("fprintf");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("stderr");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateString("X = %d\\n");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
public void testSpecExample7_3() throws Exception {
|
||||
StringBuffer sb = getExample7Defines();
|
||||
sb.append("showlist(The first, second, and third items.); \n");
|
||||
|
||||
// puts( "The first, second, and third items." ); //5
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateIdentifier("puts");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateString("The first, second, and third items.");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testSpecExample7_4() throws Exception {
|
||||
StringBuffer sb = getExample7Defines();
|
||||
sb.append("report(x>y, \"x is %d but y is %d\", x, y); \n");
|
||||
|
||||
// ( (x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y) ); //22
|
||||
initializeScanner(sb.toString());
|
||||
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tGT);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tQUESTION);
|
||||
validateIdentifier("puts");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateString("x>y");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tCOLON);
|
||||
validateIdentifier("printf");
|
||||
validateToken(IToken.tLPAREN );
|
||||
validateString("x is %d but y is %d");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateIdentifier("x");
|
||||
validateToken(IToken.tCOMMA);
|
||||
validateIdentifier("y");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tSEMI);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// #define foo g g g
|
||||
// #define g f##oo
|
||||
// foo
|
||||
public void testRecursiveExpansion() throws Exception {
|
||||
initializeScanner();
|
||||
|
||||
validateIdentifier("foo");
|
||||
validateIdentifier("foo");
|
||||
validateIdentifier("foo");
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
// #define m !(m)+n
|
||||
// #define n(n) n(m)
|
||||
// m(m)
|
||||
public void testRecursiveExpansion2() throws Exception {
|
||||
// !(m)+ !(m)+n(!(m)+n)
|
||||
initializeScanner();
|
||||
|
||||
validateToken(IToken.tNOT);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("m");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateToken(IToken.tNOT);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("m");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateIdentifier("n");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateToken(IToken.tNOT);
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("m");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateToken(IToken.tPLUS);
|
||||
validateIdentifier("n");
|
||||
validateToken(IToken.tRPAREN);
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
|
||||
// #define f g
|
||||
// #define cat(a,b) a ## b
|
||||
// #define g bad
|
||||
// cat(f, f)
|
||||
public void testRecursiveExpansion3() throws Exception {
|
||||
// ff
|
||||
initializeScanner();
|
||||
|
||||
validateIdentifier("ff");
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue