summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/gluegen/structgen
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/jogamp/gluegen/structgen')
-rw-r--r--src/java/com/jogamp/gluegen/structgen/CStruct.java53
-rw-r--r--src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java240
2 files changed, 293 insertions, 0 deletions
diff --git a/src/java/com/jogamp/gluegen/structgen/CStruct.java b/src/java/com/jogamp/gluegen/structgen/CStruct.java
new file mode 100644
index 0000000..9d57196
--- /dev/null
+++ b/src/java/com/jogamp/gluegen/structgen/CStruct.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+/**
+ *
+ * @author Michael Bien
+ * @author Sven Gothel, et.al.
+ */
+@Target(value = {ElementType.FIELD, ElementType.LOCAL_VARIABLE})
+@Retention(value = RetentionPolicy.SOURCE)
+public @interface CStruct {
+
+ /**
+ * Relative path to the header file.
+ */
+ String header();
+
+ /**
+ * The name of the struct.
+ */
+ String name() default "_default_";
+}
diff --git a/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
new file mode 100644
index 0000000..fef8545
--- /dev/null
+++ b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
@@ -0,0 +1,240 @@
+/*
+ * 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 com.jogamp.common.util.PropertyAccess;
+import com.jogamp.gluegen.GlueGen;
+import com.jogamp.gluegen.JavaEmitter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.tools.Diagnostic.Kind;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+
+import jogamp.common.Debug;
+
+import static java.io.File.*;
+
+/**
+ * <p>
+ * If the <i>header file</i> is absolute, the <i>root path</i> is the parent folder of the folder containing the package source, i.e.:
+ * <pre>
+ * Header: /gluegen/src/junit/com/jogamp/test/structgen/TestStruct01.h
+ * Root: /gluegen/src/junit/..
+ * Root: /gluegen/src
+ * </pre>
+ * Otherwise the <i>user.dir</i> is being used as the <i>root path</i>
+ * and the relative <i>header file</i> is appended to it.
+ * </p>
+ * The property <code>jogamp.gluegen.structgen.output</code> allows setting a default <i>outputPath</i>
+ * for the generated sources, if the {@link ProcessingEnvironment}'s <code>structgen.output</code> option is not set.
+ * <p>
+ * If the <i>outputPath</i> is relative, it is appended to the <i>root path</i>,
+ * otherwise it is taken as-is.
+ * </p>
+ * <p>
+ * User can enable DEBUG while defining property <code>jogamp.gluegen.structgen.debug</code>.
+ * </p>
+ *
+ * @author Michael Bien
+ * @author Sven Gothel, et.al.
+ */
+@SupportedAnnotationTypes(value = {"com.jogamp.gluegen.structgen.CStruct"})
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class CStructAnnotationProcessor extends AbstractProcessor {
+ private static final boolean DEBUG = Debug.isPropertyDefined("jogamp.gluegen.structgen.debug", true);
+ private static final String DEFAULT = "_default_";
+
+ private static final String STRUCTGENOUTPUT_OPTION = "structgen.output";
+ private static final String STRUCTGENOUTPUT = PropertyAccess.getProperty("jogamp.gluegen."+STRUCTGENOUTPUT_OPTION, true, "gensrc");
+
+ private Filer filer;
+ private Messager messager;
+ private Elements eltUtils;
+ private String outputPath;
+
+ private final static Set<String> generatedStructs = new HashSet<String>();
+
+
+ @Override
+ public void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+
+ filer = processingEnv.getFiler();
+ messager = processingEnv.getMessager();
+ eltUtils = processingEnv.getElementUtils();
+
+ outputPath = processingEnv.getOptions().get(STRUCTGENOUTPUT_OPTION);
+ outputPath = outputPath == null ? STRUCTGENOUTPUT : outputPath;
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
+
+ Set<? extends Element> elements = env.getElementsAnnotatedWith(CStruct.class);
+
+ for (Element element : elements) {
+
+ final String packageName = eltUtils.getPackageOf(element).toString();
+ final String user_dir = System.getProperty("user.dir");
+
+ try {
+ final CStruct struct = element.getAnnotation(CStruct.class);
+ final String headerRelPath = struct.header();
+ final FileObject header;
+ final File headerFileRel;
+ {
+ FileObject h = filer.getResource(StandardLocation.SOURCE_PATH, packageName, headerRelPath);
+ File f = new File( h.toUri().getPath() ); // URI is incomplete (no scheme), hence use path only!
+ if( !f.exists() ) {
+ h = filer.getResource(StandardLocation.SOURCE_PATH, "", headerRelPath);
+ f = new File( h.toUri().getPath() ); // URI is incomplete (no scheme), hence use path only!
+ if( !f.exists() ) {
+ // bail out
+ throw new RuntimeException("Could not locate header "+headerRelPath+", package "+packageName);
+ }
+ }
+ header = h;
+ headerFileRel = f;
+ }
+
+ final boolean headerFileRelIsAbsolute = headerFileRel.isAbsolute();
+
+ final String root;
+ final File headerFile;
+ if( headerFileRelIsAbsolute ) {
+ headerFile = headerFileRel;
+
+ String root0 = headerFile.getAbsolutePath();
+ root0 = root0.substring(0, root0.length()-headerFile.getName().length()-1);
+ root = root0.substring(0, root0.length()-packageName.length()) +"..";
+ } else {
+ root = user_dir;
+ headerFile = new File(root + separator + header.toUri());
+ }
+ System.err.println("CStruct: "+struct);
+ System.err.println("CStruct: package "+packageName+", header "+headerRelPath+": "+headerFile);
+ if(DEBUG) {
+ System.err.println("CStruct: header "+headerFileRel+", abs-path: "+headerFileRelIsAbsolute);
+ System.err.println("CStruct: Root: "+root);
+ System.err.println("CStruct: user.dir: "+user_dir);
+ }
+
+ generateStructBinding(element, struct, root, packageName, headerFile);
+ } 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 {
+ 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);
+ 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 + separator + outputPath;
+ final String config = outputPath1 + separator + header.getName() + ".cfg";
+ final File configFile = new File(config);
+ if(DEBUG) {
+ System.err.println("CStruct: OutputDir: "+outputPath+", is-abs "+outputDirAbs);
+ System.err.println("CStruct: OutputPath: "+outputPath1);
+ System.err.println("CStruct: ConfigFile: "+configFile);
+ }
+
+ FileWriter writer = null;
+ try{
+ writer = new FileWriter(configFile);
+ writer.write("Package "+pakage+"\n");
+ writer.write("EmitStruct "+structName+"\n");
+ if(!struct.name().equals(DEFAULT)) {
+ writer.write("RenameJavaType " + struct.name()+" " + declaredType +"\n");
+ }
+ } finally {
+ if( null != writer ) {
+ writer.close();
+ }
+ }
+
+ // TODO: Handle exceptions .. suppressed by Gluegen.main(..) ?
+ GlueGen.main(
+ // "-I"+path+"/build/",
+ "-O" + outputPath1,
+ "-E" + AnnotationProcessorJavaStructEmitter.class.getName(),
+ "-C" + config,
+ header.getPath());
+
+ configFile.delete();
+ }
+
+ public static class AnnotationProcessorJavaStructEmitter extends JavaEmitter {
+
+ @Override
+ protected PrintWriter openFile(String filename, String simpleClassName) throws IOException {
+
+ // look for recursive generated structs... keep it DRY
+ if( !simpleClassName.endsWith("32") &&
+ !simpleClassName.endsWith("64") ) {
+
+ System.out.println("generating -> " + simpleClassName);
+ generatedStructs.add(simpleClassName);
+ }
+
+ return super.openFile(filename, simpleClassName);
+ }
+
+ }
+
+}