diff options
author | Travis Watkins <amaranth@ubuntu.com> | 2012-05-23 14:52:05 -0500 |
---|---|---|
committer | Travis Watkins <amaranth@ubuntu.com> | 2012-05-23 15:32:42 -0500 |
commit | 2e744dbf64ed5a1b987508ba5f4445357d2feac6 (patch) | |
tree | 665609311693b848fc76c19bc913ee330c71b90b /src/main/java/jline/internal | |
parent | 94e9543a14c5cc70bf42a8d28992f867d52a4b98 (diff) | |
download | craftbukkit-2e744dbf64ed5a1b987508ba5f4445357d2feac6.tar craftbukkit-2e744dbf64ed5a1b987508ba5f4445357d2feac6.tar.gz craftbukkit-2e744dbf64ed5a1b987508ba5f4445357d2feac6.tar.lz craftbukkit-2e744dbf64ed5a1b987508ba5f4445357d2feac6.tar.xz craftbukkit-2e744dbf64ed5a1b987508ba5f4445357d2feac6.zip |
Add files from jline for diff visibility
Diffstat (limited to 'src/main/java/jline/internal')
-rw-r--r-- | src/main/java/jline/internal/TerminalLineSettings.java | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/main/java/jline/internal/TerminalLineSettings.java b/src/main/java/jline/internal/TerminalLineSettings.java new file mode 100644 index 00000000..d5731ca4 --- /dev/null +++ b/src/main/java/jline/internal/TerminalLineSettings.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + */ + +package jline.internal; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Provides access to terminal line settings via <tt>stty</tt>. + * + * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> + * @author <a href="mailto:dwkemp@gmail.com">Dale Kemp</a> + * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> + * @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofré</a> + * @since 2.0 + */ +public final class TerminalLineSettings +{ + public static final String JLINE_STTY = "jline.stty"; + + public static final String DEFAULT_STTY = "stty"; + + public static final String JLINE_SH = "jline.sh"; + + public static final String DEFAULT_SH = "sh"; + + private String sttyCommand; + + private String shCommand; + + private String config; + + private long configLastFetched; + + public TerminalLineSettings() throws IOException, InterruptedException { + sttyCommand = Configuration.getString(JLINE_STTY, DEFAULT_STTY); + shCommand = Configuration.getString(JLINE_SH, DEFAULT_SH); + config = get("-a"); + configLastFetched = System.currentTimeMillis(); + + Log.debug("Config: ", config); + + // sanity check + if (config.length() == 0) { + throw new IOException(MessageFormat.format("Unrecognized stty code: {0}", config)); + } + } + + public String getConfig() { + return config; + } + + public void restore() throws IOException, InterruptedException { + set("sane"); + } + + public String get(final String args) throws IOException, InterruptedException { + return stty(args); + } + + public void set(final String args) throws IOException, InterruptedException { + stty(args); + } + + /** + * <p> + * Get the value of a stty property, including the management of a cache. + * </p> + * + * @param name the stty property. + * @return the stty property value. + */ + public int getProperty(String name) { + assert name != null; + try { + // tty properties are cached so we don't have to worry too much about getting term widht/height + if (config == null || System.currentTimeMillis() - configLastFetched > 1000 ) { + config = get("-a"); + configLastFetched = System.currentTimeMillis(); + } + return this.getProperty(name, config); + } catch (Exception e) { + Log.warn("Failed to query stty ", name, e); + return -1; + } + } + + /** + * <p> + * Parses a stty output (provided by stty -a) and return the value of a given property. + * </p> + * + * @param name property name. + * @param stty string resulting of stty -a execution. + * @return value of the given property. + */ + protected static int getProperty(String name, String stty) { + // try the first kind of regex + Pattern pattern = Pattern.compile(name + "\\s+=\\s+([^;]*)[;\\n\\r]"); + Matcher matcher = pattern.matcher(stty); + if (!matcher.find()) { + // try a second kind of regex + pattern = Pattern.compile(name + "\\s+([^;]*)[;\\n\\r]"); + matcher = pattern.matcher(stty); + if (!matcher.find()) { + // try a second try of regex + pattern = Pattern.compile("(\\S*)\\s+" + name); + matcher = pattern.matcher(stty); + if (!matcher.find()) { + return -1; + } + } + } + return parseControlChar(matcher.group(1)); + } + + private static int parseControlChar(String str) { + // under + if ("<undef>".equals(str)) { + return -1; + } + // 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); + } + } + + private String stty(final String args) throws IOException, InterruptedException { + assert args != null; + return exec(String.format("%s %s < /dev/tty", sttyCommand, args)); + } + + private String exec(final String cmd) throws IOException, InterruptedException { + assert cmd != null; + return exec(shCommand, "-c", cmd); + } + + private String exec(final String... cmd) throws IOException, InterruptedException { + assert cmd != null; + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + Log.trace("Running: ", cmd); + + Process p = Runtime.getRuntime().exec(cmd); + + InputStream in = null; + InputStream err = null; + OutputStream out = null; + try { + int c; + in = p.getInputStream(); + while ((c = in.read()) != -1) { + bout.write(c); + } + err = p.getErrorStream(); + while ((c = err.read()) != -1) { + bout.write(c); + } + out = p.getOutputStream(); + p.waitFor(); + } + finally { + close(in, out, err); + } + + String result = bout.toString(); + + Log.trace("Result: ", result); + + return result; + } + + private static void close(final Closeable... closeables) { + for (Closeable c : closeables) { + try { + c.close(); + } + catch (Exception e) { + // Ignore + } + } + } +}
\ No newline at end of file |