summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-05-11 03:03:36 +0200
committerSven Gothel <[email protected]>2014-05-11 03:03:36 +0200
commit1e53a38eb06aa8ff50660fdf7bd8570b27f27c56 (patch)
treef061dfb77af5b4c1f27da78b4dbd1881b400abc3 /src/java/com/jogamp
parent598da96b3d2ffc3e0915f73749cbafa5fa5cea90 (diff)
Bug 923: Remove dependency of CStruct annotation processor _generation_ and generated_class_user due to Java8 issues.
Java8's annotation processor as embedded within javac does not allow referencing not-yet existing generated classes in a class source code which will produce these generated classes via the annotation process. Example: +++ import com.jogamp.gluegen.structgen.CStruct; public class Lala { @CStruct(name="RenderingConfig", header="TestStruct01.h") public RenderingConfig config; } +++ Above example illustrates that the type 'RenderingConfig' does not exist at time of processing the annotation. The type will be created via the annotation process itself. Even though we pass '-proc:only', i.e. skip java compilation, Java8's annotation processing via javac fails in such case. We see this as a bug within javac's annotation processing itself! +++ This workaround splits the annotation process and using the class as generated by the former. To allow this to work, CStruct receives a new field 'jname' allowing to enforce the java-name of the structure using a dummy field type like boolean. @CStruct(name="RenderingConfig", jname="RenderingConfig", header="TestStruct01.h") public boolean dummy; Further more CStruct can be annotated on the package, i.e. 'package-info.java', avoiding the dependency problem altogether. To support multiple header files and types, 'CStructs' has been introduced using an array of 'CStruct'. @CStructs({@CStruct(name="RenderingConfig", header="TestStruct01.h"), @CStruct(name="Pixel", header="TestStruct02.h")}) package com.jogamp.gluegen.test.junit.structgen; Tests: - Build w/ Java7 and Java8 - Validated 'major version 50' (Java 6) class files (OK)
Diffstat (limited to 'src/java/com/jogamp')
-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
4 files changed, 281 insertions, 177 deletions
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();
+}