/* * 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 stty. * * @author Marc Prud'hommeaux * @author Dale Kemp * @author Jason Dillon * @author Jean-Baptiste Onofré * @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); } /** *
* Get the value of a stty property, including the management of a cache. *
* * @param name the stty property. * @return the stty property value. */ public int getProperty(String name) { assert name != null; // CraftBukkit start long currentTime = System.currentTimeMillis(); try { // tty properties are cached so we don't have to worry too much about getting term widht/height if (config == null || currentTime - configLastFetched > 1000) { config = get("-a"); } } catch (Exception e) { Log.debug("Failed to query stty ", name, "\n", e); } // always update the last fetched time and try to parse the output if (currentTime - configLastFetched > 1000) { configLastFetched = currentTime; } return this.getProperty(name, config); // CraftBukkit end } /** ** Parses a stty output (provided by stty -a) and return the value of a given property. *
* * @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 ("