Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,6 @@ fabric.properties
/use-assembly/target

**/.DS_Store

# Claude Code
.claude/
17 changes: 7 additions & 10 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,13 @@ Otherwise, a simple "mvn compile" or "mwn verify" should compile
the whole USE package. "mvn verify" will run all tests whereas
"mvn compile" just compiles.

Interaction with USE is done via a command line interface. This will
be much more comfortable if you have the GNU readline library
available on your system. USE provides an interface to the readline
library. For example, it allows bash or emacs-like editing of lines
and keeps a history file of recent input. Since the readline library
is platform dependent, the interface has to be compiled on your
system. Changes to the build file may be necessary for your
environment. If you don't have the readline library - don't worry.
USE will fall back to a simple input mechanism if it cannot find or
load the readline library at runtime.
Interaction with USE is done via a command line interface. It uses the
pure-Java JLine library to provide comfortable line editing (bash or
emacs-like) and to keep a history file of recent input. JLine works out
of the box on Linux, macOS and Windows, so no platform-dependent native
library has to be built or installed. When USE is run without an
interactive terminal (for example with piped input), it automatically
falls back to a simple input mechanism.



Expand Down
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Please see the file `README' for a description of how to report bugs.

** Changes between version 7.1.0 and X.X.X
* USE now supports data types
* The interactive command line now uses the pure-Java JLine library for line
editing and history instead of the native GNU readline library. This removes
the native build step and provides command-line editing on Windows, macOS
and Linux out of the box.

** Changes between version 5.2.0 and 6.0.0
* New OCL complexity plugin
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ the web.

- The [ANTLR parser generator tool](http://www.antlr.org)
- The [JUnit library](http://www.junit.org)
- The [JLine library](https://github.com/jline/jline2) for command-line editing and history

## Reporting bugs

Expand Down
1 change: 1 addition & 0 deletions use-core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
requires java.scripting;
requires org.jruby.dist;
requires combinatoricslib;
requires jline;
requires java.datatransfer;
requires java.desktop;
exports org.tzi.use.config;
Expand Down
12 changes: 5 additions & 7 deletions use-core/src/main/java/org/tzi/use/config/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ public static String getIconPath(String iconName) {
* Otherwise, only the shell is available.
*/
public static boolean doGUI = true;

public static boolean suppressWarningsAboutMissingReadlineLibrary = false;


public static boolean quiet = false;

private static boolean debug = false;
Expand Down Expand Up @@ -246,7 +244,7 @@ private static void printHelp() {
System.out.println(" -noplugins do not use plugins");
System.out.println(" -h print help");
System.out.println(" -H=path home of use installation");
System.out.println(" -nr suppress warnings about missing readline library");
System.out.println(" -nr deprecated, ignored (kept for backward compatibility)");
System.out.println(" -q reads spec_file, executes cmd_file, and checks constraints");
System.out.println(" exit code is 1 if constraints fail, otherwise 0");
System.out.println(" -qv like -q but with verbose output of constraint check");
Expand Down Expand Up @@ -306,7 +304,6 @@ public static void resetOptions() {
compileOnly = false;
compileAndPrint = false;
doGUI = true;
suppressWarningsAboutMissingReadlineLibrary = false;
quiet = false;
debug = false;
quietAndVerboseConstraintCheck = false;
Expand Down Expand Up @@ -356,8 +353,9 @@ public static void processArgs(String[] args) {
System.err.println("Invalid path " + StringUtil.inQuotes(arg.substring(2)) + " for home directory specified.");
System.exit(1);
}
} else if (arg.equals("nr")) {
suppressWarningsAboutMissingReadlineLibrary = true;
} else if (arg.equals("nr")) {
// Deprecated: the GNU readline library is no longer used.
// Accepted as a no-op for backward compatibility.
} else if (arg.equals("q")) {
Options.quiet = true;
Options.doGUI = false;
Expand Down
47 changes: 0 additions & 47 deletions use-core/src/main/java/org/tzi/use/util/input/GNUReadline.java

This file was deleted.

95 changes: 95 additions & 0 deletions use-core/src/main/java/org/tzi/use/util/input/JLineReadline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* USE - UML based specification environment
* Copyright (C) 1999-2004 Mark Richters, University of Bremen
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

package org.tzi.use.util.input;

import jline.console.ConsoleReader;
import jline.console.history.FileHistory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
* A {@link Readline} implementation backed by the pure-Java
* <a href="https://github.com/jline/jline2">JLine</a> library. It provides
* line editing and a persistent command history on all platforms (Linux,
* macOS and Windows) without requiring a platform-dependent native library.
*
* <p>This replaces the former JNI binding to the native GNU readline library
* and removes the corresponding native build steps.</p>
*
* @author Mark Richters
*/
public class JLineReadline implements Readline {

private final ConsoleReader reader;
private FileHistory history;

public JLineReadline() throws IOException {
this(null, null);
}

/**
* Package-private constructor used by tests to supply explicit streams
* instead of attaching to the real terminal.
*/
JLineReadline(InputStream in, OutputStream out) throws IOException {
reader = (in != null && out != null)
? new ConsoleReader(in, out)
: new ConsoleReader();
// USE uses '!' and '!!' to start SOIL statements. Disable JLine's
// history expansion so these characters are passed through verbatim.
reader.setExpandEvents(false);
}

@Override
public String readline(String prompt) throws IOException {
return reader.readLine(prompt);
}

@Override
public void usingHistory() {
reader.setHistoryEnabled(true);
}

@Override
public void readHistory(String filename) throws IOException {
history = new FileHistory(new File(filename));
reader.setHistory(history);
}

@Override
public void writeHistory(String filename) throws IOException {
if (history != null) {
history.flush();
}
}

@Override
public void close() throws IOException {
reader.shutdown();
}

@Override
public boolean doEcho() {
return false;
}
}
54 changes: 26 additions & 28 deletions use-core/src/main/java/org/tzi/use/util/input/LineInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,45 @@
package org.tzi.use.util.input;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* Interface for getting a suitable platform-dependent readline
* implementation. The GNU readline library is preferably used if
* installed.
*
* @author Mark Richters
* Factory for obtaining a suitable {@link Readline} implementation.
*
* <p>For interactive use the pure-Java {@link JLineReadline} is returned,
* providing line editing and command history on all platforms. When no
* interactive terminal is available (e.g. the input is piped or USE runs in
* a headless environment) a plain {@link StreamReadline} reading from
* {@code System.in} is used instead.</p>
*
* @author Mark Richters
*/
public class LineInput {

// utility class
private LineInput() {}

/**
* Returns a readline implementation. If the native GNU readline
* library is available, return that. Otherwise, a stream readline
* implementation with System.in as source is returned.
*
* @param errorMessage if not null print a message when the native
* GNU readline library is not available, otherwise
* fail silently.
* Returns a {@link Readline} implementation for reading interactive user
* input. A JLine-backed implementation is used when a terminal is
* available; otherwise a simple stream-based implementation reading from
* {@code System.in} is returned.
*/
public static Readline getUserInputReadline(String errorMessage) {
Readline rl = null;
try {
System.loadLibrary("natGNUReadline");
rl = new GNUReadline();
} catch (UnsatisfiedLinkError ex) {
if (errorMessage != null ) {
System.out.println(ex.toString());
System.out.println(errorMessage);
public static Readline getUserInputReadline() {
if (System.console() != null) {
try {
return new JLineReadline();
} catch (IOException ex) {
// JLine could not attach to the terminal; fall back below.
}
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// no echo, do protocol
rl = new StreamReadline(reader, false);
}
return rl;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// no echo, do protocol
return new StreamReadline(reader, false);
}

public static Readline getStreamReadline(BufferedReader reader, boolean doEcho, String string) {
return new StreamReadline(reader, doEcho, string);
public static Readline getStreamReadline(BufferedReader reader, boolean doEcho, String prompt) {
return new StreamReadline(reader, doEcho, prompt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
class Readline_test {

public static void main(String[] args) {
Readline rl = LineInput.getUserInputReadline("readline library not found");
Readline rl = LineInput.getUserInputReadline();
String line;
try {
do {
Expand Down
Loading