Skip to content

Commit 3a74fa4

Browse files
committed
Added -Tname=type option to force typedefs.
1 parent 2fb395a commit 3a74fa4

5 files changed

Lines changed: 48 additions & 6 deletions

File tree

libraries/jnaerator/jnaerator/src/main/java/com/ochafik/lang/jnaerator/JNAerator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@ List<String> parsed(ParsedArg a) throws Exception {
359359
case DefineMacro:
360360
config.preprocessorConfig.macros.put(a.getStringParam(0), a.getStringParam(1));
361361
break;
362+
case DefineType:
363+
config.preprocessorConfig.forcedTypeDefs.put(a.getStringParam(0), a.getStringParam(1));
364+
break;
362365
case Direct:
363366
config.useJNADirectCalls = true;
364367
break;

libraries/jnaerator/jnaerator/src/main/java/com/ochafik/lang/jnaerator/JNAeratorCommandLineArgs.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ public enum OptionDef {
194194
Runtime( "-runtime", "Choose target runtime library between " + StringUtils.implode(JNAeratorConfig.Runtime.values(), ", ") + " (default: " + JNAeratorConfig.Runtime.DEFAULT + ").", new ArgDef(Type.Enum, "enum", JNAeratorConfig.Runtime.class)),
195195
IfRegexMatch( "-ifRegexMatch", "Conditional evaluation of an argument if a java system property matches a regular expression", new ArgDef(Type.String, "javaProperty"), new ArgDef(Type.String, "regex"), new ArgDef(Type.String, "thenArg"), new ArgDef(Type.String, "elseArg")),
196196
DefineMacro( "-D([^=]*)(?:=(.*))?", "Define a macro symbol", new ArgDef(Type.String, "name"), new ArgDef(Type.String, "value")),
197+
DefineType( "-T([^=]*)(?:=(.*))?", "Define a type symbol", new ArgDef(Type.String, "name"), new ArgDef(Type.String, "value")),
197198
NoAutoImports( "-noAutoImport", "Don't add import statements automatically to output java source files"),
198199
RootPackage( "-root(?:Package)?", "Define the root package for all output classes", new ArgDef(Type.String, "package")),
199200
CurrentLibrary( "-library", "Define the name of the output library. This is a state parameter, it will affect all files listed after it, until another -library switch is provided. It does not affect sources included from a project file (Visual Studio...).\n" +

libraries/jnaerator/jnaerator/src/main/java/com/ochafik/lang/jnaerator/JNAeratorConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ public static class PreprocessorConfig {
271271

272272
public final List<String> includes = new ArrayList<String>();
273273
public final Map<String, String> macros = new LinkedHashMap<String, String>();
274+
public final Map<String, String> forcedTypeDefs = new LinkedHashMap<String, String>();
274275
public final List<String> frameworksPath = new ArrayList<String>();
275276

276277
public List<String> includeStrings = new ArrayList<String>();

libraries/jnaerator/jnaerator/src/main/java/com/ochafik/lang/jnaerator/JNAeratorParser.java

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,17 @@ This file is part of JNAerator (http://jnaerator.googlecode.com/).
4444

4545
import com.ochafik.io.WriteText;
4646
import com.ochafik.lang.jnaerator.PreprocessorUtils.MacroUseCallback;
47+
import com.ochafik.lang.jnaerator.parser.Declarator;
4748
import com.ochafik.lang.jnaerator.parser.ObjCppLexer;
4849
import com.ochafik.lang.jnaerator.parser.ObjCppParser;
50+
import com.ochafik.lang.jnaerator.parser.Scanner;
4951
import com.ochafik.lang.jnaerator.parser.SourceFile;
52+
import com.ochafik.lang.jnaerator.parser.StoredDeclarations.TypeDef;
5053
import com.ochafik.lang.reflect.DebugUtils;
5154
import com.ochafik.util.listenable.Pair;
5255
import com.ochafik.util.string.RegexUtils;
5356
import java.util.Collection;
57+
import java.util.Map;
5458

5559
public class JNAeratorParser {
5660

@@ -194,21 +198,52 @@ public String replace(String[] groups) {
194198
});
195199
return replaced;
196200
}
197-
public SourceFiles parse(JNAeratorConfig config, TypeConversion typeConverter, MacroUseCallback macrosDependenciesOut) throws IOException, LexerException {
201+
private SourceFiles removeTypeDefsConflictingWithForcedTypeDefs(SourceFiles sourceFiles, final Set<String> forcedTypeDefs) {
202+
sourceFiles.accept(new Scanner() {
203+
Set<String> seenOnce = new HashSet<String>();
204+
@Override
205+
public void visitTypeDef(TypeDef typeDef) {
206+
super.visitTypeDef(typeDef);
207+
List<Declarator> declaratorsToRemove = null;
208+
for (Declarator d : typeDef.getDeclarators()) {
209+
String n = d.resolveName();
210+
if (forcedTypeDefs.contains(n) && !seenOnce.add(n)) {
211+
if (declaratorsToRemove == null)
212+
declaratorsToRemove = new ArrayList<Declarator>();
213+
declaratorsToRemove.add(d);
214+
}
215+
}
216+
if (declaratorsToRemove != null) {
217+
for (Declarator d : declaratorsToRemove)
218+
d.replaceBy(null);
219+
}
220+
}
221+
});
222+
return sourceFiles;
223+
}
224+
public SourceFiles parse(final JNAeratorConfig config, TypeConversion typeConverter, MacroUseCallback macrosDependenciesOut) throws IOException, LexerException {
198225
SourceFiles sourceFiles = new SourceFiles();
199226

227+
StringBuilder syntheticTypeDefsBuilder = new StringBuilder();
228+
for (Map.Entry<String, String> e : config.preprocessorConfig.forcedTypeDefs.entrySet()) {
229+
syntheticTypeDefsBuilder.append("typedef ").append(e.getValue()).append(" ").append(e.getKey()).append(";");
230+
}
231+
config.preprocessorConfig.includeStrings.add(0, syntheticTypeDefsBuilder.toString());
232+
200233
String sourceContent = PreprocessorUtils.preprocessSources(config, sourceFiles.defines, config.verbose, typeConverter, macrosDependenciesOut);
201234

202235
if (config.removeInlineAsm)
203236
sourceContent = removeInlineAsm(sourceContent);
204237

205238
ExecutorService executor = Executors.newSingleThreadExecutor();
206239
try {
240+
final Set<String> topLevelTypeDefs = Collections.synchronizedSet(config.preprocessorConfig.forcedTypeDefs.keySet());
241+
207242
if (!config.parseInChunks) {
208-
Future<SourceFile> fut = executor.submit(createParsingCallable(config, typeConverter, sourceContent, null, true));
243+
Future<SourceFile> fut = executor.submit(createParsingCallable(config, typeConverter, sourceContent, topLevelTypeDefs, true));
209244
try {
210245
sourceFiles.add(fut.get(config.fullParsingTimeout, TimeUnit.MILLISECONDS));
211-
return sourceFiles;
246+
return removeTypeDefsConflictingWithForcedTypeDefs(sourceFiles, topLevelTypeDefs);
212247
} catch (Throwable ex) {
213248
ex.printStackTrace();
214249
System.err.println("Parsing failed : " + ex);
@@ -226,7 +261,6 @@ public SourceFiles parse(JNAeratorConfig config, TypeConversion typeConverter, M
226261
if (config.verbose)
227262
System.out.println("Now parsing " + slices.size() + " slices");
228263

229-
final Set<String> topLevelTypeDefs = Collections.synchronizedSet(new HashSet<String>());
230264
boolean firstFailure = true;
231265
for (Slice slice : slices) {
232266
try {
@@ -246,7 +280,7 @@ public SourceFiles parse(JNAeratorConfig config, TypeConversion typeConverter, M
246280
System.err.println("Parsing failed : " + ex);
247281
}
248282
}
249-
return sourceFiles;
283+
return removeTypeDefsConflictingWithForcedTypeDefs(sourceFiles, topLevelTypeDefs);
250284
} finally {
251285
executor.shutdown();
252286
}

libraries/jnaerator/jnaerator/src/main/java/com/ochafik/lang/jnaerator/PreprocessorUtils.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public static String preprocessSources(JNAeratorConfig config, Collection<String
102102
return sourceContent;
103103
}
104104

105-
public static Preprocessor createPreProcessor(JNAeratorConfig.PreprocessorConfig config, final MacroUseCallback macrosDependenciesOut) throws IOException, LexerException {
105+
public static Preprocessor createPreProcessor(final JNAeratorConfig.PreprocessorConfig config, final MacroUseCallback macrosDependenciesOut) throws IOException, LexerException {
106106
Preprocessor preprocessor = new Preprocessor() {
107107
HashSet<VirtualFile> filesAlreadyIncluded = new HashSet<VirtualFile>();
108108

@@ -159,6 +159,9 @@ public void clear() {
159159
public Macro put(String key, Macro value) {
160160
if (key != null)
161161
used(key);
162+
if (config.forcedTypeDefs.containsKey(key)) {
163+
return null;
164+
}
162165
return super.put(key, value);
163166
}
164167

0 commit comments

Comments
 (0)