Skip to content

Commit 4c942c4

Browse files
authored
Merge pull request #20 from DigitalSmile/fix-return-types
Fix return types
2 parents c00f722 + f579eb0 commit 4c942c4

File tree

13 files changed

+93
-33
lines changed

13 files changed

+93
-33
lines changed

.github/workflows/gradle.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ jobs:
4242
cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git
4343
- name: Getting linux header version for tests
4444
run: |
45-
echo "headerVersion=$(uname -r)" >> "$GITHUB_ENV"
45+
echo "linuxVersion=$(uname -r)" >> "$GITHUB_ENV" && echo "gccVersion=12" >> "$GITHUB_ENV"
4646
- name: Change wrapper permissions
4747
run: chmod +x ./gradlew
4848
- name: Build Gradle
4949
run: |
50-
./gradlew build -Dversion=$headerVersion
50+
./gradlew build -Dlinux-version=$linuxVersion -Dgcc-version=$gccVersion
+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
systemProp.version=6.2.0-39
1+
systemProp.linux-version=6.8.0-52-generic
2+
systemProp.gcc-version=11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.github.digitalsmile.gpio.functions;
2+
3+
import io.github.digitalsmile.annotation.NativeMemoryException;
4+
import org.junit.jupiter.api.Test;
5+
6+
public class LibcFunctionTests {
7+
8+
@Test
9+
public void testOpenRead() throws NativeMemoryException {
10+
var file = new LibcFunctionsNative();
11+
var osRelease = file.open("/etc/os-release", 0);
12+
var buffer = file.read(osRelease, new byte[1024], 1024);
13+
System.out.println(new String(buffer));
14+
file.close();
15+
}
16+
}

annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/FunctionTest.java renamed to annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctions.java

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
package io.github.digitalsmile.gpio.functions;
22

3-
import io.github.digitalsmile.annotation.NativeMemory;
43
import io.github.digitalsmile.annotation.function.*;
54
import io.github.digitalsmile.annotation.NativeMemoryException;
6-
import io.github.digitalsmile.annotation.library.NativeFunction;
7-
import io.github.digitalsmile.annotation.library.NativeMemoryLibrary;
85
import io.github.digitalsmile.annotation.types.interfaces.NativeMemoryLayout;
96

