From: <cr...@us...> - 2009-08-22 14:37:48
|
Revision: 5659 http://jnode.svn.sourceforge.net/jnode/?rev=5659&view=rev Author: crawley Date: 2009-08-22 14:37:39 +0000 (Sat, 22 Aug 2009) Log Message: ----------- Partial implementation of shell functions. (Arguments, redirections and the context / variables are not yet implemented when a function is run.) Modified Paths: -------------- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneBuiltin.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java trunk/shell/src/shell/org/jnode/shell/bjorne/FunctionDefinitionNode.java trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneBuiltin.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneBuiltin.java 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneBuiltin.java 2009-08-22 14:37:39 UTC (rev 5659) @@ -48,12 +48,6 @@ /** * Temporary adapter method. Unconverted builtin classes override this. - * - * @param command - * @param interpreter - * @param context - * @return - * @throws ShellException */ int invoke(CommandLine command, BjorneInterpreter interpreter, BjorneContext context) throws ShellException { Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-08-22 14:37:39 UTC (rev 5659) @@ -90,8 +90,10 @@ private final BjorneInterpreter interpreter; private Map<String, VariableSlot> variables; + + private TreeMap<String, String> aliases; - private TreeMap<String, String> aliases; + private TreeMap<String, CommandNode> functions; private String command = ""; @@ -122,6 +124,7 @@ this.holders = holders; this.variables = new HashMap<String, VariableSlot>(); this.aliases = new TreeMap<String, String>(); + this.functions = new TreeMap<String, CommandNode>(); initVariables(); } @@ -157,6 +160,7 @@ this.holders = copyStreamHolders(parent.holders); this.variables = copyVariables(parent.variables); this.aliases = new TreeMap<String, String>(parent.aliases); + this.functions = new TreeMap<String, CommandNode>(parent.functions); this.globbing = parent.globbing; this.tildeExpansion = parent.tildeExpansion; this.echoExpansions = parent.echoExpansions; @@ -406,15 +410,8 @@ * @param tokens the tokens to be expanded and split into words * @throws ShellException */ - public List<BjorneToken> expandAndSplit(BjorneToken ... tokens) - throws ShellException { - List<BjorneToken> wordTokens = new LinkedList<BjorneToken>(); - for (BjorneToken token : tokens) { - dollarBacktickSplit(token, wordTokens); - } - wordTokens = fileExpand(wordTokens); - wordTokens = dequote(wordTokens); - return wordTokens; + public List<BjorneToken> expandAndSplit(BjorneToken ... tokens) throws ShellException { + return expandAndSplit(Arrays.asList(tokens)); } /** @@ -1061,7 +1058,7 @@ return new BjorneArithmeticEvaluator(this).evaluateExpression(tmp); } - int execute(CommandLine command, CommandIO[] streams, boolean isBuiltin) throws ShellException { + int execute(CommandLine command, CommandIO[] streams) throws ShellException { if (isEchoExpansions()) { StringBuilder sb = new StringBuilder(); sb.append(" + ").append(command.getCommandName()); @@ -1071,7 +1068,7 @@ resolvePrintStream(streams[Command.STD_ERR]).println(sb); } Map<String, String> env = buildEnvFromExports(); - lastReturnCode = interpreter.executeCommand(command, this, streams, null, env, isBuiltin); + lastReturnCode = interpreter.executeCommand(command, this, streams, null, env); return lastReturnCode; } @@ -1390,4 +1387,12 @@ return variables.keySet(); } + void defineFunction(BjorneToken name, CommandNode body) { + functions.put(name.getText(), body); + } + + CommandNode getFunction(String name) { + return functions.get(name); + } + } Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java 2009-08-22 14:37:39 UTC (rev 5659) @@ -122,7 +122,7 @@ public static final int FLAG_PIPE = 0x0010; public static final CommandNode EMPTY = - new SimpleCommandNode(CMD_EMPTY, new BjorneToken[0], false); + new SimpleCommandNode(CMD_EMPTY, new BjorneToken[0]); static HashMap<String, BjorneBuiltin.Factory> BUILTINS = new HashMap<String, BjorneBuiltin.Factory>(); @@ -313,13 +313,19 @@ } int executeCommand(CommandLine cmdLine, BjorneContext context, CommandIO[] streams, - Properties sysProps, Map<String, String> env, boolean isBuiltin) + Properties sysProps, Map<String, String> env) throws ShellException { - if (isBuiltin) { - BjorneBuiltinCommandInfo builtin = - BUILTINS.get(cmdLine.getCommandName()).buildCommandInfo(context); + String commandName = cmdLine.getCommandName(); + if (isBuiltin(commandName)) { + BjorneBuiltinCommandInfo builtin = BUILTINS.get(commandName).buildCommandInfo(context); cmdLine.setCommandInfo(builtin); - } + } else { + CommandNode body = context.getFunction(commandName); + if (body != null) { + // FIXME setup a new context, streams and args. + return body.execute(context); + } + } cmdLine.setStreams(streams); return shell.invoke(cmdLine, sysProps, env); } Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java 2009-08-22 14:37:39 UTC (rev 5659) @@ -145,7 +145,7 @@ } else { noLineBreaks(); if (optNext(TOK_END_OF_LINE_BIT) != null) { - command = new SimpleCommandNode(CMD_COMMAND, new BjorneToken[0], false); + command = new SimpleCommandNode(CMD_COMMAND, new BjorneToken[0]); } } return command; @@ -292,7 +292,6 @@ List<BjorneToken> assignments = new LinkedList<BjorneToken>(); List<RedirectionNode> redirects = new LinkedList<RedirectionNode>(); List<BjorneToken> words = new LinkedList<BjorneToken>(); - boolean builtin = false; // Deal with cmd_prefix'es before the command name; i.e. assignments and // redirections @@ -338,21 +337,17 @@ redirects.add(parseRedirect()); } } - String commandWord = words.get(0).getText(); - builtin = BjorneInterpreter.isBuiltin(commandWord); - // FIXME ... built-in commands should use the Syntax mechanisms so - // that completion, help, etc will work as expected. } } catch (ShellSyntaxException ex) { if (completer != null) { completer.setCommand(words.size() == 0 ? null : new SimpleCommandNode(CMD_COMMAND, - words.toArray(new BjorneToken[words.size()]), builtin)); + words.toArray(new BjorneToken[words.size()]))); } throw ex; } SimpleCommandNode res = new SimpleCommandNode(CMD_COMMAND, - words.toArray(new BjorneToken[words.size()]), builtin); + words.toArray(new BjorneToken[words.size()])); if (completer != null) { completer.setCommand(words.size() == 0 ? null : res); } @@ -382,8 +377,6 @@ } private CommandNode parseFunctionBody() throws ShellSyntaxException { - // TODO ... need to set the context to 'rule 9' while parsing the - // function body CommandNode body = parseCompoundCommand(); body.setRedirects(parseOptRedirects()); return body; Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/FunctionDefinitionNode.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/FunctionDefinitionNode.java 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/FunctionDefinitionNode.java 2009-08-22 14:37:39 UTC (rev 5659) @@ -56,7 +56,8 @@ @Override public int execute(BjorneContext context) { - return -1; + context.defineFunction(name, body); + return 0; } @Override Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java 2009-08-22 14:37:39 UTC (rev 5659) @@ -38,12 +38,10 @@ private final BjorneToken[] words; - private final boolean builtin; - public SimpleCommandNode(int nodeType, BjorneToken[] words, boolean builtin) { + public SimpleCommandNode(int nodeType, BjorneToken[] words) { super(nodeType); this.words = words; - this.builtin = builtin; } public void setAssignments(BjorneToken[] assignments) { @@ -58,10 +56,6 @@ return assignments; } - public boolean isBuiltin() { - return builtin; - } - public String toString() { StringBuilder sb = new StringBuilder(); sb.append("SimpleCommand{").append(super.toString()); @@ -69,9 +63,6 @@ sb.append(",assignments="); appendArray(sb, assignments); } - if (builtin) { - sb.append(",builtin=true"); - } if (words != null) { sb.append(",words="); appendArray(sb, words); @@ -110,7 +101,7 @@ throw new ShellFailureException( "asynchronous execution (&) not implemented yet"); } else { - rc = childContext.execute(command, ios, builtin); + rc = childContext.execute(command, ios); } } } catch (BjorneControlException ex) { @@ -153,9 +144,10 @@ throws CompletionException { try { CommandLine command = context.buildCommandLine(words); - if (builtin) { + String commandName = command.getCommandName(); + if (commandName != null && BjorneInterpreter.isBuiltin(commandName)) { BjorneBuiltinCommandInfo commandInfo = - BjorneInterpreter.BUILTINS.get(command.getCommandName()).buildCommandInfo(context); + BjorneInterpreter.BUILTINS.get(commandName).buildCommandInfo(context); command.setCommandInfo(commandInfo); } command.setArgumentAnticipated(argumentAnticipated); Modified: trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-builtin-tests.xml 2009-08-22 14:37:39 UTC (rev 5659) @@ -74,26 +74,6 @@ <output>fred='ls' </output> </testSpec> - <testSpec title="builtins recognized early" command="test" runMode="AS_SCRIPT" rc="0"> - <script>#!bjorne - alias fred=ls - alias - unalias -a - echo done - UNALIAS=unalias - alias fred=dir - alias - $UNALIAS -a - echo done - </script> - <output>fred='ls' -done -fred='dir' -done -</output> - <error>Cannot find an alias or load a command class for 'unalias' -</error> - </testSpec> <testSpec title="readonly" runMode="AS_SCRIPT" rc="0"> <script>#!bjorne readonly A Modified: trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml 2009-08-21 13:24:37 UTC (rev 5658) +++ trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml 2009-08-22 14:37:39 UTC (rev 5659) @@ -969,4 +969,14 @@ <error>Cannot find an alias or load a command class for 'foo' </error> </testSpec> + <testSpec title="shell function" command="test" runMode="AS_SCRIPT" rc="0"> + <script>#!bjorne + foo() { + echo hi + } + foo + </script> + <output >hi +</output> + </testSpec> </testSet> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |