Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/graal-ffm' into stty
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/org/fusesource/jansi/internal/AnsiConsoleSupportHolder.java
  • Loading branch information
Glavo committed Oct 4, 2023
2 parents fd6ed41 + 6e3d465 commit 6bcc1a0
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

import org.fusesource.jansi.io.AnsiProcessor;

public interface AnsiConsoleSupport {
public abstract class AnsiConsoleSupport {

interface CLibrary {
public interface CLibrary {

int STDOUT_FILENO = 1;
int STDERR_FILENO = 2;
Expand All @@ -32,7 +32,7 @@ interface CLibrary {
int isTty(int fd);
}

interface Kernel32 {
public interface Kernel32 {

int isTty(long console);

Expand All @@ -51,9 +51,39 @@ interface Kernel32 {
AnsiProcessor newProcessor(OutputStream os, long console) throws IOException;
}

String getProviderName();
private final String providerName;
private CLibrary cLibrary;
private Kernel32 kernel32;

CLibrary getCLibrary();
protected AnsiConsoleSupport(String providerName) {
this.providerName = providerName;
}

public final String getProviderName() {
return providerName;
}

protected abstract CLibrary createCLibrary();

protected abstract Kernel32 createKernel32();

public final CLibrary getCLibrary() {
if (cLibrary == null) {
cLibrary = createCLibrary();
}

Kernel32 getKernel32();
return cLibrary;
}

public final Kernel32 getKernel32() {
if (kernel32 == null) {
if (!OSInfo.isWindows()) {
throw new RuntimeException("Kernel32 is not available on this platform");
}

kernel32 = createKernel32();
}

return kernel32;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,54 +86,22 @@ private static AnsiConsoleSupport findProvider(String providerList) {
ERR = err;
}

public static String getProviderName() {
return PROVIDER.getProviderName();
public static AnsiConsoleSupport getProvider() {
if (PROVIDER == null) {
throw new RuntimeException("No provider available", ERR);
}
return PROVIDER;
}

private static final class LibraryHolder {
static final AnsiConsoleSupport.CLibrary CLIBRARY;
static final AnsiConsoleSupport.Kernel32 KERNEL32;
static final Throwable ERR;

static {
AnsiConsoleSupport.CLibrary clib = null;
AnsiConsoleSupport.Kernel32 kernel32 = null;
Throwable err = null;

if (PROVIDER != null) {
try {
clib = PROVIDER.getCLibrary();
kernel32 = OSInfo.isWindows() ? PROVIDER.getKernel32() : null;
} catch (Throwable e) {
err = e;
}
} else {
err = AnsiConsoleSupportHolder.ERR;
}

CLIBRARY = clib;
KERNEL32 = kernel32;
ERR = err;
}
public static String getProviderName() {
return getProvider().getProviderName();
}

public static AnsiConsoleSupport.CLibrary getCLibrary() {
if (LibraryHolder.CLIBRARY == null) {
throw new RuntimeException("Unable to get the instance of CLibrary", LibraryHolder.ERR);
}

return LibraryHolder.CLIBRARY;
return getProvider().getCLibrary();
}

public static AnsiConsoleSupport.Kernel32 getKernel32() {
if (LibraryHolder.KERNEL32 == null) {
if (OSInfo.isWindows()) {
throw new RuntimeException("Unable to get the instance of Kernel32", LibraryHolder.ERR);
} else {
throw new UnsupportedOperationException("Not Windows");
}
}

return LibraryHolder.KERNEL32;
return getProvider().getKernel32();
}
}
29 changes: 15 additions & 14 deletions src/main/java/org/fusesource/jansi/internal/NativeImageFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.fusesource.jansi.internal;

import java.util.Objects;

import org.fusesource.jansi.AnsiConsole;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeClassInitialization;
Expand All @@ -28,6 +30,8 @@ public String getURL() {

@Override
public void duringSetup(DuringSetupAccess access) {
RuntimeClassInitialization.initializeAtBuildTime(AnsiConsoleSupportHolder.class);

String providers = System.getProperty(AnsiConsole.JANSI_PROVIDERS);
if (providers != null) {
try {
Expand All @@ -38,18 +42,8 @@ public void duringSetup(DuringSetupAccess access) {
}
}

if (providers != null && providers.contains(AnsiConsole.JANSI_PROVIDER_FFM)) {
try {
// FFM is only available in JDK 21+, so we need to compile it separately
Class.forName("org.fusesource.jansi.internal.ffm.NativeImageDowncallRegister")
.getMethod("registerForDowncall")
.invoke(null);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}

if (providers == null || providers.contains(AnsiConsole.JANSI_PROVIDER_JNI)) {
String provider = Objects.requireNonNull(AnsiConsoleSupportHolder.getProviderName(), "No provider available");
if (provider.equals(AnsiConsole.JANSI_PROVIDER_JNI)) {
String jansiNativeLibraryName = System.mapLibraryName("jansi");
if (jansiNativeLibraryName.endsWith(".dylib")) {
jansiNativeLibraryName = jansiNativeLibraryName.replace(".dylib", ".jnilib");
Expand All @@ -76,8 +70,15 @@ public void duringSetup(DuringSetupAccess access) {
// GraalVM version < 22.3
// Users need to manually add the JNI library as resources
}
} else if (provider.equals(AnsiConsole.JANSI_PROVIDER_FFM)) {
try {
// FFM is only available in JDK 21+, so we need to compile it separately
Class.forName("org.fusesource.jansi.internal.ffm.NativeImageDowncallRegister")
.getMethod("registerForDowncall")
.invoke(null);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}

RuntimeClassInitialization.initializeAtBuildTime(AnsiConsoleSupportHolder.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,22 @@

import static org.fusesource.jansi.internal.ffm.Kernel32.*;

public final class AnsiConsoleSupportImpl implements AnsiConsoleSupport {
public final class AnsiConsoleSupportImpl extends AnsiConsoleSupport {

public AnsiConsoleSupportImpl() {}
public AnsiConsoleSupportImpl() {
super("ffm");
}

public AnsiConsoleSupportImpl(boolean checkNativeAccess) {
this();
if (checkNativeAccess && !AnsiConsoleSupportImpl.class.getModule().isNativeAccessEnabled()) {
throw new UnsupportedOperationException(
"Native access is not enabled for the current module: " + AnsiConsoleSupportImpl.class.getModule());
}
}

@Override
public String getProviderName() {
return "ffm";
}

@Override
public CLibrary getCLibrary() {
protected CLibrary createCLibrary() {
if (OSInfo.isWindows()) {
return new WindowsCLibrary();
} else {
Expand All @@ -53,7 +51,7 @@ public CLibrary getCLibrary() {
}

@Override
public Kernel32 getKernel32() {
protected Kernel32 createKernel32() {
return new Kernel32() {
@Override
public int isTty(long console) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@
import static org.fusesource.jansi.internal.Kernel32.STD_OUTPUT_HANDLE;
import static org.fusesource.jansi.internal.Kernel32.SetConsoleMode;

public final class AnsiConsoleSupportImpl implements AnsiConsoleSupport {
public final class AnsiConsoleSupportImpl extends AnsiConsoleSupport {

@Override
public String getProviderName() {
return "jni";
public AnsiConsoleSupportImpl() {
super("jni");
}

@Override
public CLibrary getCLibrary() {
protected CLibrary createCLibrary() {
return new CLibrary() {
@Override
public short getTerminalWidth(int fd) {
Expand All @@ -56,7 +55,7 @@ public int isTty(int fd) {
}

@Override
public Kernel32 getKernel32() {
protected Kernel32 createKernel32() {
return new Kernel32() {
@Override
public int isTty(long console) {
Expand Down

0 comments on commit 6bcc1a0

Please sign in to comment.