Skip to content

Commit

Permalink
print map: check on maxrows & SystemRegistryImpl.invoke() fixed NPE
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed May 1, 2020
1 parent b7ae0ea commit ba70973
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 16 deletions.
52 changes: 38 additions & 14 deletions builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public enum Command {SHOW
private LineReader reader;
private boolean executing = false;
private StyleResolver prntStyle;
private int totLines;

public ConsoleEngineImpl(ScriptEngine engine
, Supplier<Path> workDir, ConfigurationPath configPath) throws IOException {
Expand Down Expand Up @@ -1295,18 +1296,36 @@ private boolean similarSets(Set<String> ref, Set<String> c2, double threshold) {
return out;
}

@SuppressWarnings("serial")
private static class TruncatedOutputException extends RuntimeException {
public TruncatedOutputException(String message) {
super(message);
}
}

private void println(AttributedString line, int maxrows) {
line.println(terminal());
totLines++;
if (totLines > maxrows) {
totLines = 0;
throw new TruncatedOutputException("Truncated output: " + maxrows);
}
}

@SuppressWarnings("unchecked")
private void highlightAndPrint(Map<String, Object> options, Object obj) {
int width = (int)options.get(Printer.WIDTH);
boolean rownum = options.containsKey(Printer.ROWNUM);
totLines = 0;
String message = null;
if (obj == null) {
// do nothing
} else if (obj instanceof Map) {
highlightMap(options, keysToString((Map<Object, Object>)obj), width);
} else if (collectionObject(obj)) {
List<Object> collection = objectToList(obj);
if (collection.size() > (int)options.get(Printer.MAXROWS)) {
trace("Truncated output: " + (int)options.get(Printer.MAXROWS) + "/" + collection.size());
message = "Truncated output: " + (int)options.get(Printer.MAXROWS) + "/" + collection.size();
collection = collection.subList(collection.size() - (int)options.get(Printer.MAXROWS), collection.size());
}
if (!collection.isEmpty()) {
Expand Down Expand Up @@ -1468,6 +1487,9 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
} else {
highlightValue(options, null, objectToString(options, obj)).println(terminal());
}
if (message != null) {
error(message);
}
}

private void highlightList(Map<String, Object> options
Expand All @@ -1478,23 +1500,24 @@ private void highlightList(Map<String, Object> options
private void highlightList(Map<String, Object> options
, List<Object> collection, int width, int depth) {
Integer row = 0;
int maxrows = (int)options.get(Printer.MAXROWS);
int indent = (int)options.get(Printer.INDENTION);
int tabsize = indent*depth;
List<Integer> tabs = new ArrayList<>();
tabs.add(indent*depth);
if (options.containsKey(Printer.ROWNUM)) {
tabsize += digits(collection.size()) + 2;
tabs.add(indent*depth + digits(collection.size()) + 2);
}
options.remove(Printer.MAX_COLUMN_WIDTH);
for (Object o : collection) {
AttributedStringBuilder asb = new AttributedStringBuilder().tabs(tabsize);
AttributedStringBuilder asb = new AttributedStringBuilder().tabs(tabs);
asb.append("\t");
if (options.containsKey(Printer.ROWNUM)) {
asb.styled(prntStyle.resolve(".rn"), row.toString()).append(":");
row++;
}
if (tabsize != 0) {
asb.append("\t");
row++;
}
asb.append(highlightValue(options, null, objectToString(options, o)));
truncate(asb, width).println(terminal());
println(truncate(asb, width), maxrows);
}
}

Expand Down Expand Up @@ -1548,6 +1571,7 @@ private void highlightMap(Map<String, Object> options, Map<String, Object> map,
@SuppressWarnings("unchecked")
private void highlightMap(Map<String, Object> options
, Map<String, Object> map, int width, int depth) {
int maxrows = (int)options.get(Printer.MAXROWS);
int max = map.keySet().stream().map(String::length).max(Integer::compareTo).get();
if (max > (int)options.getOrDefault(Printer.MAX_COLUMN_WIDTH, Integer.MAX_VALUE)) {
max = (int)options.get(Printer.MAX_COLUMN_WIDTH);
Expand All @@ -1568,15 +1592,15 @@ private void highlightMap(Map<String, Object> options
boolean highlightValue = true;
if (depth < maxDepth && !options.containsKey(Printer.TO_STRING)) {
if (elem instanceof Map || convert) {
truncate(asb, width).println(terminal());
println(truncate(asb, width), maxrows);
Map<String, Object> childMap = convert ? objectToMap(options, elem)
: keysToString((Map<Object, Object>) elem);
highlightMap(options, childMap, width, depth + 1);
highlightValue = false;
} else if (collectionObject(elem)) {
List<Object> collection = objectToList(elem);
if (!collection.isEmpty()) {
truncate(asb, width).println(terminal());
println(truncate(asb, width), maxrows);
Map<String, Object> listOptions = new HashMap<>();
listOptions.putAll(options);
listOptions.put(Printer.TO_STRING, true);
Expand All @@ -1592,12 +1616,12 @@ private void highlightMap(Map<String, Object> options
if (val.contains('\n')) {
for (String v : val.toString().split("\\r?\\n")) {
asb.append(highlightValue(options, entry.getKey(), v));
truncate(asb, width).println(terminal());
println(truncate(asb, width), maxrows);
asb = new AttributedStringBuilder().tabs(Arrays.asList(0, max + 1));
}
} else {
asb.append(val);
truncate(asb, width).println(terminal());
println(truncate(asb, width), maxrows);
}
} else {
if (val.contains('\n')) {
Expand All @@ -1606,7 +1630,7 @@ private void highlightMap(Map<String, Object> options
} else {
asb.append(val);
}
truncate(asb, width).println(terminal());
println(truncate(asb, width), maxrows);
}
}
}
Expand Down Expand Up @@ -1656,7 +1680,7 @@ private Object prnt(CommandInput input) {
" --indention=IDENTION Indention size",
" --maxColumnWidth=WIDTH Maximum column width",
" -d --maxDepth=DEPTH Maximum depth objects are resolved",
" --maxrows=ROWS Maximum number of rows on table",
" --maxrows=ROWS Maximum number of lines to display",
" --oneRowTable Display one row data on table",
" -r --rownum Display table row numbers",
" --skipDefaultOptions Ignore all options defined in PRNT_OPTIONS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ public CmdDesc commandDescription(Widgets.CmdLine line) {
public Object invoke(String command, Object... args) throws Exception {
Object out = null;
command = ConsoleEngine.plainCommand(command);
args = args == null ? new Object[] {null} : args;
int id = registryId(command);
if (id > -1) {
out = commandRegistries[id].invoke(commandSession(), command, args);
Expand Down
4 changes: 2 additions & 2 deletions reader/src/main/java/org/jline/console/Printer.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public interface Printer {
final static String MAX_DEPTH = "maxDepth";
/**
* Value: Integer<br>
* Applies: TABLE<br>
* Maximum number of rows on table.
* Applies: MAP and TABLE<br>
* Maximum number of lines on display.
*/
final static String MAXROWS = "maxrows";
/**
Expand Down

0 comments on commit ba70973

Please sign in to comment.