summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/build-test.xml21
-rwxr-xr-xmake/scripts/check-java-major-version.sh7
-rwxr-xr-xmake/scripts/make.gluegen.all.linux-x86_64.sh2
-rwxr-xr-xmake/scripts/runtest.sh3
-rw-r--r--make/scripts/setenv-build-jogl-x86_64.sh16
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java233
-rw-r--r--src/java/com/jogamp/gluegen/structgen/CStruct.java19
-rw-r--r--src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java160
-rw-r--r--src/java/com/jogamp/gluegen/structgen/CStructs.java46
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/structgen/BuildStruct01.java34
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/structgen/TestStruct02.h14
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java23
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java51
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/structgen/package-info.java15
-rw-r--r--test/junit/com/jogamp/gluegen/StructAccessorTest.java15
15 files changed, 453 insertions, 206 deletions
diff --git a/make/build-test.xml b/make/build-test.xml
index bccc534..2bf2e37 100644
--- a/make/build-test.xml
+++ b/make/build-test.xml
@@ -114,7 +114,23 @@
<echo message=" test.base.dir ${test.base.dir}"/>
<echo message=" build_t.gen ${build_t.gen}"/>
- <!-- Annotation Processor Only - First -->
+ <!-- Javac of Annotation Processor dependencies - First -->
+ <javac destdir="${build_t.java}"
+ fork="yes"
+ includeAntRuntime="false"
+ memoryMaximumSize="${javac.memorymax}"
+ encoding="UTF-8"
+ source="${target.sourcelevel}"
+ target="${target.targetlevel}"
+ bootclasspath="${target.rt.jar}"
+ debug="${javacdebug}" debuglevel="${javacdebuglevel}">
+ <classpath refid="junit.compile.classpath"/>
+ <compilerarg value="-proc:none"/>
+ <src path="${test.base.dir}/com/jogamp/junit/util"/>
+ </javac>
+
+ <!-- Annotation Processor - Second -->
+ <mkdir dir="${build_t.gen}/classes/com/jogamp/gluegen/test/junit/structgen"/>
<javac destdir="${build_t.java}"
fork="yes"
includeAntRuntime="false"
@@ -129,9 +145,10 @@
<compilerarg value="-J-Djogamp.gluegen.structgen.debug"/>
<compilerarg value="-J-Djogamp.gluegen.structgen.output=${build_t.gen}/classes"/>
<src path="${test.base.dir}/com/jogamp/gluegen/test/junit/structgen"/>
+ <src path="${build_t.gen}/classes/com/jogamp/gluegen/test/junit/structgen" />
</javac>
- <!-- Javac Only - Second -->
+ <!-- Javac All - Third -->
<javac destdir="${build_t.java}"
fork="yes"
includeAntRuntime="false"
diff --git a/make/scripts/check-java-major-version.sh b/make/scripts/check-java-major-version.sh
index 6b1711c..49c0445 100755
--- a/make/scripts/check-java-major-version.sh
+++ b/make/scripts/check-java-major-version.sh
@@ -10,9 +10,10 @@ function dump_version() {
function dump_versions() {
cd $1
#dump_version jogamp.common.Debug
- for i in `find . -name '*.class'` ; do
- dump_version `echo $i | sed -e 's/\//./g' -e 's/\.class//g'`
- done
+ javap -v `find . -name '*.class'` | grep -e '^Classfile' -e 'major version'
+ #for i in `find . -name '*.class'` ; do
+ # dump_version `echo $i | sed -e 's/\//./g' -e 's/\.class//g'`
+ #done
cd $TDIR
}
diff --git a/make/scripts/make.gluegen.all.linux-x86_64.sh b/make/scripts/make.gluegen.all.linux-x86_64.sh
index 8c62cd0..60e35d6 100755
--- a/make/scripts/make.gluegen.all.linux-x86_64.sh
+++ b/make/scripts/make.gluegen.all.linux-x86_64.sh
@@ -27,7 +27,7 @@ export TARGET_RT_JAR=/opt-share/jre1.6.0_30/lib/rt.jar
#export JOGAMP_JAR_CODEBASE="Codebase: *.jogamp.org"
export JOGAMP_JAR_CODEBASE="Codebase: *.goethel.localnet"
-# BUILD_ARCHIVE=true \
+BUILD_ARCHIVE=true \
ant \
-Drootrel.build=build-x86_64 \
$* 2>&1 | tee make.gluegen.all.linux-x86_64.log
diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh
index 947755f..f518668 100755
--- a/make/scripts/runtest.sh
+++ b/make/scripts/runtest.sh
@@ -119,7 +119,8 @@ function onetest() {
#onetest com.jogamp.common.os.TestElfReader01 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.PCPPTest 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG
-onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG
+#onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen01 2>&1 | tee -a $LOG
+onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen02 2>&1 | tee -a $LOG
diff --git a/make/scripts/setenv-build-jogl-x86_64.sh b/make/scripts/setenv-build-jogl-x86_64.sh
index c0746e9..8994365 100644
--- a/make/scripts/setenv-build-jogl-x86_64.sh
+++ b/make/scripts/setenv-build-jogl-x86_64.sh
@@ -26,15 +26,25 @@ if [ -z "$ANT_PATH" ] ; then
exit
fi
-if [ -e /opt-linux-x86_64/jre7 -a -e /opt-linux-x86_64/j2se7 ] ; then
- J2RE_HOME=/opt-linux-x86_64/jre7
- JAVA_HOME=/opt-linux-x86_64/j2se7
+if [ -e /opt-linux-x86_64/jre8 -a -e /opt-linux-x86_64/j2se8 ] ; then
+ J2RE_HOME=/opt-linux-x86_64/jre8
+ JAVA_HOME=/opt-linux-x86_64/j2se8
PATH=$J2RE_HOME/bin:$JAVA_HOME/bin:$PATH
export J2RE_HOME JAVA_HOME
FOUND_JAVA=1
fi
if [ -z "$FOUND_JAVA" ] ; then
+ if [ -e /opt-linux-x86_64/jre7 -a -e /opt-linux-x86_64/j2se7 ] ; then
+ J2RE_HOME=/opt-linux-x86_64/jre7
+ JAVA_HOME=/opt-linux-x86_64/j2se7
+ PATH=$J2RE_HOME/bin:$JAVA_HOME/bin:$PATH
+ export J2RE_HOME JAVA_HOME
+ FOUND_JAVA=1
+ fi
+fi
+
+if [ -z "$FOUND_JAVA" ] ; then
if [ -e /opt-linux-x86_64/jre6 -a -e /opt-linux-x86_64/j2se6 ] ; then
J2RE_HOME=/opt-linux-x86_64/jre6
JAVA_HOME=/opt-linux-x86_64/j2se6
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index ec8757c..3f4fa9e 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -836,69 +836,74 @@ public class JavaEmitter implements GlueEmitter {
}
}
- String structClassPkg = cfg.packageForStruct(name);
- PrintWriter writer = null;
- PrintWriter newWriter = null;
+ final String structClassPkg = cfg.packageForStruct(name);
+ final PrintWriter javaWriter;
+ final PrintWriter jniWriter;
try {
- writer = openFile(
- cfg.javaOutputDir() + File.separator +
- CodeGenUtils.packageAsPath(structClassPkg) +
- File.separator + containingTypeName + ".java", containingTypeName);
- CodeGenUtils.emitAutogeneratedWarning(writer, this);
- if (needsNativeCode) {
- String nRoot = cfg.nativeOutputDir();
- if (cfg.nativeOutputUsesJavaHierarchy()) {
- nRoot += File.separator + CodeGenUtils.packageAsPath(cfg.packageName());
+ javaWriter = openFile(cfg.javaOutputDir() + File.separator +
+ CodeGenUtils.packageAsPath(structClassPkg) +
+ File.separator + containingTypeName + ".java", containingTypeName);
+ if( null == javaWriter ) {
+ // suppress output if openFile deliberately returns null.
+ return;
+ }
+ CodeGenUtils.emitAutogeneratedWarning(javaWriter, this);
+ if (needsNativeCode) {
+ String nRoot = cfg.nativeOutputDir();
+ if (cfg.nativeOutputUsesJavaHierarchy()) {
+ nRoot += File.separator + CodeGenUtils.packageAsPath(cfg.packageName());
+ }
+ jniWriter = openFile(nRoot + File.separator + containingTypeName + "_JNI.c", containingTypeName);
+ CodeGenUtils.emitAutogeneratedWarning(jniWriter, this);
+ emitCHeader(jniWriter, containingTypeName);
+ } else {
+ jniWriter = null;
}
- newWriter = openFile(nRoot + File.separator + containingTypeName + "_JNI.c", containingTypeName);
- CodeGenUtils.emitAutogeneratedWarning(newWriter, this);
- emitCHeader(newWriter, containingTypeName);
- }
} catch(Exception e) {
- throw new RuntimeException("Unable to open files for emission of struct class", e);
+ throw new RuntimeException("Unable to open files for emission of struct class", e);
}
- writer.println();
- writer.println("package " + structClassPkg + ";");
- writer.println();
- writer.println("import java.nio.*;");
- writer.println();
+ javaWriter.println();
+ javaWriter.println("package " + structClassPkg + ";");
+ javaWriter.println();
+ javaWriter.println("import java.nio.*;");
+ javaWriter.println();
- writer.println("import " + cfg.gluegenRuntimePackage() + ".*;");
- writer.println("import " + DynamicLookupHelper.class.getPackage().getName() + ".*;");
- writer.println("import " + Buffers.class.getPackage().getName() + ".*;");
- writer.println("import " + MachineDescriptionRuntime.class.getName() + ";");
- writer.println();
+ javaWriter.println("import " + cfg.gluegenRuntimePackage() + ".*;");
+ javaWriter.println("import " + DynamicLookupHelper.class.getPackage().getName() + ".*;");
+ javaWriter.println("import " + Buffers.class.getPackage().getName() + ".*;");
+ javaWriter.println("import " + MachineDescriptionRuntime.class.getName() + ";");
+ javaWriter.println();
List<String> imports = cfg.imports();
for (String str : imports) {
- writer.print("import ");
- writer.print(str);
- writer.println(";");
+ javaWriter.print("import ");
+ javaWriter.print(str);
+ javaWriter.println(";");
}
- writer.println();
+ javaWriter.println();
List<String> javadoc = cfg.javadocForClass(containingTypeName);
for (String doc : javadoc) {
- writer.println(doc);
+ javaWriter.println(doc);
}
- writer.print("public class " + containingTypeName + " ");
+ javaWriter.print("public class " + containingTypeName + " ");
boolean firstIteration = true;
List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingTypeName);
for (String userInterface : userSpecifiedInterfaces) {
if (firstIteration) {
- writer.print("implements ");
+ javaWriter.print("implements ");
}
firstIteration = false;
- writer.print(userInterface);
- writer.print(" ");
- }
- writer.println("{");
- writer.println();
- writer.println(" StructAccessor accessor;");
- writer.println();
- writer.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();");
- writer.println();
+ javaWriter.print(userInterface);
+ javaWriter.print(" ");
+ }
+ javaWriter.println("{");
+ javaWriter.println();
+ javaWriter.println(" StructAccessor accessor;");
+ javaWriter.println();
+ javaWriter.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();");
+ javaWriter.println();
// generate all offset and size arrays
- generateOffsetAndSizeArrays(writer, containingTypeName, structType, null); /* w/o offset */
+ generateOffsetAndSizeArrays(javaWriter, containingTypeName, structType, null); /* w/o offset */
for (int i = 0; i < structType.getNumFields(); i++) {
final Field field = structType.getField(i);
final Type fieldType = field.getType();
@@ -917,14 +922,14 @@ public class JavaEmitter implements GlueEmitter {
field + "\" in type \"" + name + "\")");
}
- generateOffsetAndSizeArrays(writer, fieldName, fieldType, field);
+ generateOffsetAndSizeArrays(javaWriter, fieldName, fieldType, field);
} else if (fieldType.isArray()) {
Type baseElementType = field.getType().asArray().getBaseElementType();
if(!baseElementType.isPrimitive())
break;
- generateOffsetAndSizeArrays(writer, fieldName, null, field); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, fieldName, null, field); /* w/o size */
} else {
JavaType externalJavaType = null;
try {
@@ -936,7 +941,7 @@ public class JavaEmitter implements GlueEmitter {
}
if (externalJavaType.isPrimitive()) {
// Primitive type
- generateOffsetAndSizeArrays(writer, fieldName, null, field); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, fieldName, null, field); /* w/o size */
} else {
// FIXME
LOG.log(WARNING, "Complicated fields (field \"{0}\" of type \"{1}\") not implemented yet", new Object[]{field, name});
@@ -946,27 +951,27 @@ public class JavaEmitter implements GlueEmitter {
}
}
}
- writer.println();
-
- writer.println(" public static int size() {");
- writer.println(" return "+containingTypeName+"_size[mdIdx];");
- writer.println(" }");
- writer.println();
- writer.println(" public static " + containingTypeName + " create() {");
- writer.println(" return create(Buffers.newDirectByteBuffer(size()));");
- writer.println(" }");
- writer.println();
- writer.println(" public static " + containingTypeName + " create(java.nio.ByteBuffer buf) {");
- writer.println(" return new " + containingTypeName + "(buf);");
- writer.println(" }");
- writer.println();
- writer.println(" " + containingTypeName + "(java.nio.ByteBuffer buf) {");
- writer.println(" accessor = new StructAccessor(buf);");
- writer.println(" }");
- writer.println();
- writer.println(" public java.nio.ByteBuffer getBuffer() {");
- writer.println(" return accessor.getBuffer();");
- writer.println(" }");
+ javaWriter.println();
+
+ javaWriter.println(" public static int size() {");
+ javaWriter.println(" return "+containingTypeName+"_size[mdIdx];");
+ javaWriter.println(" }");
+ javaWriter.println();
+ javaWriter.println(" public static " + containingTypeName + " create() {");
+ javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));");
+ javaWriter.println(" }");
+ javaWriter.println();
+ javaWriter.println(" public static " + containingTypeName + " create(java.nio.ByteBuffer buf) {");
+ javaWriter.println(" return new " + containingTypeName + "(buf);");
+ javaWriter.println(" }");
+ javaWriter.println();
+ javaWriter.println(" " + containingTypeName + "(java.nio.ByteBuffer buf) {");
+ javaWriter.println(" accessor = new StructAccessor(buf);");
+ javaWriter.println(" }");
+ javaWriter.println();
+ javaWriter.println(" public java.nio.ByteBuffer getBuffer() {");
+ javaWriter.println(" return accessor.getBuffer();");
+ javaWriter.println(" }");
for (int i = 0; i < structType.getNumFields(); i++) {
final Field field = structType.getField(i);
@@ -983,12 +988,12 @@ public class JavaEmitter implements GlueEmitter {
FunctionSymbol funcSym = new FunctionSymbol(fieldName, funcType);
MethodBinding binding = bindFunction(funcSym, containingType, containingCType, machDescJava);
binding.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
- writer.println();
+ javaWriter.println();
// Emit public Java entry point for calling this function pointer
JavaMethodBindingEmitter emitter =
new JavaMethodBindingEmitter(binding,
- writer,
+ javaWriter,
cfg.runtimeExceptionType(),
cfg.unsupportedExceptionType(),
true,
@@ -1008,7 +1013,7 @@ public class JavaEmitter implements GlueEmitter {
// Emit private native Java entry point for calling this function pointer
emitter =
new JavaMethodBindingEmitter(binding,
- writer,
+ javaWriter,
cfg.runtimeExceptionType(),
cfg.unsupportedExceptionType(),
false,
@@ -1029,7 +1034,7 @@ public class JavaEmitter implements GlueEmitter {
// Emit (private) C entry point for calling this function pointer
CMethodBindingEmitter cEmitter =
new CMethodBindingEmitter(binding,
- newWriter,
+ jniWriter,
structClassPkg,
containingTypeName,
true, // FIXME: this is optional at this point
@@ -1052,12 +1057,12 @@ public class JavaEmitter implements GlueEmitter {
field + "\" in type \"" + name + "\")");
}
- writer.println();
- generateGetterSignature(writer, false, fieldType.getName(), capitalizeString(fieldName));
- writer.println(" {");
- writer.println(" return " + fieldType.getName() + ".create( accessor.slice( " +
+ javaWriter.println();
+ generateGetterSignature(javaWriter, false, fieldType.getName(), capitalizeString(fieldName));
+ javaWriter.println(" {");
+ javaWriter.println(" return " + fieldType.getName() + ".create( accessor.slice( " +
fieldName+"_offset[mdIdx], "+fieldName+"_size[mdIdx] ) );");
- writer.println(" }");
+ javaWriter.println(" }");
} else if (fieldType.isArray()) {
@@ -1070,18 +1075,18 @@ public class JavaEmitter implements GlueEmitter {
String capitalized = capitalizeString(fieldName);
// Setter
- writer.println();
- generateSetterSignature(writer, false, containingTypeName, capitalized, paramType+"[]");
- writer.println(" {");
- writer.print (" accessor.set" + capitalizeString(paramType) + "sAt(" + fieldName+"_offset[mdIdx], val);");
- writer.println(" return this;");
- writer.println(" }");
- writer.println();
+ javaWriter.println();
+ generateSetterSignature(javaWriter, false, containingTypeName, capitalized, paramType+"[]");
+ javaWriter.println(" {");
+ javaWriter.print (" accessor.set" + capitalizeString(paramType) + "sAt(" + fieldName+"_offset[mdIdx], val);");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ javaWriter.println();
// Getter
- generateGetterSignature(writer, false, paramType+"[]", capitalized);
- writer.println(" {");
- writer.print (" return accessor.get" + capitalizeString(paramType) + "sAt(" + fieldName+"_offset[mdIdx], new " +paramType+"["+fieldType.asArray().getLength()+"]);");
- writer.println(" }");
+ generateGetterSignature(javaWriter, false, paramType+"[]", capitalized);
+ javaWriter.println(" {");
+ javaWriter.print (" return accessor.get" + capitalizeString(paramType) + "sAt(" + fieldName+"_offset[mdIdx], new " +paramType+"["+fieldType.asArray().getLength()+"]);");
+ javaWriter.println(" }");
} else {
JavaType javaType = null;
@@ -1111,40 +1116,40 @@ public class JavaEmitter implements GlueEmitter {
", sizeDenominator "+sizeDenominator);
}
- writer.println();
+ javaWriter.println();
// Setter
- generateSetterSignature(writer, false, containingTypeName, capFieldName, javaTypeName);
- writer.println(" {");
+ generateSetterSignature(javaWriter, false, containingTypeName, capFieldName, javaTypeName);
+ javaWriter.println(" {");
if( fieldTypeNativeSizeFixed ) {
- writer.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
+ javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
} else {
- writer.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
+ javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
}
- writer.println(" return this;");
- writer.println(" }");
- writer.println();
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ javaWriter.println();
// Getter
- generateGetterSignature(writer, false, javaTypeName, capFieldName);
- writer.println(" {");
- writer.print (" return ");
+ generateGetterSignature(javaWriter, false, javaTypeName, capFieldName);
+ javaWriter.println(" {");
+ javaWriter.print (" return ");
if( fieldTypeNativeSizeFixed ) {
- writer.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx]);");
+ javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx]);");
} else {
- writer.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
+ javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
}
- writer.println(" }");
+ javaWriter.println(" }");
}
}
}
}
- emitCustomJavaCode(writer, containingTypeName);
- writer.println("}");
- writer.flush();
- writer.close();
+ emitCustomJavaCode(javaWriter, containingTypeName);
+ javaWriter.println("}");
+ javaWriter.flush();
+ javaWriter.close();
if (needsNativeCode) {
- newWriter.flush();
- newWriter.close();
+ jniWriter.flush();
+ jniWriter.close();
}
}
@Override
@@ -1415,17 +1420,15 @@ public class JavaEmitter implements GlueEmitter {
/**
* @param filename the class's full filename to open w/ write access
* @param simpleClassName the simple class name, i.e. w/o package name
- * @return a {@link PrintWriter} instance to write the class source file
+ * @return a {@link PrintWriter} instance to write the class source file or <code>null</code> to suppress output!
* @throws IOException
*/
protected PrintWriter openFile(String filename, String simpleClassName) throws IOException {
//System.out.println("Trying to open: " + filename);
- File file = new File(filename);
- String parentDir = file.getParent();
- if (parentDir != null)
- {
- File pDirFile = new File(parentDir);
- pDirFile.mkdirs();
+ final File file = new File(filename);
+ final String parentDir = file.getParent();
+ if (parentDir != null) {
+ new File(parentDir).mkdirs();
}
return new PrintWriter(new BufferedWriter(new FileWriter(file)));
}
diff --git a/src/java/com/jogamp/gluegen/structgen/CStruct.java b/src/java/com/jogamp/gluegen/structgen/CStruct.java
index 9d57196..be72cd8 100644
--- a/src/java/com/jogamp/gluegen/structgen/CStruct.java
+++ b/src/java/com/jogamp/gluegen/structgen/CStruct.java
@@ -33,21 +33,32 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- *
- * @author Michael Bien
- * @author Sven Gothel, et.al.
+ * @author Michael Bien, et al.
*/
-@Target(value = {ElementType.FIELD, ElementType.LOCAL_VARIABLE})
+@Target(value = {ElementType.TYPE, ElementType.PACKAGE, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
@Retention(value = RetentionPolicy.SOURCE)
public @interface CStruct {
/**
* Relative path to the header file.
+ * <p>
+ * Mandatory.
+ * </p>
*/
String header();
/**
* The name of the struct.
+ * <p>
+ * Mandatory for {@link ElementType.TYPE} and {@link ElementType.PACKAGE} annotations
+ * otherwise optional.
+ * </p>
*/
String name() default "_default_";
+
+ /**
+ * The optional java name of the struct.
+ */
+ String jname() default "_default_";
+
}
diff --git a/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
index ee761a3..7b24967 100644
--- a/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
+++ b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
@@ -30,12 +30,20 @@ package com.jogamp.gluegen.structgen;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.gluegen.GlueGen;
import com.jogamp.gluegen.JavaEmitter;
+
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
+import java.io.Reader;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
@@ -76,11 +84,11 @@ import jogamp.common.Debug;
*
* @author Michael Bien, et al.
*/
-@SupportedAnnotationTypes(value = {"com.jogamp.gluegen.structgen.CStruct"})
+@SupportedAnnotationTypes(value = {"com.jogamp.gluegen.structgen.CStruct", "com.jogamp.gluegen.structgen.CStructs"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class CStructAnnotationProcessor extends AbstractProcessor {
private static final String DEFAULT = "_default_";
- private static final boolean DEBUG;
+ static final boolean DEBUG;
static {
Debug.initSingleton();
@@ -131,71 +139,96 @@ public class CStructAnnotationProcessor extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
final String user_dir = System.getProperty("user.dir");
- final Set<? extends Element> elements = env.getElementsAnnotatedWith(CStruct.class);
-
- for (Element element : elements) {
-
- final String packageName = eltUtils.getPackageOf(element).toString();
+ final Set<? extends Element> cStructsElements = env.getElementsAnnotatedWith(CStructs.class);
+ for (Element structsElement : cStructsElements) {
+ final String packageName = eltUtils.getPackageOf(structsElement).toString();
+ final CStructs cstructs = structsElement.getAnnotation(CStructs.class);
+ if( null != cstructs ) {
+ final CStruct[] cstructArray = cstructs.value();
+ for(CStruct cstruct : cstructArray) {
+ processCStruct(cstruct, structsElement, packageName, user_dir);
+ }
+ }
+ }
- try {
- final CStruct struct = element.getAnnotation(CStruct.class);
- final String headerRelPath = struct.header();
- final Element enclElement = element.getEnclosingElement();
+ final Set<? extends Element> cStructElements = env.getElementsAnnotatedWith(CStruct.class);
+ for (Element structElement : cStructElements) {
+ final String packageName = eltUtils.getPackageOf(structElement).toString();
+ final CStruct cstruct = structElement.getAnnotation(CStruct.class);
+ if( null != cstruct ) {
+ processCStruct(cstruct, structElement, packageName, user_dir);
+ }
+ }
+ return true;
+ }
- System.err.println("CStruct: "+struct+", package "+packageName+", header "+headerRelPath);
- if(DEBUG) {
- System.err.println("CStruct.0: user.dir: "+user_dir);
- System.err.println("CStruct.0: element: "+element+", .simpleName "+element.getSimpleName());
- System.err.println("CStruct.0: enclElement: "+enclElement+", .simpleName "+enclElement.getSimpleName()+", .package "+eltUtils.getPackageOf(enclElement).toString());
+ private void processCStruct(final CStruct struct, final Element element, final String packageName, final String user_dir) {
+ try {
+ final String headerRelPath = struct.header();
+ final Element enclElement = element.getEnclosingElement();
+ final boolean isPackageOrType = null == enclElement;
+
+ System.err.println("CStruct: "+struct+", package "+packageName+", header "+headerRelPath);
+ if(DEBUG) {
+ System.err.println("CStruct.0: user.dir: "+user_dir);
+ System.err.println("CStruct.0: element: "+element+", .simpleName "+element.getSimpleName());
+ System.err.print("CStruct.0: isPackageOrType "+isPackageOrType+", enclElement: "+enclElement);
+ if( !isPackageOrType ) {
+ System.err.println(", .simpleName "+enclElement.getSimpleName()+", .package "+eltUtils.getPackageOf(enclElement).toString());
+ } else {
+ System.err.println("");
}
+ }
+ if( isPackageOrType && struct.name().equals(DEFAULT) ) {
+ throw new IllegalArgumentException("CStruct annotation on package or type must have name specified: "+struct+" @ "+element);
+ }
- final File headerFile;
- {
- File f = locateSource(packageName, headerRelPath);
+ final File headerFile;
+ {
+ File f = locateSource(packageName, headerRelPath);
+ if( null == f ) {
+ f = locateSource("", headerRelPath);
if( null == f ) {
- f = locateSource("", headerRelPath);
- if( null == f ) {
- // bail out
- throw new RuntimeException("Could not locate header "+headerRelPath+", package "+packageName);
- }
+ // bail out
+ throw new RuntimeException("Could not locate header "+headerRelPath+", package "+packageName);
}
- headerFile = f;
}
+ headerFile = f;
+ }
- final String root;
- {
- String root0 = headerFile.getAbsolutePath();
- root0 = root0.substring(0, root0.length()-headerFile.getName().length()-1);
- root = root0.substring(0, root0.length()-packageName.length()) +"..";
- }
- System.err.println("CStruct: "+headerFile+", abs: "+headerFile.isAbsolute()+", root "+root);
-
- generateStructBinding(element, struct, root, packageName, headerFile);
- } catch (IOException ex) {
- throw new RuntimeException("IOException while processing!", ex);
+ final String rootOut, headerParent;
+ {
+ final String root0 = headerFile.getAbsolutePath();
+ headerParent = root0.substring(0, root0.length()-headerFile.getName().length()-1);
+ rootOut = headerParent.substring(0, headerParent.length()-packageName.length()) + "..";
}
+ System.err.println("CStruct: "+headerFile+", abs: "+headerFile.isAbsolute()+", headerParent "+headerParent+", rootOut "+rootOut);
+
+ generateStructBinding(element, struct, isPackageOrType, rootOut, packageName, headerFile, headerParent);
+ } catch (IOException ex) {
+ throw new RuntimeException("IOException while processing!", ex);
}
- return true;
}
- private void generateStructBinding(Element element, CStruct struct, String root, String pakage, File header) throws IOException {
+ private void generateStructBinding(Element element, CStruct struct, boolean isPackageOrType, String rootOut, String pakage, File header, String headerParent) throws IOException {
final String declaredType = element.asType().toString();
- final String structName = struct.name().equals(DEFAULT) ? declaredType : struct.name();
-
- if( generatedStructs.contains(structName) ) {
- messager.printMessage(Kind.WARNING, "struct "+structName+" already defined elsewhere.", element);
+ final boolean useStructName = !struct.name().equals(DEFAULT);
+ final String structName = useStructName ? struct.name() : declaredType;
+ final boolean useJavaName = !struct.jname().equals(DEFAULT);
+
+ final String finalType = useJavaName ? struct.jname() : ( !isPackageOrType ? declaredType : structName );
+ System.err.println("CStruct: Generating struct accessor for struct: "+structName+" -> "+finalType+" [struct.name "+struct.name()+", struct.jname "+struct.jname()+", declaredType "+declaredType+"]");
+ if( generatedStructs.contains(finalType) ) {
+ messager.printMessage(Kind.NOTE, "struct "+structName+" already defined elsewhere, skipping.", element);
return;
}
- System.out.println("generating struct accessor for struct: "+structName);
-
- generatedStructs.add(structName);
final boolean outputDirAbs;
{
final File outputDirFile = new File(outputPath);
outputDirAbs = outputDirFile.isAbsolute();
}
- final String outputPath1 = outputDirAbs ? outputPath : root + File.separator + outputPath;
+ final String outputPath1 = outputDirAbs ? outputPath : rootOut + File.separator + outputPath;
final String config = outputPath1 + File.separator + header.getName() + ".cfg";
final File configFile = new File(config);
if(DEBUG) {
@@ -209,7 +242,8 @@ public class CStructAnnotationProcessor extends AbstractProcessor {
writer = new FileWriter(configFile);
writer.write("Package "+pakage+"\n");
writer.write("EmitStruct "+structName+"\n");
- if(!struct.name().equals(DEFAULT)) {
+ if( finalType != structName ) {
+ // We allow renaming the structType to the element's declaredType (FIELD annotation only)
writer.write("RenameJavaType " + struct.name()+" " + declaredType +"\n");
}
} finally {
@@ -217,16 +251,23 @@ public class CStructAnnotationProcessor extends AbstractProcessor {
writer.close();
}
}
-
- // TODO: Handle exceptions .. suppressed by Gluegen.main(..) ?
- GlueGen.main(
- // "-I"+path+"/build/",
- "-O" + outputPath1,
- "-E" + AnnotationProcessorJavaStructEmitter.class.getName(),
- "-C" + config,
- header.getPath());
+ final List<String> cfgFiles = new ArrayList<String>();
+ cfgFiles.add(config);
+ final List<String> includePaths = new ArrayList<String>();
+ includePaths.add(headerParent);
+ includePaths.add(outputPath1);
+ final Reader reader;
+ final String filename = header.getPath();
+ try {
+ reader = new BufferedReader(new FileReader(filename));
+ } catch (FileNotFoundException ex) {
+ throw new RuntimeException("input file not found", ex);
+ }
+ new GlueGen().run(reader, filename, AnnotationProcessorJavaStructEmitter.class,
+ includePaths, cfgFiles, outputPath1, false /* copyCPPOutput2Stderr */);
configFile.delete();
+ generatedStructs.add(finalType);
}
public static class AnnotationProcessorJavaStructEmitter extends JavaEmitter {
@@ -234,14 +275,17 @@ public class CStructAnnotationProcessor extends AbstractProcessor {
@Override
protected PrintWriter openFile(String filename, String simpleClassName) throws IOException {
+ if( generatedStructs.contains(simpleClassName) ) {
+ System.err.println("skipping -> " + simpleClassName);
+ return null;
+ }
+
// look for recursive generated structs... keep it DRY
if( !simpleClassName.endsWith("32") &&
!simpleClassName.endsWith("64") ) {
-
- System.out.println("generating -> " + simpleClassName);
+ System.err.println("generating -> " + simpleClassName);
generatedStructs.add(simpleClassName);
}
-
return super.openFile(filename, simpleClassName);
}
diff --git a/src/java/com/jogamp/gluegen/structgen/CStructs.java b/src/java/com/jogamp/gluegen/structgen/CStructs.java
new file mode 100644
index 0000000..1023d3e
--- /dev/null
+++ b/src/java/com/jogamp/gluegen/structgen/CStructs.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, Michael Bien. All rights reserved.
+ * Copyright (c) 2013 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:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Michael Bien nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 Michael Bien 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.
+ */
+
+package com.jogamp.gluegen.structgen;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Multiple {@link CStruct} elements
+ */
+@Target(value = {ElementType.TYPE, ElementType.PACKAGE, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
+@Retention(value = RetentionPolicy.SOURCE)
+public @interface CStructs {
+
+ /**
+ * Multiple {@link CStruct} elements.
+ */
+ CStruct[] value();
+}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/structgen/BuildStruct01.java b/src/junit/com/jogamp/gluegen/test/junit/structgen/BuildStruct01.java
new file mode 100644
index 0000000..7824e55
--- /dev/null
+++ b/src/junit/com/jogamp/gluegen/test/junit/structgen/BuildStruct01.java
@@ -0,0 +1,34 @@
+package com.jogamp.gluegen.test.junit.structgen;
+
+import com.jogamp.gluegen.structgen.CStruct;
+
+/**
+ * Class simply triggering CStruct annotation processor to generate the types 'RenderingConfig' etc.
+ * <p>
+ * Due to Java8 issues, see Bug 923,
+ * using {@link package-info} is more elegant to kick-off the annotation processor.
+ * </p>
+ */
+public class BuildStruct01 {
+
+ // APT is only triggered for fields,
+ // hence we use unused fields in this unit test!
+
+ // @CStruct(name="RenderingConfig", header="TestStruct01.h")
+ // MyRenderingConfig config;
+
+ // @CStruct(header="TestStruct01.h")
+ // MyRenderingConfig config;
+
+ /**
+ * Java8: We cannot use type 'RenderingConfig' yet (bug?) even if not compiling.
+ * Hence we force the type-name via 'jname' and use a dummy variable!
+ */
+ @CStruct(name="RenderingConfig", jname="RenderingConfig", header="TestStruct01.h")
+ boolean dummy1;
+
+ @CStruct(name="Pixel", jname="Pixel", header="TestStruct02.h")
+ boolean dummy2;
+
+ public static void initSingleton() {}
+}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStruct02.h b/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStruct02.h
new file mode 100644
index 0000000..64fda78
--- /dev/null
+++ b/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStruct02.h
@@ -0,0 +1,14 @@
+//
+// TestStruct02.h
+//
+
+#include "TestStruct01.h"
+
+typedef struct {
+ float r, g, b, a;
+} Col4f;
+
+typedef struct {
+ Col4f color;
+ Vec3f pos;
+} Pixel;
diff --git a/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java b/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java
index 23b1624..74f0552 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen01.java
@@ -1,26 +1,23 @@
package com.jogamp.gluegen.test.junit.structgen;
-import com.jogamp.gluegen.structgen.CStruct;
import com.jogamp.junit.util.JunitTracer;
import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
-
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestStructGen01 extends JunitTracer {
- // APT is only triggered for fields,
- // hence we use unused fields in this unit test!
-
- // @CStruct(name="RenderingConfig", header="TestStruct01.h")
- // MyRenderingConfig config;
-
- @CStruct(header="TestStruct01.h")
- RenderingConfig config0;
-
+ @BeforeClass
+ public static void init() {
+ // Enforce dependency,
+ // i.e. CStruct annotation processor to generate the types 'RenderingConfig' etc.
+ BuildStruct01.initSingleton();
+ }
+
@Test
public void test01() {
RenderingConfig config = RenderingConfig.create();
@@ -46,10 +43,10 @@ public class TestStructGen01 extends JunitTracer {
cam_orig.setY(1);
cam_orig.setZ(2);
}
-
+
public static void main(String args[]) {
String tstname = TestStructGen01.class.getName();
org.junit.runner.JUnitCore.main(tstname);
}
-
+
}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java b/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java
new file mode 100644
index 0000000..a8f0e52
--- /dev/null
+++ b/src/junit/com/jogamp/gluegen/test/junit/structgen/TestStructGen02.java
@@ -0,0 +1,51 @@
+package com.jogamp.gluegen.test.junit.structgen;
+
+import com.jogamp.junit.util.JunitTracer;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestStructGen02 extends JunitTracer {
+
+ @BeforeClass
+ public static void init() {
+ // Enforce dependency,
+ // i.e. CStruct annotation processor to generate the types 'RenderingConfig' etc.
+ BuildStruct01.initSingleton();
+ }
+
+ @Test
+ public void test01() {
+ final Pixel pixel = Pixel.create();
+ final Col4f color = pixel.getColor();
+ color.setR(1f);
+ color.setG(2f);
+ color.setB(3f);
+ color.setA(4f);
+ final Vec3f pos = pixel.getPos();
+ pos.setX(0.5f);
+ pos.setY(0.6f);
+ pos.setZ(0.7f);
+
+ Pixel pixel2 = Pixel.create(pixel.getBuffer());
+ final Col4f color2 = pixel2.getColor();
+ Assert.assertEquals(color.getR(), color2.getR(), 0.0001f);
+ Assert.assertEquals(color.getG(), color2.getG(), 0.0001f);
+ Assert.assertEquals(color.getB(), color2.getB(), 0.0001f);
+ Assert.assertEquals(color.getA(), color2.getA(), 0.0001f);
+ final Vec3f pos2 = pixel2.getPos();
+ Assert.assertEquals(pos.getX(), pos2.getX(), 0.0001f);
+ Assert.assertEquals(pos.getY(), pos2.getY(), 0.0001f);
+ Assert.assertEquals(pos.getZ(), pos2.getZ(), 0.0001f);
+ }
+
+ public static void main(String args[]) {
+ String tstname = TestStructGen02.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/structgen/package-info.java b/src/junit/com/jogamp/gluegen/test/junit/structgen/package-info.java
new file mode 100644
index 0000000..d009c5f
--- /dev/null
+++ b/src/junit/com/jogamp/gluegen/test/junit/structgen/package-info.java
@@ -0,0 +1,15 @@
+/**
+ * Package scope generation of {@link CStruct}s
+ * avoiding Java8 issues w/ annotation processing
+ * where the generated class is not yet available.
+ * <p>
+ * See Bug 923.
+ * </p>
+ * @see BuildStruct01
+ */
+@CStructs({@CStruct(name="RenderingConfig", header="TestStruct01.h"), @CStruct(name="Pixel", header="TestStruct02.h")})
+package com.jogamp.gluegen.test.junit.structgen;
+
+import com.jogamp.gluegen.structgen.CStructs;
+import com.jogamp.gluegen.structgen.CStruct;
+
diff --git a/test/junit/com/jogamp/gluegen/StructAccessorTest.java b/test/junit/com/jogamp/gluegen/StructAccessorTest.java
index 4d1bffd..6c8d0e8 100644
--- a/test/junit/com/jogamp/gluegen/StructAccessorTest.java
+++ b/test/junit/com/jogamp/gluegen/StructAccessorTest.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,12 +20,12 @@
* 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;
import java.io.File;
@@ -35,15 +35,18 @@ import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
+
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
-import junit.framework.Assert;
+
import org.junit.AfterClass;
+import org.junit.Assert;
import org.junit.Test;
+
import static java.lang.System.*;
import static com.jogamp.gluegen.BuildUtil.*;