use of org.jline.builtins.Options in project felix by apache.
the class Posix method tail.
protected void tail(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = { "tail - displays last lines of file", "Usage: tail [-f] [-q] [-c # | -n #] [file ...]", " -? --help Show help", " -q --quiet Suppress headers when printing multiple sources", " -f --follow Do not stop at end of file", " -F --FOLLOW Follow and check for file renaming or rotation", " -n --lines=LINES Number of lines to print", " -c --bytes=BYTES Number of bytes to print" };
Options opt = parseOptions(session, usage, argv);
if (opt.isSet("lines") && opt.isSet("bytes")) {
throw new IllegalArgumentException("usage: tail [-f] [-q] [-c # | -n #] [file ...]");
}
int lines;
int bytes;
if (opt.isSet("lines")) {
lines = opt.getNumber("lines");
bytes = Integer.MAX_VALUE;
} else if (opt.isSet("bytes")) {
lines = Integer.MAX_VALUE;
bytes = opt.getNumber("bytes");
} else {
lines = 10;
bytes = Integer.MAX_VALUE;
}
boolean follow = opt.isSet("follow") || opt.isSet("FOLLOW");
AtomicReference<Object> lastPrinted = new AtomicReference<>();
WatchService watchService = follow ? session.currentDir().getFileSystem().newWatchService() : null;
Set<Path> watched = new HashSet<>();
class Input implements Closeable {
String name;
Path path;
Reader reader;
StringBuilder buffer;
long ino;
long size;
public Input(String name) {
this.name = name;
this.buffer = new StringBuilder();
}
public void open() {
if (reader == null) {
try {
InputStream is;
if ("-".equals(name)) {
is = new StdInSource(process).read();
} else {
path = session.currentDir().resolve(name);
is = Files.newInputStream(path);
if (opt.isSet("FOLLOW")) {
try {
ino = (Long) Files.getAttribute(path, "unix:ino");
} catch (Exception e) {
// Ignore
}
}
size = Files.size(path);
}
reader = new InputStreamReader(is);
} catch (IOException e) {
// Ignore
}
}
}
@Override
public void close() throws IOException {
if (reader != null) {
try {
reader.close();
} finally {
reader = null;
}
}
}
public boolean tail() throws IOException {
open();
if (reader != null) {
if (buffer != null) {
char[] buf = new char[1024];
int nb;
while ((nb = reader.read(buf)) > 0) {
buffer.append(buf, 0, nb);
if (bytes > 0 && buffer.length() > bytes) {
buffer.delete(0, buffer.length() - bytes);
} else {
int l = 0;
int i = -1;
while ((i = buffer.indexOf("\n", i + 1)) >= 0) {
l++;
}
if (l > lines) {
i = -1;
l = l - lines;
while (--l >= 0) {
i = buffer.indexOf("\n", i + 1);
}
buffer.delete(0, i + 1);
}
}
}
String toPrint = buffer.toString();
print(toPrint);
buffer = null;
if (follow && path != null) {
Path parent = path.getParent();
if (!watched.contains(parent)) {
parent.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
watched.add(parent);
}
}
return follow;
} else if (follow && path != null) {
while (true) {
long newSize = Files.size(path);
if (size != newSize) {
char[] buf = new char[1024];
int nb;
while ((nb = reader.read(buf)) > 0) {
print(new String(buf, 0, nb));
}
size = newSize;
}
if (opt.isSet("FOLLOW")) {
long newIno = 0;
try {
newIno = (Long) Files.getAttribute(path, "unix:ino");
} catch (Exception e) {
// Ignore
}
if (ino != newIno) {
close();
open();
ino = newIno;
size = -1;
continue;
}
}
break;
}
return true;
} else {
return false;
}
} else {
Path parent = path.getParent();
if (!watched.contains(parent)) {
parent.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
watched.add(parent);
}
return true;
}
}
private void print(String toPrint) {
if (lastPrinted.get() != this && opt.args().size() > 1 && !opt.isSet("quiet")) {
process.out().println();
process.out().println("==> " + name + " <==");
}
process.out().print(toPrint);
lastPrinted.set(this);
}
}
if (opt.args().isEmpty()) {
opt.args().add("-");
}
List<Input> inputs = new ArrayList<>();
for (String name : opt.args()) {
Input input = new Input(name);
inputs.add(input);
}
try {
boolean cont = true;
while (cont) {
cont = false;
for (Input input : inputs) {
cont |= input.tail();
}
if (cont) {
WatchKey key = watchService.take();
key.pollEvents();
key.reset();
}
}
} catch (InterruptedException e) {
// Ignore, this is the only way to quit
} finally {
for (Input input : inputs) {
input.close();
}
}
}
use of org.jline.builtins.Options in project felix by apache.
the class Posix method less.
protected void less(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = { "less - file pager", "Usage: less [OPTIONS] [FILES]", " -? --help Show help", " -e --quit-at-eof Exit on second EOF", " -E --QUIT-AT-EOF Exit on EOF", " -F --quit-if-one-screen Exit if entire file fits on first screen", " -q --quiet --silent Silent mode", " -Q --QUIET --SILENT Completely silent", " -S --chop-long-lines Do not fold long lines", " -i --ignore-case Search ignores lowercase case", " -I --IGNORE-CASE Search ignores all case", " -x --tabs Set tab stops", " -N --LINE-NUMBERS Display line number for each line", " --no-init Disable terminal initialization", " --no-keypad Disable keypad handling" };
boolean hasExtendedOptions = false;
try {
Less.class.getField("quitIfOneScreen");
hasExtendedOptions = true;
} catch (NoSuchFieldException e) {
List<String> ustrs = new ArrayList<>(Arrays.asList(usage));
ustrs.removeIf(s -> s.contains("--quit-if-one-screen") || s.contains("--no-init") || s.contains("--no-keypad"));
usage = ustrs.toArray(new String[ustrs.size()]);
}
Options opt = parseOptions(session, usage, argv);
List<Source> sources = new ArrayList<>();
if (opt.args().isEmpty()) {
opt.args().add("-");
}
for (String arg : opt.args()) {
if ("-".equals(arg)) {
sources.add(new StdInSource(process));
} else {
sources.add(new PathSource(session.currentDir().resolve(arg), arg));
}
}
if (!process.isTty(1)) {
for (Source source : sources) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(source.read()))) {
cat(process, reader, opt.isSet("LINE-NUMBERS"));
}
}
return;
}
Less less = new Less(Shell.getTerminal(session));
less.quitAtFirstEof = opt.isSet("QUIT-AT-EOF");
less.quitAtSecondEof = opt.isSet("quit-at-eof");
less.quiet = opt.isSet("quiet");
less.veryQuiet = opt.isSet("QUIET");
less.chopLongLines = opt.isSet("chop-long-lines");
less.ignoreCaseAlways = opt.isSet("IGNORE-CASE");
less.ignoreCaseCond = opt.isSet("ignore-case");
if (opt.isSet("tabs")) {
less.tabs = opt.getNumber("tabs");
}
less.printLineNumbers = opt.isSet("LINE-NUMBERS");
if (hasExtendedOptions) {
Less.class.getField("quitIfOneScreen").set(less, opt.isSet("quit-if-one-screen"));
Less.class.getField("noInit").set(less, opt.isSet("no-init"));
Less.class.getField("noKeypad").set(less, opt.isSet("no-keypad"));
}
less.run(sources);
}
use of org.jline.builtins.Options in project felix by apache.
the class Posix method parseOptions.
protected Options parseOptions(CommandSession session, String[] usage, Object[] argv) throws Exception {
Options opt = Options.compile(usage, s -> get(session, s)).parse(argv, true);
if (opt.isSet("help")) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
opt.usage(new PrintStream(baos));
throw new HelpException(baos.toString());
}
return opt;
}
use of org.jline.builtins.Options in project felix by apache.
the class Procedural method doIf.
protected Object doIf(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = { "if - if / then / else construct", "Usage: if {condition} {if-action} ... {else-action}", " -? --help Show help" };
Options opt = parseOptions(session, usage, argv);
List<Function> functions = getFunctions(opt);
if (functions == null || functions.size() < 2) {
process.err().println("usage: if {condition} {if-action} ... {else-action}");
process.error(2);
return null;
}
for (int i = 0, length = functions.size(); i < length; ++i) {
if (i == length - 1 || isTrue(session, ((Function) opt.argObjects().get(i++)))) {
return ((Function) opt.argObjects().get(i)).execute(session, null);
}
}
return null;
}
use of org.jline.builtins.Options in project felix by apache.
the class Procedural method doEach.
protected List<Object> doEach(CommandSession session, Process process, Object[] argv) throws Exception {
String[] usage = { "each - loop over the elements", "Usage: each [-r] elements { closure }", " elements an array to iterate on", " closure a closure to call", " -? --help Show help", " -r --result Return a list containing each iteration result" };
Options opt = parseOptions(session, usage, argv);
Collection<Object> elements = getElements(opt);
List<Function> functions = getFunctions(opt);
if (elements == null || functions == null || functions.size() != 1) {
process.err().println("usage: each elements { closure }");
process.err().println(" elements: an array to iterate on");
process.err().println(" closure: a function or closure to call");
process.error(2);
return null;
}
List<Object> args = new ArrayList<>();
List<Object> results = new ArrayList<>();
args.add(null);
for (Object x : elements) {
checkInterrupt();
args.set(0, x);
try {
results.add(functions.get(0).execute(session, args));
} catch (BreakException b) {
break;
} catch (ContinueException c) {
continue;
}
}
return opt.isSet("result") ? results : null;
}
Aggregations