Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ jobs:
cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git
- name: Getting linux header version for tests
run: |
echo "headerVersion=$(uname -r)" >> "$GITHUB_ENV"
echo "linuxVersion=$(uname -r)" >> "$GITHUB_ENV" && echo "gccVersion=12" >> "$GITHUB_ENV"
- name: Change wrapper permissions
run: chmod +x ./gradlew
- name: Build Gradle
run: |
./gradlew build -Dversion=$headerVersion
./gradlew build -Dlinux-version=$linuxVersion -Dgcc-version=$gccVersion
3 changes: 2 additions & 1 deletion annotation-processor-test/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
systemProp.version=6.2.0-39
systemProp.linux-version=6.8.0-52-generic
systemProp.gcc-version=11
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.github.digitalsmile.gpio.functions;

import io.github.digitalsmile.annotation.NativeMemoryException;
import org.junit.jupiter.api.Test;

public class LibcFunctionTests {

@Test
public void testOpenRead() throws NativeMemoryException {
var file = new LibcFunctionsNative();
var osRelease = file.open("/etc/os-release", 0);
var buffer = file.read(osRelease, new byte[1024], 1024);
System.out.println(new String(buffer));
file.close();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package io.github.digitalsmile.gpio.functions;

import io.github.digitalsmile.annotation.NativeMemory;
import io.github.digitalsmile.annotation.function.*;
import io.github.digitalsmile.annotation.NativeMemoryException;
import io.github.digitalsmile.annotation.library.NativeFunction;
import io.github.digitalsmile.annotation.library.NativeMemoryLibrary;
import io.github.digitalsmile.annotation.types.interfaces.NativeMemoryLayout;

import java.util.List;

public interface FunctionTest {
public interface LibcFunctions {
@NativeManualFunction(name = "ioctl", useErrno = true)
int callByValue(int fd, long command, long data) throws NativeMemoryException;

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

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

@NativeManualFunction(name = "write", useErrno = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

@NativeMemory(headers = "libcurl/curl/include/curl/curl.h")
@NativeMemoryOptions(systemIncludes = {
"/usr/lib/gcc/x86_64-linux-gnu/12/include/"
"/usr/lib/gcc/x86_64-linux-gnu/${gcc-version}/include/"
}, debugMode = true, processRootConstants = true)
@Structs({
@Struct(name = "CURL", javaName = "CurlInstance")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@NativeMemory(headers = "libvlc/vlc/include/vlc/vlc.h")
@NativeMemoryOptions(
includes = "libvlc/vlc/include",
systemIncludes = "/usr/lib/gcc/x86_64-linux-gnu/12/include/",
systemIncludes = "/usr/lib/gcc/x86_64-linux-gnu/${gcc-version}/include/",
debugMode = true
)
@Structs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import io.github.digitalsmile.annotation.structure.Structs;
import io.github.digitalsmile.annotation.structure.Unions;

@NativeMemory(headers = "/usr/src/linux-headers-${version}/include/uapi/linux/gpio.h")
@NativeMemory(headers = "/usr/src/linux-headers-${linux-version}/include/uapi/linux/gpio.h")
@NativeMemoryOptions(
processRootConstants = true
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import io.github.digitalsmile.annotation.structure.Structs;
import io.github.digitalsmile.annotation.structure.Unions;

@NativeMemory(headers = "/usr/src/linux-headers-${version}/include/uapi/linux/gpio.h")
@NativeMemory(headers = "/usr/src/linux-headers-${linux-version}/include/uapi/linux/gpio.h")
@NativeMemoryOptions(
processRootConstants = true
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ private void processFunctions(Element rootElement, List<Element> functionElement
var parameterNode = new ParameterNode(variableName, node, returns != null, byAddress);
parameters.add(parameterNode);
}
var functionOptions = new FunctionOptions(instance.name(), instance.isAlreadyLoaded(), instance.useErrno());
var functionOptions = new FunctionOptions(instance.name(), instance.isAlreadyLoaded(), instance.useErrno(), OriginalType.of(instance.nativeReturnType()));
var functionNode = new FunctionNode(functionElement.getSimpleName().toString(), functionOptions, returnNode, parameters, functionElement.getTypeParameters());
nodes.add(functionNode);
var libraryFileName = instance.library();
Expand Down Expand Up @@ -398,7 +398,7 @@ private List<Path> getHeaderPaths(String... headerFiles) throws ValidationExcept
}

private File calculatePath(File directory) {
if (directory.isDirectory() && directory.getName().equals("build")) {
if (directory.isDirectory() && (directory.getName().equals("build") || directory.getName().equals("target"))) {
return directory.getParentFile();
}
return calculatePath(directory.getParentFile());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ public String compose(String packageName, String javaName, Map<Library, List<Fun
var options = functionNode.functionOptions();
var returnNode = functionNode.returnNode();
var returnType = returnNode.getType();
if (!returnType.carrierClass().equals(void.class)) {
switch (returnType) {
if (options.nativeReturnType().carrierClass() != Void.class) {
switch (options.nativeReturnType()) {
case PrimitiveOriginalType primitiveTypeMapping ->
parameters.add(CodeBlock.builder().add("$T.$L", ValueLayout.class, primitiveTypeMapping.valueLayoutName()).build());
case ObjectOriginalType _, ArrayOriginalType _ -> {
Expand All @@ -81,6 +81,21 @@ public String compose(String packageName, String javaName, Map<Library, List<Fun
}
default -> throw new IllegalStateException("Unexpected value: " + returnType);
}
} else {
if (!returnType.carrierClass().equals(void.class)) {
switch (returnType) {
case PrimitiveOriginalType primitiveTypeMapping ->
parameters.add(CodeBlock.builder().add("$T.$L", ValueLayout.class, primitiveTypeMapping.valueLayoutName()).build());
case ObjectOriginalType _, ArrayOriginalType _ -> {
if (returnNode.getNodeType().isEnum()) {
parameters.add(CodeBlock.builder().add("$T.JAVA_INT", ValueLayout.class).build());
} else {
parameters.add(CodeBlock.builder().add("$T.ADDRESS", ValueLayout.class).build());
}
}
default -> throw new IllegalStateException("Unexpected value: " + returnType);
}
}
}
for (ParameterNode parameterNode : functionNode.functionParameters()) {
var node = parameterNode.nativeMemoryNode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,26 +116,50 @@ public String compose(String packageName, String originalName, List<FunctionNode
}
}

if (options.useErrno()) {
methodBody.addStatement("var capturedState = context.allocate(CAPTURED_STATE_LAYOUT)");
methodBody.addStatement("var callResult = (int) $T.$L.invoke(capturedState, $L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
methodBody.addStatement("processError(callResult, capturedState, $S, $L)", functionNode.functionName(), CodeBlock.join(arguments, ", "));
if (options.nativeReturnType().carrierClass() == Void.class) {
if (options.useErrno()) {
methodBody.addStatement("var capturedState = context.allocate(CAPTURED_STATE_LAYOUT)");
methodBody.addStatement("var callResult = (int) $T.$L.invoke(capturedState, $L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
methodBody.addStatement("processError(callResult, capturedState, $S, $L)", functionNode.functionName(), CodeBlock.join(arguments, ", "));
} else {
if (returnType.carrierClass().equals(void.class)) {
methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
} else {
switch (returnType) {
case ArrayOriginalType _, ObjectOriginalType _ ->
methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class,
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
returnType.carrierClass(),
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
}
}
}
} else {
if (returnType.carrierClass().equals(void.class)) {
methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
if (options.useErrno()) {
methodBody.addStatement("var capturedState = context.allocate(CAPTURED_STATE_LAYOUT)");
methodBody.addStatement("var callResult = ($T) $T.$L.invoke(capturedState, $L)", options.nativeReturnType().carrierClass(), context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
methodBody.addStatement("processError(callResult, capturedState, $S, $L)", functionNode.functionName(), CodeBlock.join(arguments, ", "));
} else {
switch (returnType) {
case ArrayOriginalType _, ObjectOriginalType _ ->
methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class,
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
returnType.carrierClass(),
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
if (returnType.carrierClass().equals(void.class)) {
methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
} else {
switch (returnType) {
case ArrayOriginalType _, ObjectOriginalType _ ->
methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class,
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)",
returnType.carrierClass(),
context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", "));
}
}
}
}



if (!returnType.carrierClass().equals(void.class) && functionNode.functionParameters().stream().noneMatch(ParameterNode::returns)) {
if (returnType instanceof ObjectOriginalType) {
if (returnType.carrierClass().equals(String.class)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package io.github.digitalsmile.functions;

public record FunctionOptions(String nativeFunctionName, boolean isAlreadyLoaded, boolean useErrno) {
import io.github.digitalsmile.headers.mapping.OriginalType;

public record FunctionOptions(String nativeFunctionName, boolean isAlreadyLoaded, boolean useErrno, OriginalType nativeReturnType) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,11 @@
* @return true if use errno/strerr
*/
boolean useErrno() default false;

/**
* Native return type, as described in function docs.
*
* @return native function return type
*/
Class<?> nativeReturnType() default Void.class;
}
Loading