10-
import java.util.List;
11-
12-
public interface FunctionTest {
7+
public interface LibcFunctions {
138
@NativeManualFunction(name = "ioctl", useErrno = true)
149
int callByValue(int fd, long command, long data) throws NativeMemoryException;
1510

@@ -28,7 +23,7 @@ public interface FunctionTest {
2823
@NativeManualFunction(name = "close")
2924
void close(int fd) throws NativeMemoryException;
3025

31-
@NativeManualFunction(name = "read", useErrno = true)
26+
@NativeManualFunction(name = "read", useErrno = true, nativeReturnType = int.class)
3227
byte[] read(int fd, @Returns @ByAddress byte[] buffer, int size) throws NativeMemoryException;
3328

3429
@NativeManualFunction(name = "write", useErrno = true)

annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libcurl/Libcurl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
@NativeMemory(headers = "libcurl/curl/include/curl/curl.h")
1919
@NativeMemoryOptions(systemIncludes = {
20-
"/usr/lib/gcc/x86_64-linux-gnu/12/include/"
20+
"/usr/lib/gcc/x86_64-linux-gnu/${gcc-version}/include/"
2121
}, debugMode = true, processRootConstants = true)
2222
@Structs({
2323
@Struct(name = "CURL", javaName = "CurlInstance")

annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libvlc/LibVLC.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
@NativeMemory(headers = "libvlc/vlc/include/vlc/vlc.h")
1717
@NativeMemoryOptions(
1818
includes = "libvlc/vlc/include",
19-
systemIncludes = "/usr/lib/gcc/x86_64-linux-gnu/12/include/",
19+
systemIncludes = "/usr/lib/gcc/x86_64-linux-gnu/${gcc-version}/include/",
2020
debugMode = true
2121
)
2222
@Structs

annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/all/GPIOTypesAll.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import io.github.digitalsmile.annotation.structure.Structs;
77
import io.github.digitalsmile.annotation.structure.Unions;
88

9-
@NativeMemory(headers = "/usr/src/linux-headers-${version}/include/uapi/linux/gpio.h")
9+
@NativeMemory(headers = "/usr/src/linux-headers-${linux-version}/include/uapi/linux/gpio.h")
1010
@NativeMemoryOptions(
1111
processRootConstants = true
1212
)

annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/custom/GPIOTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import io.github.digitalsmile.annotation.structure.Structs;
88
import io.github.digitalsmile.annotation.structure.Unions;
99

10-
@NativeMemory(headers = "/usr/src/linux-headers-${version}/include/uapi/linux/gpio.h")
10+
@NativeMemory(headers = "/usr/src/linux-headers-${linux-version}/include/uapi/linux/gpio.h")
1111
@NativeMemoryOptions(
1212
processRootConstants = true
1313
)

annotation-processor/src/main/java/io/github/digitalsmile/NativeProcessor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ private void processFunctions(Element rootElement, List<Element> functionElement
298298
var parameterNode = new ParameterNode(variableName, node, returns != null, byAddress);
299299
parameters.add(parameterNode);
300300
}
301-
var functionOptions = new FunctionOptions(instance.name(), instance.isAlreadyLoaded(), instance.useErrno());
301+
var functionOptions = new FunctionOptions(instance.name(), instance.isAlreadyLoaded(), instance.useErrno(), OriginalType.of(instance.nativeReturnType()));
302302
var functionNode = new FunctionNode(functionElement.getSimpleName().toString(), functionOptions, returnNode, parameters, functionElement.getTypeParameters());
303303
nodes.add(functionNode);
304304
var libraryFileName = instance.library();
@@ -398,7 +398,7 @@ private List<Path> getHeaderPaths(String... headerFiles) throws ValidationExcept
398398
}
399399

400400
private File calculatePath(File directory) {
401-
if (directory.isDirectory() && directory.getName().equals("build")) {
401+
if (directory.isDirectory() && (directory.getName().equals("build") || directory.getName().equals("target"))) {
402402
return directory.getParentFile();
403403
}
404404
return calculatePath(directory.getParentFile());

annotation-processor/src/main/java/io/github/digitalsmile/composers/ContextComposer.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public String compose(String packageName, String javaName, Map<Library, List<Fun
6868
var options = functionNode.functionOptions();
6969
var returnNode = functionNode.returnNode();
7070
var returnType = returnNode.getType();
71-
if (!returnType.carrierClass().equals(void.class)) {
72-
switch (returnType) {
71+
if (options.nativeReturnType().carrierClass() != Void.class) {
72+
switch (options.nativeReturnType()) {
7373
case PrimitiveOriginalType primitiveTypeMapping ->
7474
parameters.add(CodeBlock.builder().add("$T.$L", ValueLayout.class, primitiveTypeMapping.valueLayoutName()).build());
7575
case ObjectOriginalType _, ArrayOriginalType _ -> {
@@ -81,6 +81,21 @@ public String compose(String packageName, String javaName, Map<Library, List<Fun
8181
}
8282
default -> throw new IllegalStateException("Unexpected value: " + returnType);
8383
}
84+
} else {
85+
if (!returnType.carrierClass().equals(void.class)) {
86+
switch (returnType) {
87+
case PrimitiveOriginalType primitiveTypeMapping ->
88+
parameters.add(CodeBlock.builder().add("$T.$L", ValueLayout.class, primitiveTypeMapping.valueLayoutName()).build());
89+
case ObjectOriginalType _, ArrayOriginalType _ -> {
90+
if (returnNode.getNodeType().isEnum()) {
91+
parameters.add(CodeBlock.builder().add("$T.JAVA_INT", ValueLayout.class).build());
92+
} else {
93+
parameters.add(CodeBlock.builder().add("$T.ADDRESS", ValueLayout.class).build());
94+
}
95+
}
96+
default -> throw new IllegalStateException("Unexpected value: " + returnType);
97+
}
98+
}
8499
}
85100
for (ParameterNode parameterNode : functionNode.functionParameters()) {
86101
var node = parameterNode.nativeMemoryNode();

annotation-processor/src/main/java/io/github/digitalsmile/composers/FunctionComposer.java

+38-14
Original file line numberDiff line numberDiff line change
@@ -116,26 +116,50 @@ public String compose(String packageName, String originalName, List<FunctionNode
116116
}
117117
}
118118

119-
if (options.useErrno()) {
120-
methodBody.addStatement("var capturedState = context.allocate(CAPTURED_STATE_LAYOUT)");
121-
methodBody.addStatement("var callResult = (int) $T.$L.invoke(capturedState, $L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
122-
methodBody.addStatement("processError(callResult, capturedState, $S, $L)", functionNode.functionName(), CodeBlock.join(arguments, ", "));
119+
if (options.nativeReturnType().carrierClass() == Void.class) {
120+
if (options.useErrno()) {
121+
methodBody.addStatement("var capturedState = context.allocate(CAPTURED_STATE_LAYOUT)");
122+
methodBody.addStatement("var callResult = (int) $T.$L.invoke(capturedState, $L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
123+
methodBody.addStatement("processError(callResult, capturedState, $S, $L)", functionNode.functionName(), CodeBlock.join(arguments, ", "));
124+
} else {
125+
if (returnType.carrierClass().equals(void.class)) {
126+
methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
127+
} else {
128+
switch (returnType) {
129+
case ArrayOriginalType _, ObjectOriginalType _ ->
130+
methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
131+
functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class,
132+
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
133+
default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
134+
returnType.carrierClass(),
135+
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
136+
}
137+
}
138+
}
123139
} else {
124-
if (returnType.carrierClass().equals(void.class)) {
125-
methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
140+
if (options.useErrno()) {
141+
methodBody.addStatement("var capturedState = context.allocate(CAPTURED_STATE_LAYOUT)");
142+
methodBody.addStatement("var callResult = ($T) $T.$L.invoke(capturedState, $L)", options.nativeReturnType().carrierClass(), context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
143+
methodBody.addStatement("processError(callResult, capturedState, $S, $L)", functionNode.functionName(), CodeBlock.join(arguments, ", "));
126144
} else {
127-
switch (returnType) {
128-
case ArrayOriginalType _, ObjectOriginalType _ ->
129-
methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
130-
functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class,
131-
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
132-
default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
133-
returnType.carrierClass(),
134-
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
145+
if (returnType.carrierClass().equals(void.class)) {
146+
methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
147+
} else {
148+
switch (returnType) {
149+
case ArrayOriginalType _, ObjectOriginalType _ ->
150+
methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
151+
functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class,
152+
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
153+
default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
154+
returnType.carrierClass(),
155+
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
156+
}
135157
}
136158
}
137159
}
138160

161+
162+
139163
if (!returnType.carrierClass().equals(void.class) && functionNode.functionParameters().stream().noneMatch(ParameterNode::returns)) {
140164
if (returnType instanceof ObjectOriginalType) {
141165
if (returnType.carrierClass().equals(String.class)) {
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
package io.github.digitalsmile.functions;
22

3-
public record FunctionOptions(String nativeFunctionName, boolean isAlreadyLoaded, boolean useErrno) {
3+
import io.github.digitalsmile.headers.mapping.OriginalType;
4+
5+
public record FunctionOptions(String nativeFunctionName, boolean isAlreadyLoaded, boolean useErrno, OriginalType nativeReturnType) {
46
}

annotation/src/main/java/io/github/digitalsmile/annotation/function/NativeManualFunction.java

+7
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,11 @@
8989
* @return true if use errno/strerr
9090
*/
9191
boolean useErrno() default false;
92+
93+
/**
94+
* Native return type, as described in function docs.
95+
*
96+
* @return native function return type
97+
*/
98+
Class<?> nativeReturnType() default Void.class;
9299
}

0 commit comments

Comments
 (0)