Skip to content
Snippets Groups Projects
Commit 611f12e2 authored by apvrille's avatar apvrille
Browse files

Adding terminal facility

parent e6277c04
No related branches found
No related tags found
No related merge requests found
......@@ -26,6 +26,7 @@
<root url="jar://$PROJECT_DIR$/libs/batik-xml.jar!/" />
<root url="jar://$PROJECT_DIR$/libs/jautomata-core.jar!/" />
<root url="jar://$PROJECT_DIR$/libs/com.microsoft.z3.jar!/" />
<root url="jar://$PROJECT_DIR$/libs/jna-3.3.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/libs/commons-io-2.5-javadoc.jar!/" />
......
......@@ -26,6 +26,7 @@ dependencies {
compileOnly name: 'commons-codec-1.10'
compileOnly name: 'jsoup-1.8.1'
compile name: 'jautomata-core'
compileOnly name: 'jna-3.3.0'
}
jar {
......
......@@ -21,6 +21,7 @@ dependencies {
compileOnly name: 'commons-codec-1.10'
compileOnly name: 'jsoup-1.8.1'
compile name: 'jautomata-core'
compileOnly name: 'jna-3.3.0'
}
jar {
......
......@@ -15,6 +15,7 @@ dependencies {
compile name: 'commons-codec-1.10'
compileOnly name: 'commons-io-2.5'
compileOnly name: 'jsoup-1.8.1'
compileOnly name: 'jna-3.3.0'
}
jar {
......
File added
......@@ -25,6 +25,7 @@ dependencies {
compileOnly name:'batik-util'
compile name:'jautomata-core'
compile name:'com.microsoft.z3'
compileOnly name: 'jna-3.3.0'
}
jar {
......
// Copyright 2015 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
// www.source-code.biz, www.inventec.ch/chdh
//
// This module is multi-licensed and may be used under the terms of any of the following licenses:
//
// LGPL, GNU Lesser General Public License, V2.1 or later, http://www.gnu.org/licenses/lgpl.html
// EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal
//
// Please contact the author if you need another license.
// This module is provided "as is", without warranties of any kind.
//
// Home page: http://www.source-code.biz/snippets/java/RawConsoleInput
package myutil;
import java.io.InputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
/**
* A JNA based driver for reading single characters from the console.
*
* <p>This class is used for console mode programs.
* It supports non-blocking reads of single key strokes without echo.
*/
public class RawConsoleInput {
private static final boolean isWindows = System.getProperty("os.name").startsWith("Windows");
private static final int invalidKey = 0xFFFE;
private static final String invalidKeyStr = String.valueOf((char)invalidKey);
private static boolean initDone;
private static boolean stdinIsConsole;
private static boolean consoleModeAltered;
/**
* Reads a character from the console without echo.
*
* @param wait
* <code>true</code> to wait until an input character is available,
* <code>false</code> to return immediately if no character is available.
* @return
* -2 if <code>wait</code> is <code>false</code> and no character is available.
* -1 on EOF.
* Otherwise an Unicode character code within the range 0 to 0xFFFF.
*/
public static int read (boolean wait) throws IOException {
if (isWindows) {
return readWindows(wait); }
else {
return readUnix(wait); }}
/**
* Resets console mode to normal line mode with echo.
*
* <p>On Windows this method re-enables Ctrl-C processing.
*
* <p>On Unix this method switches the console back to echo mode.
* read() leaves the console in non-echo mode.
*/
public static void resetConsoleMode() throws IOException {
if (isWindows) {
resetConsoleModeWindows(); }
else {
resetConsoleModeUnix(); }}
private static void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook( new Thread() {
public void run() {
shutdownHook(); }}); }
private static void shutdownHook() {
try {
resetConsoleMode(); }
catch (Exception e) {}}
//--- Windows ------------------------------------------------------------------
// The Windows version uses _kbhit() and _getwch() from msvcrt.dll.
private static Msvcrt msvcrt;
private static Kernel32 kernel32;
private static Pointer consoleHandle;
private static int originalConsoleMode;
private static int readWindows (boolean wait) throws IOException {
initWindows();
if (!stdinIsConsole) {
int c = msvcrt.getwchar();
if (c == 0xFFFF) {
c = -1; }
return c; }
consoleModeAltered = true;
setConsoleMode(consoleHandle, originalConsoleMode & ~Kernel32Defs.ENABLE_PROCESSED_INPUT);
// ENABLE_PROCESSED_INPUT must remain off to prevent Ctrl-C from beeing processed by the system
// while the program is not within getwch().
if (!wait && msvcrt._kbhit() == 0) {
return -2; } // no key available
return getwch(); }
private static int getwch() {
int c = msvcrt._getwch();
if (c == 0 || c == 0xE0) { // Function key or arrow key
c = msvcrt._getwch();
if (c >= 0 && c <= 0x18FF) {
return 0xE000 + c; } // construct key code in private Unicode range
return invalidKey; }
if (c < 0 || c > 0xFFFF) {
return invalidKey; }
return c; } // normal key
private static synchronized void initWindows() throws IOException {
if (initDone) {
return; }
msvcrt = (Msvcrt)Native.loadLibrary("msvcrt", Msvcrt.class);
kernel32 = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
try {
consoleHandle = getStdInputHandle();
originalConsoleMode = getConsoleMode(consoleHandle);
stdinIsConsole = true; }
catch (IOException e) {
stdinIsConsole = false; }
if (stdinIsConsole) {
registerShutdownHook(); }
initDone = true; }
private static Pointer getStdInputHandle() throws IOException {
Pointer handle = kernel32.GetStdHandle(Kernel32Defs.STD_INPUT_HANDLE);
if (Pointer.nativeValue(handle) == 0 || Pointer.nativeValue(handle) == Kernel32Defs.INVALID_HANDLE_VALUE) {
throw new IOException("GetStdHandle(STD_INPUT_HANDLE) failed."); }
return handle; }
private static int getConsoleMode (Pointer handle) throws IOException {
IntByReference mode = new IntByReference();
int rc = kernel32.GetConsoleMode(handle, mode);
if (rc == 0) {
throw new IOException("GetConsoleMode() failed."); }
return mode.getValue(); }
private static void setConsoleMode (Pointer handle, int mode) throws IOException {
int rc = kernel32.SetConsoleMode(handle, mode);
if (rc == 0) {
throw new IOException("SetConsoleMode() failed."); }}
private static void resetConsoleModeWindows() throws IOException {
if (!initDone || !stdinIsConsole || !consoleModeAltered) {
return; }
setConsoleMode(consoleHandle, originalConsoleMode);
consoleModeAltered = false; }
private static interface Msvcrt extends Library {
int _kbhit();
int _getwch();
int getwchar(); }
private static class Kernel32Defs {
static final int STD_INPUT_HANDLE = -10;
static final long INVALID_HANDLE_VALUE = (Pointer.SIZE == 8) ? -1 : 0xFFFFFFFFL;
static final int ENABLE_PROCESSED_INPUT = 0x0001;
static final int ENABLE_LINE_INPUT = 0x0002;
static final int ENABLE_ECHO_INPUT = 0x0004;
static final int ENABLE_WINDOW_INPUT = 0x0008; }
private static interface Kernel32 extends Library {
int GetConsoleMode (Pointer hConsoleHandle, IntByReference lpMode);
int SetConsoleMode (Pointer hConsoleHandle, int dwMode);
Pointer GetStdHandle (int nStdHandle); }
//--- Unix ---------------------------------------------------------------------
// The Unix version uses tcsetattr() to switch the console to non-canonical mode,
// System.in.available() to check whether data is available and System.in.read()
// to read bytes from the console.
// A CharsetDecoder is used to convert bytes to characters.
private static final int stdinFd = 0;
private static Libc libc;
private static CharsetDecoder charsetDecoder;
private static Termios originalTermios;
private static Termios rawTermios;
private static Termios intermediateTermios;
private static int readUnix (boolean wait) throws IOException {
initUnix();
if (!stdinIsConsole) { // STDIN is not a console
return readSingleCharFromByteStream(System.in); }
consoleModeAltered = true;
setTerminalAttrs(stdinFd, rawTermios); // switch off canonical mode, echo and signals
try {
if (!wait && System.in.available() == 0) {
return -2; } // no input available
return readSingleCharFromByteStream(System.in); }
finally {
setTerminalAttrs(stdinFd, intermediateTermios); }} // reset some console attributes
private static Termios getTerminalAttrs (int fd) throws IOException {
Termios termios = new Termios();
try {
int rc = libc.tcgetattr(fd, termios);
if (rc != 0) {
throw new RuntimeException("tcgetattr() failed."); }}
catch (LastErrorException e) {
throw new IOException("tcgetattr() failed.", e); }
return termios; }
private static void setTerminalAttrs (int fd, Termios termios) throws IOException {
try {
int rc = libc.tcsetattr(fd, LibcDefs.TCSANOW, termios);
if (rc != 0) {
throw new RuntimeException("tcsetattr() failed."); }}
catch (LastErrorException e) {
throw new IOException("tcsetattr() failed.", e); }}
private static int readSingleCharFromByteStream (InputStream inputStream) throws IOException {
byte[] inBuf = new byte[4];
int inLen = 0;
while (true) {
if (inLen >= inBuf.length) { // input buffer overflow
return invalidKey; }
int b = inputStream.read(); // read next byte
if (b == -1) { // EOF
return -1; }
inBuf[inLen++] = (byte)b;
int c = decodeCharFromBytes(inBuf, inLen);
if (c != -1) {
return c; }}}
// (This method is synchronized because the charsetDecoder must only be used by a single thread at once.)
private static synchronized int decodeCharFromBytes (byte[] inBytes, int inLen) {
charsetDecoder.reset();
charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE);
charsetDecoder.replaceWith(invalidKeyStr);
ByteBuffer in = ByteBuffer.wrap(inBytes, 0, inLen);
CharBuffer out = CharBuffer.allocate(1);
charsetDecoder.decode(in, out, false);
if (out.position() == 0) {
return -1; }
return out.get(0); }
private static synchronized void initUnix() throws IOException {
if (initDone) {
return; }
libc = (Libc)Native.loadLibrary("c", Libc.class);
stdinIsConsole = libc.isatty(stdinFd) == 1;
charsetDecoder = Charset.defaultCharset().newDecoder();
if (stdinIsConsole) {
originalTermios = getTerminalAttrs(stdinFd);
rawTermios = new Termios(originalTermios);
rawTermios.c_lflag &= ~(LibcDefs.ICANON | LibcDefs.ECHO | LibcDefs.ECHONL | LibcDefs.ISIG);
intermediateTermios = new Termios(rawTermios);
intermediateTermios.c_lflag |= LibcDefs.ICANON;
// Canonical mode can be switched off between the read() calls, but echo must remain disabled.
registerShutdownHook(); }
initDone = true; }
private static void resetConsoleModeUnix() throws IOException {
if (!initDone || !stdinIsConsole || !consoleModeAltered) {
return; }
setTerminalAttrs(stdinFd, originalTermios);
consoleModeAltered = false; }
protected static class Termios extends Structure { // termios.h
public int c_iflag;
public int c_oflag;
public int c_cflag;
public int c_lflag;
public byte c_line;
public byte[] filler = new byte[64]; // actual length is platform dependent
@Override protected List<String> getFieldOrder() {
return Arrays.asList("c_iflag", "c_oflag", "c_cflag", "c_lflag", "c_line", "filler"); }
Termios() {}
Termios (Termios t) {
c_iflag = t.c_iflag;
c_oflag = t.c_oflag;
c_cflag = t.c_cflag;
c_lflag = t.c_lflag;
c_line = t.c_line;
filler = t.filler.clone(); }}
private static class LibcDefs {
// termios.h
static final int ISIG = 0000001;
static final int ICANON = 0000002;
static final int ECHO = 0000010;
static final int ECHONL = 0000100;
static final int TCSANOW = 0; }
private static interface Libc extends Library {
// termios.h
int tcgetattr (int fd, Termios termios) throws LastErrorException;
int tcsetattr (int fd, int opt, Termios termios) throws LastErrorException;
// unistd.h
int isatty (int fd); }
}
/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
*
* ludovic.apvrille AT enst.fr
*
* This software is a computer program whose purpose is to allow the
* edition of TURTLE analysis, design and deployment diagrams, to
* allow the generation of RT-LOTOS or Java code from this diagram,
* and at last to allow the analysis of formal validation traces
* obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
* from INRIA Rhone-Alpes.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
package myutil;
import java.util.Vector;
/**
* Class GenericTree
* Creation: 13/03/2003
* Version 2.0 25/10/2007
* @author Ludovic APVRILLE
*/
public class Terminal {
private final static int MAX_BUFFER_SIZE = 5000;
private Vector<String> buffer;
int maxbufferSize = MAX_BUFFER_SIZE;
public Terminal() {
buffer = new Vector<>();
}
public String getNextString() {
char x = 110;
int val = 0;
int cpt = 0;
printPrompt(cpt);
String currentBuf = "";
try {
while(val != 3) {
val = (RawConsoleInput.read(true));
x = (char) val;
if (val >= 32) {
//System.out.print("" + x + "(val=" + val + ");");
myPrint(""+x);
currentBuf += x;
}
if (val == 10) {
cpt ++;
myPrint("\n");
printPrompt(cpt);
return currentBuf;
}
}
} catch (Exception e) {
return null;
}
return "";
}
public void myPrint(String s) {
System.out.print(s);
}
public void printHistory() {
int cpt = 1;
for(String s: buffer) {
System.out.println("" + cpt+ ":" + s);
cpt ++;
}
}
public void printPrompt(int cpt) {
System.out.print("" + cpt + "> ");
}
}
......@@ -20,6 +20,7 @@ dependencies {
compileOnly name: 'commons-io-2.5'
compileOnly name: 'jsoup-1.8.1'
compileOnly name: 'commons-codec-1.10'
compileOnly name: 'jna-3.3.0'
}
jar {
......
......@@ -26,6 +26,7 @@ dependencies {
compile name: 'commons-math3-3.6.1'
compile name: 'jautomata-core'
compile name: 'com.microsoft.z3'
compileOnly name: 'jna-3.3.0'
}
jar {
......
......@@ -34,6 +34,7 @@ dependencies {
compile name: 'batik-awt-util'
compile name: 'jautomata-core'
compile name: 'com.microsoft.z3'
compile name: 'jna-3.3.0'
// Use JUnit test framework
testCompile 'junit:junit:4.12'
......
Main-Class: TToolCLI
Class-Path: jsoup-1.8.1.jar commons-codec-1.10.jar gs-core-1.3.jar gs-ui-1.3.jar commons-io-2.5.jar commons-math3-3.6.1.jar batik-awt-util.jar batik-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar jautomata-core.jar com.microsoft.z3.jar
Class-Path: jsoup-1.8.1.jar commons-codec-1.10.jar gs-core-1.3.jar gs-ui-1.3.jar commons-io-2.5.jar commons-math3-3.6.1.jar batik-awt-util.jar batik-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar jautomata-core.jar com.microsoft.z3.jar jna-3.3.0.jar
Manifest-Version: 1.0
Class-Path: jsoup-1.8.1.jar commons-codec-1.10.jar gs-core-1.3.jar gs-ui-1.3.jar commons-io-2.5.jar commons-math3-3.6.1.jar batik-awt-util.jar batik-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar jautomata-core.jar com.microsoft.z3.jar
Class-Path: jsoup-1.8.1.jar commons-codec-1.10.jar gs-core-1.3.jar gs-ui-1.3.jar commons-io-2.5.jar commons-math3-3.6.1.jar batik-awt-util.jar batik-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar jautomata-core.jar com.microsoft.z3.jar jna-3.3.0.jar
Main-Class: Main
......@@ -38,6 +38,8 @@ dependencies {
compile name: 'assertj/assertj-swing/3.8.0/assertj-swing-3.8.0-sources'
compile name: 'assertj/assertj-swing-junit/3.8.0/assertj-swing-junit-3.8.0'
compile name: 'assertj/assertj-swing-junit/3.8.0/assertj-swing-junit-3.8.0-sources'
compile name: 'jna-3.3.0'
// Use JUnit test framework
testCompile 'junit:junit:4.12'
......
......@@ -22,6 +22,7 @@ dependencies {
compileOnly name: 'JavaPlot'
compileOnly name: 'jaxen-1.1.6'
compileOnly name: 'opencloud'
compileOnly name: 'jna-3.3.0'
}
jar {
......
......@@ -22,6 +22,7 @@ dependencies {
compile name: 'JavaPlot'
compile name: 'jaxen-1.1.6'
compile name: 'opencloud'
compileOnly name: 'jna-3.3.0'
}
jar {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment