28package com.jogamp.gluegen.structgen;
30import com.jogamp.common.util.PropertyAccess;
31import com.jogamp.gluegen.CCodeUnit;
32import com.jogamp.gluegen.GlueGen;
33import com.jogamp.gluegen.JavaCodeUnit;
34import com.jogamp.gluegen.JavaEmitter;
36import java.io.BufferedReader;
38import java.io.FileNotFoundException;
39import java.io.FileReader;
40import java.io.FileWriter;
41import java.io.IOException;
42import java.io.PrintWriter;
44import java.util.ArrayList;
45import java.util.HashSet;
49import javax.annotation.processing.AbstractProcessor;
50import javax.annotation.processing.Filer;
51import javax.annotation.processing.Messager;
52import javax.annotation.processing.ProcessingEnvironment;
53import javax.annotation.processing.RoundEnvironment;
54import javax.annotation.processing.SupportedAnnotationTypes;
55import javax.annotation.processing.SupportedSourceVersion;
56import javax.lang.model.SourceVersion;
57import javax.lang.model.element.Element;
58import javax.lang.model.element.TypeElement;
59import javax.lang.model.util.Elements;
60import javax.tools.Diagnostic.Kind;
61import javax.tools.FileObject;
62import javax.tools.StandardLocation;
64import jogamp.common.Debug;
89@SupportedAnnotationTypes(value = {
"com.jogamp.gluegen.structgen.CStruct",
"com.jogamp.gluegen.structgen.CStructs"})
90@SupportedSourceVersion(SourceVersion.RELEASE_11)
92 private static final String DEFAULT =
"_default_";
93 static final boolean DEBUG;
96 Debug.initSingleton();
100 private static final String STRUCTGENOUTPUT_OPTION =
"structgen.output";
101 private static final String STRUCTGENPRAGMA_ONCE =
"structgen.enable.pragma.once";
102 private static final String STRUCTGENOUTPUT =
PropertyAccess.
getProperty(
"jogamp.gluegen."+STRUCTGENOUTPUT_OPTION,
true,
"gensrc");
103 private static final String STRUCTGENPRAGMAONCE =
PropertyAccess.
getProperty(
"jogamp.gluegen."+STRUCTGENPRAGMA_ONCE,
true,
"true");
106 private Messager messager;
107 private Elements eltUtils;
108 private String outputPath;
109 private boolean enablePragmaOnce;
111 private final static Set<String> generatedStructs =
new HashSet<String>();
115 public void init(
final ProcessingEnvironment processingEnv) {
116 super.init(processingEnv);
118 filer = processingEnv.getFiler();
119 messager = processingEnv.getMessager();
120 eltUtils = processingEnv.getElementUtils();
122 outputPath = processingEnv.getOptions().get(STRUCTGENOUTPUT_OPTION);
123 outputPath = outputPath ==
null ? STRUCTGENOUTPUT : outputPath;
125 final String enablePragmaOnceOpt = processingEnv.getOptions().get(STRUCTGENPRAGMAONCE);
126 enablePragmaOnce = Boolean.parseBoolean(enablePragmaOnceOpt ==
null ? STRUCTGENPRAGMAONCE : enablePragmaOnceOpt);
129 private File locateSource(
final String packageName,
final String relativeName) {
132 System.err.println(
"CStruct.locateSource.0: p "+packageName+
", r "+relativeName);
134 final FileObject h = filer.getResource(StandardLocation.SOURCE_PATH, packageName, relativeName);
136 System.err.println(
"CStruct.locateSource.1: h "+h.toUri());
138 final File f =
new File( h.toUri().getPath() );
142 }
catch (
final IOException e) {
144 System.err.println(
"Caught "+e.getClass().getSimpleName()+
": "+e.getMessage());
151 public boolean process(
final Set<? extends TypeElement> annotations,
final RoundEnvironment env) {
152 final String user_dir = System.getProperty(
"user.dir");
154 final Set<? extends Element> cStructsElements = env.getElementsAnnotatedWith(
CStructs.class);
155 for (
final Element structsElement : cStructsElements) {
156 final String packageName = eltUtils.getPackageOf(structsElement).toString();
158 if(
null != cstructs ) {
160 for(
final CStruct cstruct : cstructArray) {
161 processCStruct(cstruct, structsElement, packageName, user_dir);
166 final Set<? extends Element> cStructElements = env.getElementsAnnotatedWith(
CStruct.class);
167 for (
final Element structElement : cStructElements) {
168 final String packageName = eltUtils.getPackageOf(structElement).toString();
169 final CStruct cstruct = structElement.getAnnotation(
CStruct.class);
170 if(
null != cstruct ) {
171 processCStruct(cstruct, structElement, packageName, user_dir);
177 private void processCStruct(
final CStruct struct,
final Element element,
final String packageName,
final String user_dir) {
179 final String headerRelPath = struct.
header();
180 final Element enclElement = element.getEnclosingElement();
181 final boolean isPackageOrType =
null == enclElement;
183 System.err.println(
"CStruct: "+struct+
", package "+packageName+
", header "+headerRelPath);
185 System.err.println(
"CStruct.0: user.dir: "+user_dir);
186 System.err.println(
"CStruct.0: element: "+element+
", .simpleName "+element.getSimpleName());
187 System.err.print(
"CStruct.0: isPackageOrType "+isPackageOrType+
", enclElement: "+enclElement);
188 if( !isPackageOrType ) {
189 if(!enclElement.toString().equals(
"unnamed module"))
190 System.err.println(
", .simpleName "+enclElement.getSimpleName()+
", .package "+eltUtils.getPackageOf(enclElement).toString());
192 System.err.println(
", .simpleName "+enclElement.getSimpleName()+
", .package <unnamed modules have no package>");
194 System.err.println(
"");
197 if( isPackageOrType && struct.
name().equals(DEFAULT) ) {
198 throw new IllegalArgumentException(
"CStruct annotation on package or type must have name specified: "+struct+
" @ "+element);
201 final File headerFile;
203 File f = locateSource(packageName, headerRelPath);
205 f = locateSource(
"", headerRelPath);
208 throw new RuntimeException(
"Could not locate header "+headerRelPath+
", package "+packageName);
214 final String rootOut, headerParent;
216 final String root0 = headerFile.getAbsolutePath();
217 headerParent = root0.substring(0, root0.length()-headerFile.getName().length()-1);
218 rootOut = headerParent.substring(0, headerParent.length()-packageName.length()) +
"..";
220 System.err.println(
"CStruct: "+headerFile+
", abs: "+headerFile.isAbsolute()+
", headerParent "+headerParent+
", rootOut "+rootOut+
", enablePragmaOnce "+enablePragmaOnce);
222 generateStructBinding(element, struct, isPackageOrType, rootOut, packageName, headerFile, headerParent);
223 }
catch (
final IOException ex) {
224 throw new RuntimeException(
"IOException while processing!", ex);
228 private void generateStructBinding(
final Element element,
final CStruct struct,
final boolean isPackageOrType,
final String rootOut,
final String pakage,
final File header,
final String headerParent)
throws IOException {
229 final String declaredType = element.asType().toString();
230 final boolean useStructName = !struct.
name().equals(DEFAULT);
231 final String structName = useStructName ? struct.
name() : declaredType;
232 final boolean useJavaName = !struct.
jname().equals(DEFAULT);
234 final String finalType = useJavaName ? struct.
jname() : ( !isPackageOrType ? declaredType : structName );
235 System.err.println(
"CStruct: Generating struct accessor for struct: "+structName+
" -> "+finalType+
" [struct.name "+struct.
name()+
", struct.jname "+struct.
jname()+
", declaredType "+declaredType+
"]");
236 if( generatedStructs.contains(finalType) ) {
237 messager.printMessage(Kind.NOTE,
"struct "+structName+
" already defined elsewhere, skipping.", element);
241 final boolean outputDirAbs;
243 final File outputDirFile =
new File(outputPath);
244 outputDirAbs = outputDirFile.isAbsolute();
246 final String outputPath1 = outputDirAbs ? outputPath : rootOut + File.separator + outputPath;
247 final String config = outputPath1 + File.separator + header.getName() +
".cfg";
248 final File configFile =
new File(config);
250 System.err.println(
"CStruct: OutputDir: "+outputPath+
", is-abs "+outputDirAbs);
251 System.err.println(
"CStruct: OutputPath: "+outputPath1);
252 System.err.println(
"CStruct: ConfigFile: "+configFile);
255 FileWriter writer =
null;
257 writer =
new FileWriter(configFile);
258 writer.write(
"Package "+pakage+
"\n");
259 writer.write(
"EmitStruct "+structName+
"\n");
260 if( !useJavaName && (finalType != structName) ) {
262 writer.write(
"RenameJavaType " + struct.
name()+
" " + declaredType +
"\n");
265 if(
null != writer ) {
269 final List<String> cfgFiles =
new ArrayList<String>();
270 cfgFiles.add(config);
271 final List<String> includePaths =
new ArrayList<String>();
272 includePaths.add(headerParent);
273 includePaths.add(outputPath1);
275 final String filename = header.getPath();
277 reader =
new BufferedReader(
new FileReader(filename));
278 }
catch (
final FileNotFoundException ex) {
279 throw new RuntimeException(
"input file not found", ex);
282 GlueGen.setDebug(
true);
284 new GlueGen().run(reader, filename, AnnotationProcessorJavaStructEmitter.class,
285 includePaths, cfgFiles, outputPath1,
false ,
286 enablePragmaOnce ,
false );
288 generatedStructs.add(finalType);
293 private boolean filter(
final String simpleClassName) {
294 if( generatedStructs.contains(simpleClassName) ) {
295 System.err.println(
"skipping -> " + simpleClassName);
300 if( !simpleClassName.endsWith(
"32") &&
301 !simpleClassName.endsWith(
"64") ) {
302 System.err.println(
"generating -> " + simpleClassName);
303 generatedStructs.add(simpleClassName);
310 if( !filter(cUnitName) ) {
313 return super.openCUnit(filename, cUnitName);
324 protected JavaCodeUnit openJavaUnit(
final String filename,
final String packageName,
final String simpleClassName)
throws IOException {
325 if( !filter(simpleClassName) ) {
328 return super.openJavaUnit(filename, packageName, simpleClassName);
Helper routines for accessing properties.
static final boolean isPropertyDefined(final String property, final boolean jnlpAlias)
static final String getProperty(final String propertyKey, final boolean jnlpAlias)
Query the property with the name propertyKey.
C code unit (a generated C source file), covering multiple FunctionEmitter allowing to unify output,...
Java code unit (a generated Java source file), covering multiple FunctionEmitter allowing to unify ou...
CCodeUnit openCUnit(final String filename, final String cUnitName)
JavaCodeUnit openJavaUnit(final String filename, final String packageName, final String simpleClassName)
boolean process(final Set<? extends TypeElement > annotations, final RoundEnvironment env)
void init(final ProcessingEnvironment processingEnv)
String name() default "_default_"
The name of the struct.
String jname() default "_default_"
The optional java name of the struct.
String header()
Relative path to the header file.
Multiple CStruct elements.
CStruct[] value()
Multiple CStruct elements.