org.pkl.thirdparty.jline.terminal.impl.ExecPty Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pkl-tools Show documentation
Show all versions of pkl-tools Show documentation
Fat Jar containing pkl-cli, pkl-codegen-java, pkl-codegen-kotlin, pkl-config-java, pkl-core, pkl-doc, and their shaded third-party dependencies.
/*
* Copyright (c) 2002-2016, the original author(s).
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* https://opensource.org/licenses/BSD-3-Clause
*/
package org.pkl.thirdparty.jline.terminal.impl;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.pkl.thirdparty.jline.terminal.Attributes;
import org.pkl.thirdparty.jline.terminal.Attributes.ControlChar;
import org.pkl.thirdparty.jline.terminal.Attributes.ControlFlag;
import org.pkl.thirdparty.jline.terminal.Attributes.InputFlag;
import org.pkl.thirdparty.jline.terminal.Attributes.LocalFlag;
import org.pkl.thirdparty.jline.terminal.Attributes.OutputFlag;
import org.pkl.thirdparty.jline.terminal.Size;
import org.pkl.thirdparty.jline.terminal.spi.Pty;
import org.pkl.thirdparty.jline.terminal.spi.TerminalProvider;
import org.pkl.thirdparty.jline.utils.OSUtils;
import static org.pkl.thirdparty.jline.utils.ExecHelper.exec;
public class ExecPty extends AbstractPty implements Pty {
private final String name;
private final TerminalProvider.Stream console;
public static Pty current(TerminalProvider.Stream console) throws IOException {
try {
String result = exec(true, OSUtils.TTY_COMMAND);
if (console != TerminalProvider.Stream.Output && console != TerminalProvider.Stream.Error) {
throw new IllegalArgumentException("console should be Output or Error: " + console);
}
return new ExecPty(result.trim(), console);
} catch (IOException e) {
throw new IOException("Not a tty", e);
}
}
protected ExecPty(String name, TerminalProvider.Stream console) {
this.name = name;
this.console = console;
}
@Override
public void close() throws IOException {}
public String getName() {
return name;
}
@Override
public InputStream getMasterInput() {
throw new UnsupportedOperationException();
}
@Override
public OutputStream getMasterOutput() {
throw new UnsupportedOperationException();
}
@Override
protected InputStream doGetSlaveInput() throws IOException {
return console != null ? new FileInputStream(FileDescriptor.in) : new FileInputStream(getName());
}
@Override
public OutputStream getSlaveOutput() throws IOException {
return console == TerminalProvider.Stream.Output
? new FileOutputStream(FileDescriptor.out)
: console == TerminalProvider.Stream.Error
? new FileOutputStream(FileDescriptor.err)
: new FileOutputStream(getName());
}
@Override
public Attributes getAttr() throws IOException {
String cfg = doGetConfig();
return doGetAttr(cfg);
}
@Override
protected void doSetAttr(Attributes attr) throws IOException {
List commands = getFlagsToSet(attr, getAttr());
if (!commands.isEmpty()) {
commands.add(0, OSUtils.STTY_COMMAND);
if (console == null) {
commands.add(1, OSUtils.STTY_F_OPTION);
commands.add(2, getName());
}
exec(console != null, commands.toArray(new String[0]));
}
}
protected List getFlagsToSet(Attributes attr, Attributes current) {
List commands = new ArrayList<>();
for (InputFlag flag : InputFlag.values()) {
if (attr.getInputFlag(flag) != current.getInputFlag(flag)) {
commands.add((attr.getInputFlag(flag) ? flag.name() : "-" + flag.name()).toLowerCase());
}
}
for (OutputFlag flag : OutputFlag.values()) {
if (attr.getOutputFlag(flag) != current.getOutputFlag(flag)) {
commands.add((attr.getOutputFlag(flag) ? flag.name() : "-" + flag.name()).toLowerCase());
}
}
for (ControlFlag flag : ControlFlag.values()) {
if (attr.getControlFlag(flag) != current.getControlFlag(flag)) {
commands.add((attr.getControlFlag(flag) ? flag.name() : "-" + flag.name()).toLowerCase());
}
}
for (LocalFlag flag : LocalFlag.values()) {
if (attr.getLocalFlag(flag) != current.getLocalFlag(flag)) {
commands.add((attr.getLocalFlag(flag) ? flag.name() : "-" + flag.name()).toLowerCase());
}
}
String undef = System.getProperty("os.name").toLowerCase().startsWith("hp") ? "^-" : "undef";
for (ControlChar cchar : ControlChar.values()) {
int v = attr.getControlChar(cchar);
if (v >= 0 && v != current.getControlChar(cchar)) {
String str = "";
commands.add(cchar.name().toLowerCase().substring(1));
if (cchar == ControlChar.VMIN || cchar == ControlChar.VTIME) {
commands.add(Integer.toString(v));
} else if (v == 0) {
commands.add(undef);
} else {
if (v >= 128) {
v -= 128;
str += "M-";
}
if (v < 32 || v == 127) {
v ^= 0x40;
str += "^";
}
str += (char) v;
commands.add(str);
}
}
}
return commands;
}
@Override
public Size getSize() throws IOException {
String cfg = doGetConfig();
return doGetSize(cfg);
}
protected String doGetConfig() throws IOException {
return console != null
? exec(true, OSUtils.STTY_COMMAND, "-a")
: exec(false, OSUtils.STTY_COMMAND, OSUtils.STTY_F_OPTION, getName(), "-a");
}
static Attributes doGetAttr(String cfg) throws IOException {
Attributes attributes = new Attributes();
for (InputFlag flag : InputFlag.values()) {
Boolean value = doGetFlag(cfg, flag);
if (value != null) {
attributes.setInputFlag(flag, value);
}
}
for (OutputFlag flag : OutputFlag.values()) {
Boolean value = doGetFlag(cfg, flag);
if (value != null) {
attributes.setOutputFlag(flag, value);
}
}
for (ControlFlag flag : ControlFlag.values()) {
Boolean value = doGetFlag(cfg, flag);
if (value != null) {
attributes.setControlFlag(flag, value);
}
}
for (LocalFlag flag : LocalFlag.values()) {
Boolean value = doGetFlag(cfg, flag);
if (value != null) {
attributes.setLocalFlag(flag, value);
}
}
for (ControlChar cchar : ControlChar.values()) {
String name = cchar.name().toLowerCase().substring(1);
if ("reprint".endsWith(name)) {
name = "(?:reprint|rprnt)";
}
Matcher matcher =
Pattern.compile("[\\s;]" + name + "\\s*=\\s*(.+?)[\\s;]").matcher(cfg);
if (matcher.find()) {
attributes.setControlChar(
cchar, parseControlChar(matcher.group(1).toUpperCase()));
}
}
return attributes;
}
private static Boolean doGetFlag(String cfg, Enum> flag) {
Matcher matcher = Pattern.compile("(?:^|[\\s;])(\\-?" + flag.name().toLowerCase() + ")(?:[\\s;]|$)")
.matcher(cfg);
return matcher.find() ? !matcher.group(1).startsWith("-") : null;
}
static int parseControlChar(String str) {
// undef
if ("".equals(str)) {
return -1;
}
// del
if ("DEL".equalsIgnoreCase(str)) {
return 127;
}
// octal
if (str.charAt(0) == '0') {
return Integer.parseInt(str, 8);
}
// decimal
if (str.charAt(0) >= '1' && str.charAt(0) <= '9') {
return Integer.parseInt(str, 10);
}
// control char
if (str.charAt(0) == '^') {
if (str.charAt(1) == '?') {
return 127;
} else {
return str.charAt(1) - 64;
}
} else if (str.charAt(0) == 'M' && str.charAt(1) == '-') {
if (str.charAt(2) == '^') {
if (str.charAt(3) == '?') {
return 127 + 128;
} else {
return str.charAt(3) - 64 + 128;
}
} else {
return str.charAt(2) + 128;
}
} else {
return str.charAt(0);
}
}
static Size doGetSize(String cfg) throws IOException {
return new Size(doGetInt("columns", cfg), doGetInt("rows", cfg));
}
static int doGetInt(String name, String cfg) throws IOException {
String[] patterns = new String[] {
"\\b([0-9]+)\\s+" + name + "\\b", "\\b" + name + "\\s+([0-9]+)\\b", "\\b" + name + "\\s*=\\s*([0-9]+)\\b"
};
for (String pattern : patterns) {
Matcher matcher = Pattern.compile(pattern).matcher(cfg);
if (matcher.find()) {
return Integer.parseInt(matcher.group(1));
}
}
throw new IOException("Unable to parse " + name);
}
@Override
public void setSize(Size size) throws IOException {
if (console != null) {
exec(
true,
OSUtils.STTY_COMMAND,
"columns",
Integer.toString(size.getColumns()),
"rows",
Integer.toString(size.getRows()));
} else {
exec(
false,
OSUtils.STTY_COMMAND,
OSUtils.STTY_F_OPTION,
getName(),
"columns",
Integer.toString(size.getColumns()),
"rows",
Integer.toString(size.getRows()));
}
}
@Override
public String toString() {
return "ExecPty[" + getName() + (console != null ? ", system]" : "]");
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy