|
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.
|