Skip to content

Commit

Permalink
refactor: Rewrite macro parsing, but it was actually pointless
Browse files Browse the repository at this point in the history
  • Loading branch information
Berstanio committed Jan 1, 2025
1 parent 8133a42 commit 0a28eb1
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@
import com.badlogic.gdx.jnigen.generator.parser.CommentParser;
import com.badlogic.gdx.jnigen.generator.parser.EnumParser;
import com.badlogic.gdx.jnigen.generator.parser.StackElementParser;
import com.badlogic.gdx.jnigen.generator.types.ClosureType;
import com.badlogic.gdx.jnigen.generator.types.FunctionSignature;
import com.badlogic.gdx.jnigen.generator.types.FunctionType;
import com.badlogic.gdx.jnigen.generator.types.MappedType;
import com.badlogic.gdx.jnigen.generator.types.NamedType;
import com.badlogic.gdx.jnigen.generator.types.PointerType;
import com.badlogic.gdx.jnigen.generator.types.PrimitiveType;
import com.badlogic.gdx.jnigen.generator.types.TypeDefinition;
import com.badlogic.gdx.jnigen.generator.types.TypeKind;
import com.badlogic.gdx.jnigen.generator.types.*;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.IntPointer;
import org.bytedeco.javacpp.PointerPointer;
Expand Down Expand Up @@ -307,7 +299,9 @@ public int call(@ByVal CXCursor current, @ByVal CXCursor parent, CXClientData cx
for (int i = 1; i < nTokens.get(); i++) {
value.append(clang_getTokenSpelling(translationUnit, tokens.position(i)).getString());
}
Manager.getInstance().registerMacro(tokenizedName, value.toString());

// Libclang doesn't support define comment parsing
Manager.getInstance().registerMacro(new MacroType(tokenizedName, value.toString(), null));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package com.badlogic.gdx.jnigen.generator;

import com.badlogic.gdx.jnigen.generator.types.ClosureType;
import com.badlogic.gdx.jnigen.generator.types.EnumType;
import com.badlogic.gdx.jnigen.generator.types.FunctionType;
import com.badlogic.gdx.jnigen.generator.types.GlobalType;
import com.badlogic.gdx.jnigen.generator.types.StackElementType;
import com.badlogic.gdx.jnigen.generator.types.TypeDefinition;
import com.badlogic.gdx.jnigen.generator.types.*;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Modifier.Keyword;
Expand Down Expand Up @@ -58,7 +53,7 @@ public static void init(String parsedCHeader, String basePackage) {

private final Map<String, String> typedefs = new HashMap<>();

private final Map<String, String> macros = new HashMap<>();
private final Map<String, MacroType> macros = new HashMap<>();

private final GlobalType globalType;

Expand Down Expand Up @@ -128,12 +123,12 @@ public int getCTypeID(String name) {
return knownCTypes.indexOf(name);
}

public void registerMacro(String name, String value) {
if (macros.containsKey(name)) {
if (!macros.get(name).equals(value))
throw new IllegalArgumentException("Macro with name " + name + " already exists, but has different value. Old: " + macros.get(name) + " != New: " + value);
public void registerMacro(MacroType macroType) {
if (macros.containsKey(macroType.getName())) {
if (!macros.get(macroType.getName()).getValue().equals(macroType.getValue()))
throw new IllegalArgumentException("Macro with name " + macroType.getName() + " already exists, but has different value. Old: " + macros.get(macroType.getName()).getValue() + " != New: " + macroType.getValue());
}
macros.put(name, value);
macros.put(macroType.getName(), macroType);
}

public void registerCTypeMapping(String name, TypeDefinition javaRepresentation) {
Expand Down Expand Up @@ -255,52 +250,11 @@ public void emit(String basePath) {
// Macros
CompilationUnit constantsCU = new CompilationUnit(basePackage);
ClassOrInterfaceDeclaration constantsClass = constantsCU.addClass("Constants", Keyword.PUBLIC, Keyword.FINAL);
macros.keySet().stream().sorted().forEach(name -> {
String value = macros.get(name);

// TODO: 21.06.24 We need to find more reliable ways, maybe a fancy regex?
if (value.startsWith("(") && value.endsWith(")"))
value = value.substring(1, value.length() - 1);

for (int i = 0; i < 3; i++) {
if (value.isEmpty())
return;
char indexLowerCase = value.toLowerCase().charAt(value.length() - 1);
if (indexLowerCase == 'l' || indexLowerCase == 'u')
value = value.substring(0, value.length() - 1);
else
break;
}

if (SourceVersion.isKeyword(name))
name = name + "_r";
try {
long l = Long.decode(value);
Class<?> lowestBound;
if (l <= Byte.MAX_VALUE && l >= Byte.MIN_VALUE) {
lowestBound = byte.class;
} else if (l <= Short.MAX_VALUE && l >= Short.MIN_VALUE) {
lowestBound = short.class;
} else if (l <= Character.MAX_VALUE && l >= Character.MIN_VALUE) {
lowestBound = char.class;
} else if (l <= Integer.MAX_VALUE && l >= Integer.MIN_VALUE) {
lowestBound = int.class;
} else {
value += "L";
lowestBound = long.class;
}
constantsClass.addFieldWithInitializer(lowestBound, name, new IntegerLiteralExpr(value), Keyword.PUBLIC, Keyword.STATIC, Keyword.FINAL);
}catch (NumberFormatException ignored){
try {
if (value.endsWith("L") || value.endsWith("l"))
value = value.substring(0, value.length() - 1);
Double.parseDouble(value);
boolean isFloat = value.endsWith("f") || value.endsWith("F");
Class<?> lowestBound = isFloat ? float.class : double.class;
constantsClass.addFieldWithInitializer(lowestBound, name, new DoubleLiteralExpr(value), Keyword.PUBLIC, Keyword.STATIC, Keyword.FINAL);
} catch (NumberFormatException ignored1){}
}
});

macros.entrySet().stream()
.sorted(Entry.comparingByValue(Comparator.comparing(MacroType::getName)))
.forEach(macroType -> macroType.getValue().write(constantsCU, constantsClass));

Files.write(Paths.get(basePath + basePackage.replace(".", "/") + "/Constants.java"), constantsCU.toString().getBytes(StandardCharsets.UTF_8));


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.badlogic.gdx.jnigen.generator.types;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.expr.DoubleLiteralExpr;
import com.github.javaparser.ast.expr.IntegerLiteralExpr;

import javax.lang.model.SourceVersion;

public class MacroType {

private final String name;
private final String value;
private final String comment;

public MacroType(String name, String value, String comment) {
this.name = name;
this.value = value;
this.comment = comment;
}

public void write(CompilationUnit cu, ClassOrInterfaceDeclaration wrappingClass) {
String processedValue = value;
String processedName = name;
// TODO: 21.06.24 We need to find more reliable ways, maybe a fancy regex?
if (processedValue.startsWith("(") && processedValue.endsWith(")"))
processedValue = processedValue.substring(1, processedValue.length() - 1);

for (int i = 0; i < 3; i++) {
if (processedValue.isEmpty())
return;
char indexLowerCase = processedValue.toLowerCase().charAt(processedValue.length() - 1);
if (indexLowerCase == 'l' || indexLowerCase == 'u')
processedValue = processedValue.substring(0, processedValue.length() - 1);
else
break;
}

if (SourceVersion.isKeyword(processedName))
processedName = processedName + "_r";
FieldDeclaration declaration = null;
try {
long l = Long.decode(processedValue);
Class<?> lowestBound;
if (l <= Byte.MAX_VALUE && l >= Byte.MIN_VALUE) {
lowestBound = byte.class;
} else if (l <= Short.MAX_VALUE && l >= Short.MIN_VALUE) {
lowestBound = short.class;
} else if (l <= Character.MAX_VALUE && l >= Character.MIN_VALUE) {
lowestBound = char.class;
} else if (l <= Integer.MAX_VALUE && l >= Integer.MIN_VALUE) {
lowestBound = int.class;
} else {
processedValue += "L";
lowestBound = long.class;
}
declaration = wrappingClass.addFieldWithInitializer(lowestBound, processedName, new IntegerLiteralExpr(processedValue), Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC, Modifier.Keyword.FINAL);
}catch (NumberFormatException ignored){
try {
if (processedValue.endsWith("L") || processedValue.endsWith("l"))
processedValue = processedValue.substring(0, processedValue.length() - 1);
Double.parseDouble(processedValue);
boolean isFloat = processedValue.endsWith("f") || processedValue.endsWith("F");
Class<?> lowestBound = isFloat ? float.class : double.class;
declaration = wrappingClass.addFieldWithInitializer(lowestBound, processedName, new DoubleLiteralExpr(processedValue), Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC, Modifier.Keyword.FINAL);
} catch (NumberFormatException ignored1){}
}

if (declaration != null && comment != null)
declaration.setJavadocComment(comment);
}

public String getName() {
return name;
}

public String getValue() {
return value;
}

public String getComment() {
return comment;
}
}
1 change: 1 addition & 0 deletions gdx-jnigen-generator-test/src/test/resources/test_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern "C" {
#endif

#define UNSIGNED_INT 10
/// This has a comment
#define SIGNED_INT -10
#define UNSIGNED_DOUBLE 10.5
#define SIGNED_DOUBLE -10.5
Expand Down

0 comments on commit 0a28eb1

Please sign in to comment.