diff options
-rw-r--r-- | make/build.xml | 4 | ||||
-rwxr-xr-x | make/scripts/runtest.sh | 3 | ||||
-rw-r--r-- | src/junit/com/jogamp/gluegen/test/junit/generation/TestCParser.java | 253 | ||||
-rw-r--r-- | src/junit/com/jogamp/gluegen/test/junit/generation/TestJCPP.java | 59 | ||||
-rw-r--r-- | src/junit/com/jogamp/gluegen/test/junit/generation/cpptest_1.h (renamed from src/junit/com/jogamp/gluegen/test/junit/generation/cpptest.h) | 36 | ||||
-rw-r--r-- | src/junit/com/jogamp/gluegen/test/junit/generation/cpptest_10.hpp | 10 | ||||
-rw-r--r-- | src/junit/com/jogamp/gluegen/test/junit/generation/test2.h | 20 |
7 files changed, 371 insertions, 14 deletions
diff --git a/make/build.xml b/make/build.xml index a4afadb..516daa1 100644 --- a/make/build.xml +++ b/make/build.xml @@ -699,7 +699,7 @@ --> <target name="generate.java"> <!-- Generate the Java files --> - <antlr target="${output.dir}/${target}" outputdirectory="${output.dir}"> + <antlr target="${output.dir}/${target}" outputdirectory="${output.dir}" debug="no" trace="no"> <classpath refid="antlr.classpath" /> </antlr> </target> @@ -715,7 +715,7 @@ --> <target name="generate.java.override"> <!-- Generate the Java files --> - <antlr target="${output.dir}/${target}" glib="${output.dir}/${override}" outputdirectory="${output.dir}"> + <antlr target="${output.dir}/${target}" glib="${output.dir}/${override}" outputdirectory="${output.dir}" debug="no" trace="no"> <classpath refid="antlr.classpath" /> </antlr> </target> diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh index cb480f4..32a57b3 100755 --- a/make/scripts/runtest.sh +++ b/make/scripts/runtest.sh @@ -150,7 +150,8 @@ function onetest() { #onetest com.jogamp.common.os.TestElfReader01 $* 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.internals.TestType 2>&1 | tee -a $LOG -onetest com.jogamp.gluegen.test.junit.generation.TestJCPP 2>&1 | tee -a $LOG +#onetest com.jogamp.gluegen.test.junit.generation.TestJCPP $* 2>&1 | tee -a $LOG +onetest com.jogamp.gluegen.test.junit.generation.TestCParser $* 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.jcpp.CppReaderTest 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.jcpp.ErrorTest 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.jcpp.IncludeAbsoluteTest 2>&1 | tee -a $LOG diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/TestCParser.java b/src/junit/com/jogamp/gluegen/test/junit/generation/TestCParser.java new file mode 100644 index 0000000..795e27d --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/TestCParser.java @@ -0,0 +1,253 @@ +/** + * Copyright 2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.gluegen.test.junit.generation; + +import com.jogamp.common.os.AndroidVersion; +import com.jogamp.gluegen.ConstantDefinition; +import com.jogamp.gluegen.JavaConfiguration; +import com.jogamp.gluegen.cgram.CToken; +import com.jogamp.gluegen.cgram.Define; +import com.jogamp.gluegen.cgram.GNUCTokenTypes; +import com.jogamp.gluegen.cgram.GnuCLexer; +import com.jogamp.gluegen.cgram.GnuCParser; +import com.jogamp.gluegen.cgram.HeaderParser; +import com.jogamp.gluegen.cgram.TNode; +import com.jogamp.gluegen.cgram.types.EnumType; +import com.jogamp.gluegen.cgram.types.TypeDictionary; +import com.jogamp.gluegen.jcpp.JCPP; +import com.jogamp.gluegen.jcpp.LexerException; +import com.jogamp.gluegen.jcpp.Macro; +import com.jogamp.junit.util.SingletonJunitCase; + +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.TokenStreamRecognitionException; +import junit.framework.Assert; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collections; + +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * serves mainly as entry point for debugging purposes. + * @author Sven Gothel, Michael Bien + */ +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestCParser extends SingletonJunitCase { + + static final String sourcePath = BuildEnvironment.gluegenRoot + "/src/junit/com/jogamp/gluegen/test/junit/generation/"; + static final boolean debug = false; + + @BeforeClass + public static void init() { + if(AndroidVersion.isAvailable) { + // JCPP is n/a on Android - GlueGen Runtime only + setTestSupported(false); + } + } + + @Test + public void test01_cpp_cc() { + if( null != test10CCFileName ) { + return; + } + Exception ex = null; + try { + final String cppResultPath = cpp("cpptest_1", ".h", debug); + cc(cppResultPath, debug); + } catch (RecognitionException | IOException | LexerException e) { + e.printStackTrace(); + ex = e; + } + assertNull(ex); + } + + // @Test + public void test10_cc() { + Exception ex = null; + try { + if( null != test10CCFileName ) { + cc(test10CCFileName, debug); + } else { + cc(sourcePath + "cpptest_10.hpp", debug); + } + } catch (RecognitionException | IOException | LexerException e) { + e.printStackTrace(); + ex = e; + } + assertNull(ex); + } + + public String cpp(final String cSourceBasename, final String cSourceSuffix, final boolean debug) throws FileNotFoundException, IOException, LexerException, RecognitionException { + final String cSourcePath = sourcePath + cSourceBasename + cSourceSuffix; + final FileReader cSourceReader = new FileReader(cSourcePath); + + final String cppResultPath = BuildEnvironment.testOutput + "/" + cSourceBasename + ".hpp"; + final File cppResultFile = new File( cppResultPath ); + if( cppResultFile.exists() ) { + cppResultFile.delete(); + } + + System.err.println("XXX JCPP: "+cSourcePath); + System.err.println("XXX cpp result-file "+cppResultFile); + try( final FileOutputStream cppResultOStream = new FileOutputStream(cppResultFile) ) { + final JCPP pp = new JCPP(Collections.<String>singletonList(sourcePath), debug, false, true /* default */); + pp.addDefine("__GLUEGEN__", "2"); + pp.setOut(cppResultOStream); + pp.run(new BufferedReader(cSourceReader), cSourceBasename); + cppResultOStream.flush(); + cppResultOStream.close(); + { + int macroCount = 0; + for (final Macro cdef : pp.cpp.getMacros(true)) { + System.err.println("XXX cpp Macr "+macroCount+" <"+cdef+">, isFunc "+ + cdef.isFunctionLike()+", isConstExpr "+ + ConstantDefinition.isConstantExpression(cdef.getText())); + ++macroCount; + } + } + { + int defCount = 0; + for (final ConstantDefinition cdef : pp.getConstantDefinitions()) { + System.err.println("XXX cpp Defn "+defCount+" <"+cdef+">"); + ++defCount; + } + } + } + + return cppResultPath; + } + + public void cc(final String cppResultPath, final boolean debug) throws FileNotFoundException, IOException, LexerException, RecognitionException { + final File cppResultFile = new File( cppResultPath ); + System.err.println("XXX C Parser: "+cppResultPath); + try( final FileInputStream inStream = new FileInputStream(cppResultFile) ) { + final DataInputStream dis = new DataInputStream(inStream); + + final GnuCLexer lexer = new GnuCLexer(dis); + lexer.setTokenObjectClass(CToken.class.getName()); + lexer.initialize(); + // Parse the input expression. + final GnuCParser parser = new GnuCParser(lexer); + + // set AST node type to TNode or get nasty cast class errors + parser.setASTNodeClass(TNode.class.getName()); + TNode.setTokenVocabulary(GNUCTokenTypes.class.getName()); + + // invoke parser + parser.setDebug(debug); + try { + parser.translationUnit(); + } catch (final RecognitionException e) { + throw new RuntimeException(String.format( + "Fatal error during translation (Localisation : %s:%s:%s)", + e.getFilename(), e.getLine(), e.getColumn() + ), e); + } catch (final TokenStreamRecognitionException e) { + throw new RuntimeException(String.format( + "Fatal error during translation (Localisation : %s:%s:%s)", + e.recog.getFilename(), e.recog.getLine(), e.recog.getColumn() + ), e); + } catch (final TokenStreamException e) { + throw new RuntimeException("Fatal IO error", e); + } + + System.err.println("XXX C Header Tree Parser ..."); + final JavaConfiguration cfg = new JavaConfiguration(); + final HeaderParser headerParser = new HeaderParser(); + headerParser.setDebug(debug); + headerParser.setJavaConfiguration(cfg); + final TypeDictionary td = new TypeDictionary(); + headerParser.setTypedefDictionary(td); + final TypeDictionary sd = new TypeDictionary(); + headerParser.setStructDictionary(sd); + // set AST node type to TNode or get nasty cast class errors + headerParser.setASTNodeClass(TNode.class.getName()); + // walk that tree + headerParser.translationUnit(parser.getAST()); + dis.close(); + inStream.close(); + + { + int enumCount = 0; + for (final EnumType enumeration : headerParser.getEnums()) { + String enumName = enumeration.getName(); + if (enumName.equals("<anonymous>")) { + enumName = null; + } + // iterate over all values in the enumeration + for (int i = 0; i < enumeration.getNumEnumerates(); ++i) { + final EnumType.Enumerator enumerate = enumeration.getEnum(i); + final ConstantDefinition cdef = + new ConstantDefinition(enumerate.getName(), enumerate.getExpr(), + enumerate.getNumber(), + enumName, enumeration.getASTLocusTag()); + System.err.println("XXX cc_ Enum "+enumCount+":"+i+" <"+cdef+">"); + } + ++enumCount; + } + } + { + int defCount = 0; + for (final Object elem : lexer.getDefines()) { + final Define def = (Define) elem; + final ConstantDefinition cdef = + new ConstantDefinition(def.getName(), def.getValue(), null, def.getASTLocusTag()); + System.err.println("XXX cc_ Defn "+defCount+" <"+cdef+">"); + ++defCount; + } + } + } + } + + static String test10CCFileName = null; + public static void main(final String args[]) throws IOException { + for(int i=0; i<args.length; ++i ) { + if( "-in".equals(args[i]) ) { + test10CCFileName = args[++i]; + } + } + final String tstname = TestCParser.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/TestJCPP.java b/src/junit/com/jogamp/gluegen/test/junit/generation/TestJCPP.java index d197592..736794e 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/TestJCPP.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/TestJCPP.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. + * Copyright 2010-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -63,13 +63,27 @@ public class TestJCPP extends SingletonJunitCase { } @Test - public void test01MacroAndIncWithoutPragmaOnce() throws FileNotFoundException, IOException, LexerException { - testMacroAndInc(false); + public void test01MacroAndIncWithoutPragmaOnce() { + Exception ex = null; + try { + testMacroAndInc(false); + } catch (IOException | LexerException e) { + e.printStackTrace(); + ex = e; + } + assertNull(ex); } @Test - public void test02MacroAndIncWithPragmaOnce() throws FileNotFoundException, IOException, LexerException { - testMacroAndInc(true); + public void test02MacroAndIncWithPragmaOnce() { + Exception ex = null; + try { + testMacroAndInc(true); + } catch (IOException | LexerException e) { + e.printStackTrace(); + ex = e; + } + assertNull(ex); } public void testMacroAndInc(final boolean pragmaOnce) throws FileNotFoundException, IOException, LexerException { @@ -81,13 +95,14 @@ public class TestJCPP extends SingletonJunitCase { final ByteArrayOutputStream output = new ByteArrayOutputStream(); pp.setOut(output); - final String filename = "cpptest.h"; + final String filename = "cpptest_1.h"; final String filepath = folderpath + "/" + filename ; pp.run(new BufferedReader(new FileReader(filepath)), filename); final String expected = - "#line 1 \"cpptest.h\" 1"+ + "#line 1 \"cpptest_1.h\" 1"+ ""+ + "typedef char cl_char;"+ "cl_char GOOD_A;"+ "int GOOD_B;"+ "int GOOD_C;"+ @@ -117,15 +132,38 @@ public class TestJCPP extends SingletonJunitCase { ""+ "const int GOOD_H = 42;"+ ""+ - "#line 135 \"cpptest.h\" 2"+ + "#line 136 \"cpptest_1.h\" 2"+ "#line 1 \""+folderpath+"/sub-inc/-cpptest-included2.h\" 1"+ ""+ "const int GOOD_I = 43;"+ - "#line 136 \"cpptest.h\" 2"+ + "#line 137 \"cpptest_1.h\" 2"+ + ""+ + "typedef enum SomeEnum {"+ + " ConstEnumValue00 = 16,"+ + " ConstEnumValue01 = (1 << ConstEnumValue00) - 1,"+ + " ConstEnumValue02 = (10-1),"+ + " ConstEnumValue03 = (10 - 2),"+ + " ConstEnumValue04 = ( 10 - 3 ),"+ + " ConstEnumValue05 = 10-4,"+ + " ConstEnumValue06 = 10 - 11,"+ + " ConstEnumValue07 = -2,"+ + " ConstEnumValue08 = - 2,"+ + " ConstEnumValueXX = 0"+ + "} SomeEnum;"+ + ""+ + "const int constInt00 = 16;"+ + "const int constInt01 = ((1 << 16) - 1);"+ + "const int constInt02 = (10-1);"+ + "const int constInt03 = (10 - 2);"+ + "const int constInt04 = ( 10 - 3 );"+ + "const int constInt05 = 10-4;"+ + "const int constInt06 = 10 - 11;"+ + "const int constInt07 = -2;"+ + "const int constInt08 = - 2;"+ + "const int constIntXX = 0;"+ "" ; - output.flush(); final String result = output.toString(); output.close(); @@ -143,7 +181,6 @@ public class TestJCPP extends SingletonJunitCase { System.err.println(); assertEquals(killWhitespace(expected), killWhitespace(result)); - } private String killWhitespace(final String a) { diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/cpptest.h b/src/junit/com/jogamp/gluegen/test/junit/generation/cpptest_1.h index 376442a..d61c778 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/cpptest.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/cpptest_1.h @@ -33,6 +33,7 @@ #define TEST_C GOOD_C #endif +typedef char cl_char; cl_char TEST_A(2); int TEST_B; int TEST_C; @@ -134,5 +135,40 @@ int TEST_G_VAL; #include <cpptest-included.h> #include <sub-inc/-cpptest-included2.h> +typedef enum SomeEnum { + ConstEnumValue00 = 16, + ConstEnumValue01 = (1 << ConstEnumValue00) - 1, + ConstEnumValue02 = (10-1), + ConstEnumValue03 = (10 - 2), + ConstEnumValue04 = ( 10 - 3 ), + ConstEnumValue05 = 10-4, + ConstEnumValue06 = 10 - 11, + ConstEnumValue07 = -2, + ConstEnumValue08 = - 2, + ConstEnumValueXX = 0 +} SomeEnum; + +#define ConstDefValue00 16 +#define ConstDefValue01 ((1 << ConstDefValue00) - 1) +#define ConstDefValue02 (10-1) +#define ConstDefValue03 (10 - 2) +#define ConstDefValue04 ( 10 - 3 ) +#define ConstDefValue05 10-4 +#define ConstDefValue06 10 - 11 +#define ConstDefValue07 -2 +#define ConstDefValue08 - 2 +#define ConstDefValueXX 0 + +const int constInt00 = ConstDefValue00; +const int constInt01 = ConstDefValue01; +const int constInt02 = ConstDefValue02; +const int constInt03 = ConstDefValue03; +const int constInt04 = ConstDefValue04; +const int constInt05 = ConstDefValue05; +const int constInt06 = ConstDefValue06; +const int constInt07 = ConstDefValue07; +const int constInt08 = ConstDefValue08; +const int constIntXX = ConstDefValueXX; + #endif /* __test_h_ */ diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/cpptest_10.hpp b/src/junit/com/jogamp/gluegen/test/junit/generation/cpptest_10.hpp new file mode 100644 index 0000000..d209544 --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/cpptest_10.hpp @@ -0,0 +1,10 @@ +typedef enum SomeEnum { + ConstEnumValue00 = 16, + ConstEnumValue01 = (1 << ConstEnumValue00) - 1, + ConstEnumValue02 = 10-1, + ConstEnumValue03 = 10 - 1, + ConstEnumValue04 = 10 - 11, + ConstEnumValue05 = -2, + ConstEnumValue06 = - 2, + ConstEnumValueXX = 0 +} SomeEnum; diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h index 653fcc2..32db2ad 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h @@ -2,6 +2,26 @@ #include <gluegen_stdint.h> #include <gluegen_stddef.h> +typedef enum SomeEnum { + ConstEnumValue00 = 16, + ConstEnumValue01 = (1 << ConstEnumValue00) - 1, + ConstEnumValue02 = 10-1, + ConstEnumValue03 = 10 - 1, + ConstEnumValue04 = 10 - 11, + ConstEnumValue05 = -2, + ConstEnumValue06 = - 2, + ConstEnumValueXX = 0 +} SomeEnum; + +#define ConstDefValue00 16 +#define ConstDefValue01 ((1 << ConstDefValue00) - 1) +#define ConstDefValue02 (10-1) +#define ConstDefValue03 (10 - 1) +#define ConstDefValue04 10 - 11 +#define ConstDefValue05 -2 +#define ConstDefValue06 - 2 +#define ConstDefValueXX 0 + // Opaque long T2_UndefStruct* // struct T2_UndefStruct; // undefined struct forward declaration, implementation secret typedef struct T2_UndefStruct* T2_UndefStructPtr; |