Author: gnodet Date: Wed Apr 4 13:27:20 2018 New Revision: 1828342 URL: http://svn.apache.org/viewvc?rev=1828342&view=rev Log: [FELIX-5822][gogo][jline] Improve syntax of procedural functions
Modified: felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java Modified: felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java URL: http://svn.apache.org/viewvc/felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java?rev=1828342&r1=1828341&r2=1828342&view=diff ============================================================================== --- felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java (original) +++ felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java Wed Apr 4 13:27:20 2018 @@ -25,9 +25,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -import org.apache.felix.service.command.Process; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Function; +import org.apache.felix.service.command.Process; import org.jline.builtins.Options; public class Procedural { @@ -127,7 +127,7 @@ public class Procedural { Object[] argv) throws Exception { String[] usage = { "each - loop over the elements", - "Usage: each [-r] elements { closure }", + "Usage: each [-r] elements [do] { closure }", " elements an array to iterate on", " closure a closure to call", " -? --help Show help", @@ -136,10 +136,14 @@ public class Procedural { Options opt = parseOptions(session, usage, argv); Collection<Object> elements = getElements(opt); + if (opt.argObjects().size() > 0 && "do".equals(opt.argObjects().get(0))) { + opt.argObjects().remove(0); + } List<Function> functions = getFunctions(opt); + if (elements == null || functions == null || functions.size() != 1) { - process.err().println("usage: each elements { closure }"); + process.err().println("usage: each elements [do] { closure }"); process.err().println(" elements: an array to iterate on"); process.err().println(" closure: a function or closure to call"); process.error(2); @@ -168,21 +172,104 @@ public class Procedural { 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}", + "Usage: if {condition} [then] {if-action} [elif {cond} [then] {elif-action}]... [else] {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}"); + + List<Function> conditions = new ArrayList<>(); + List<Function> actions = new ArrayList<>(); + Function elseFunction = null; + int step = 0; + boolean error = false; + for (Object obj : opt.argObjects()) { + switch (step) { + case 0: + if (obj instanceof Function) { + conditions.add((Function) obj); + } else { + error = true; + } + step = 1; + break; + case 1: + if ("then".equals(obj)) { + step = 2; + break; + } + case 2: + if (obj instanceof Function) { + actions.add((Function) obj); + step = 3; + } else { + error = true; + } + break; + case 3: + if ("elif".equals(obj)) { + step = 4; + } else if ("else".equals(obj)) { + step = 7; + } else if (obj instanceof Function) { + elseFunction = (Function) obj; + step = 8; + } else { + error = true; + } + break; + case 4: + if (obj instanceof Function) { + conditions.add((Function) obj); + } else { + error = true; + } + step = 5; + break; + case 5: + if ("then".equals(obj)) { + step = 6; + break; + } + case 6: + if (obj instanceof Function) { + actions.add((Function) obj); + step = 3; + } else { + error = true; + } + break; + case 7: + if (obj instanceof Function) { + elseFunction = (Function) obj; + step = 8; + } else { + error = true; + } + break; + case 8: + error = true; + break; + } + if (error) { + break; + } + } + error |= conditions.isEmpty(); + error |= conditions.size() != actions.size(); + + if (error) { + process.err().println("usage: if {condition} [then] {if-action} [elif {elif-action}]... [else] {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); + for (int i = 0, length = conditions.size(); i < length; ++i) { + if (isTrue(session, conditions.get(i))) { + return actions.get(i).execute(session, null); } } + if (elseFunction != null) { + return elseFunction.execute(session, null); + } return null; } @@ -237,29 +324,78 @@ public class Procedural { protected Object doTry(CommandSession session, Process process, Object[] argv) throws Exception { String[] usage = { "try - try / catch / finally construct", - "Usage: try { try-action } [ { catch-action } [ { finally-action } ] ]", + "Usage: try { try-action } [ [catch] { catch-action } [ [finally] { finally-action } ] ]", " -? --help Show help", }; Options opt = parseOptions(session, usage, argv); - List<Function> functions = getFunctions(opt); - if (functions == null || functions.size() < 1 || functions.size() > 3) { - process.err().println("usage: try { try-action } [ { catch-action } [ { finally-action } ] ]"); + Function tryAction = null; + Function catchFunction = null; + Function finallyFunction = null; + int step = 0; + boolean error = false; + for (Object obj : opt.argObjects()) { + if (tryAction == null) { + if (obj instanceof Function) { + tryAction = (Function) obj; + } else { + error = true; + break; + } + step = 1; + } else if ("catch".equals(obj)) { + if (step != 1) { + error = true; + break; + } + step = 2; + } else if ("finally".equals(obj)) { + if (step != 1 && step != 3) { + error = true; + break; + } + step = 4; + } else if (step == 1 || step == 2) { + if (obj instanceof Function) { + catchFunction = (Function) obj; + } else { + error = true; + break; + } + step = 3; + } else if (step == 3 || step == 4) { + if (obj instanceof Function) { + finallyFunction = (Function) obj; + } else { + error = true; + break; + } + step = 5; + } else { + error = true; + break; + } + } + error |= tryAction == null; + error |= catchFunction == null && finallyFunction == null; + + if (error) { + process.err().println("usage: try { try-action } [ [catch] { catch-action } [ [finally] { finally-action } ] ]"); process.error(2); return null; } try { - return functions.get(0).execute(session, null); + return tryAction.execute(session, null); } catch (BreakException b) { throw b; } catch (Exception e) { session.put("exception", e); - if (functions.size() > 1) { - functions.get(1).execute(session, null); + if (catchFunction != null) { + catchFunction.execute(session, null); } return null; } finally { - if (functions.size() > 2) { - functions.get(2).execute(session, null); + if (finallyFunction != null) { + finallyFunction.execute(session, null); } } } @@ -267,19 +403,53 @@ public class Procedural { protected Object doWhile(CommandSession session, Process process, Object[] argv) throws Exception { String[] usage = { "while - while loop", - "Usage: while { condition } { action }", + "Usage: while { condition } [do] { 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: while { condition } { action }"); + Function condition = null; + Function action = null; + int step = 0; + boolean error = false; + for (Object obj : opt.argObjects()) { + if (condition == null) { + if (obj instanceof Function) { + condition = (Function) obj; + } else { + error = true; + break; + } + step = 1; + } else if ("do".equals(obj)) { + if (step != 1) { + error = true; + break; + } + step = 2; + } else if (step == 1 || step == 2) { + if (obj instanceof Function) { + action = (Function) obj; + } else { + error = true; + break; + } + step = 3; + } else { + error = true; + break; + } + } + error |= condition == null; + error |= action == null; + + if (error) { + process.err().println("usage: while { condition } [do] { action }"); process.error(2); return null; } - while (isTrue(session, functions.get(0))) { + while (isTrue(session, condition)) { try { - functions.get(1).execute(session, null); + action.execute(session, null); } catch (BreakException b) { break; } catch (ContinueException c) { @@ -292,29 +462,53 @@ public class Procedural { protected Object doUntil(CommandSession session, Process process, Object[] argv) throws Exception { String[] usage = { "until - until loop", - "Usage: until { condition } { action }", + "Usage: until { condition } [do] { action }", " -? --help Show help", }; Options opt = parseOptions(session, usage, argv); - List<Function> functions = new ArrayList<>(); - for (Object o : opt.argObjects()) { - if (o instanceof Function) { - functions.add((Function) o); - } - else { - functions = null; + Function condition = null; + Function action = null; + int step = 0; + boolean error = false; + for (Object obj : opt.argObjects()) { + if (condition == null) { + if (obj instanceof Function) { + condition = (Function) obj; + } else { + error = true; + break; + } + step = 1; + } else if ("do".equals(obj)) { + if (step != 1) { + error = true; + break; + } + step = 2; + } else if (step == 1 || step == 2) { + if (obj instanceof Function) { + action = (Function) obj; + } else { + error = true; + break; + } + step = 3; + } else { + error = true; break; } } - int length = opt.argObjects().size(); - if (length != 2 || functions == null) { - process.err().println("usage: until { condition } { action }"); + error |= condition == null; + error |= action == null; + + if (error) { + process.err().println("usage: until { condition } [do] { action }"); process.error(2); return null; } - while (!isTrue(session, functions.get(0))) { + while (!isTrue(session, condition)) { try { - functions.get(1).execute(session, null); + action.execute(session, null); } catch (BreakException e) { break; } catch (ContinueException c) {