|
From: <cr...@us...> - 2009-02-08 08:01:53
|
Revision: 5006
http://jnode.svn.sourceforge.net/jnode/?rev=5006&view=rev
Author: crawley
Date: 2009-02-08 08:01:48 +0000 (Sun, 08 Feb 2009)
Log Message:
-----------
Fix quote handling of "$X" and related stuff.
Modified Paths:
--------------
trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java
trunk/shell/src/shell/org/jnode/shell/bjorne/ListCommandNode.java
trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java
trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTests.java
trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml
trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java
Added Paths:
-----------
trunk/shell/src/shell/org/jnode/shell/bjorne/CharIterator.java
trunk/shell/src/shell/org/jnode/shell/bjorne/StreamHolder.java
trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-02-08 06:42:27 UTC (rev 5005)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -541,7 +541,8 @@
if (quote == '\'') {
sb.append('$');
} else {
- sb.append(dollarExpansion(ci, quote));
+ String tmp = dollarExpansion(ci, quote);
+ sb.append(tmp == null ? "" : tmp);
}
break;
@@ -573,27 +574,16 @@
case '?':
case '!':
case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return specialVariable(ch);
+ return specialVariable(ch, quote == '"');
default:
StringBuffer sb = new StringBuffer().append((char) ch);
ch = ci.peekCh();
- while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= 'a' && ch <= 'z') || ch == '_') {
+ while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_') {
sb.append((char) ch);
ci.nextCh();
ch = ci.peekCh();
}
- VariableSlot var = variables.get(sb.toString());
- return (var != null) ? var.value : "";
+ return variable(sb.toString());
}
}
@@ -741,7 +731,7 @@
// Extract the word
word = sb.substring(i);
}
- String value = variable(parameter);
+ String value = dollarExpansion(new CharIterator(parameter), '\000');
switch (operator) {
case NONE:
return (value != null) ? value : "";
@@ -835,12 +825,6 @@
private String variable(String parameter) throws ShellSyntaxException {
- if (parameter.length() == 1) {
- String tmp = specialVariable(parameter.charAt(0));
- if (tmp != null) {
- return tmp;
- }
- }
if (BjorneToken.isName(parameter)) {
VariableSlot var = variables.get(parameter);
return (var != null) ? var.value : null;
@@ -854,58 +838,49 @@
}
}
- private String specialVariable(int ch) {
+ private String specialVariable(int ch, boolean inDoubleQuotes) {
switch (ch) {
case '$':
return Integer.toString(shellPid);
case '#':
return Integer.toString(args.size());
case '@':
- return concatenateArgs(false);
+ return concatenateArgs(false, inDoubleQuotes);
case '*':
- return concatenateArgs(false);
+ return concatenateArgs(true, inDoubleQuotes);
case '?':
return Integer.toString(lastReturnCode);
case '!':
return Integer.toString(lastAsyncPid);
case '-':
return options;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return argVariable(ch);
default:
return null;
}
}
- private String concatenateArgs(boolean isStar) {
- // FIXME - implement $@ versus $* differences; i.e. quoting and $IFS behavior.
+ private String concatenateArgs(boolean isStar, boolean inDoubleQuotes) {
StringBuilder sb = new StringBuilder();
for (String arg : args) {
if (sb.length() > 0) {
- sb.append(' ');
+ if (isStar || !inDoubleQuotes) {
+ sb.append(' ');
+ } else {
+ sb.append("\" \"");
+ }
}
sb.append(arg);
}
return sb.toString();
}
- private String argVariable(int argChar) {
- int argNo = argChar - '0';
+ private String argVariable(int argNo) {
if (argNo == 0) {
return command;
} else if (argNo <= args.size()) {
return args.get(argNo - 1);
} else {
- return "";
+ return null;
}
}
@@ -1115,92 +1090,4 @@
// TODO Auto-generated method stub
return false;
}
-
- private static class VariableSlot {
- public String value;
-
- public boolean exported;
-
- public VariableSlot(String value, boolean exported) {
- if (value == null) {
- throw new ShellFailureException("null value");
- }
- this.value = value;
- this.exported = exported;
- }
-
- public VariableSlot(VariableSlot other) {
- this.value = other.value;
- this.exported = other.exported;
- }
- }
-
- public static class StreamHolder {
- private CommandIO stream;
- private boolean isMine;
-
- public StreamHolder(CommandIO stream, boolean isMine) {
- this.stream = stream;
- this.isMine = isMine;
- }
-
- public StreamHolder(StreamHolder other) {
- this.stream = other.stream;
- this.isMine = false;
- }
-
- public CommandIO getStream() {
- return stream;
- }
-
- public void setStream(CommandIO stream, boolean isMine) {
- close();
- this.stream = stream;
- this.isMine = isMine;
- }
-
- public void close() {
- if (isMine) {
- try {
- isMine = false; // just in case we call close twice
- stream.close();
- } catch (IOException ex) {
- // FIXME - should we squash or report this?
- }
- }
- }
-
- public boolean isMine() {
- return isMine;
- }
- }
-
- private static class CharIterator {
- private CharSequence str;
- private int pos, start, limit;
-
- public CharIterator(CharSequence str) {
- this.str = str;
- this.start = pos = 0;
- this.limit = str.length();
- }
-
- public CharIterator(CharSequence str, int start, int limit) {
- this.str = str;
- this.start = pos = start;
- this.limit = limit;
- }
-
- public int nextCh() {
- return (pos >= limit) ? -1 : str.charAt(pos++);
- }
-
- public int peekCh() {
- return (pos >= limit) ? -1 : str.charAt(pos);
- }
-
- public int lastCh() {
- return (pos > start) ? str.charAt(pos - 1) : -1;
- }
- }
}
Added: trunk/shell/src/shell/org/jnode/shell/bjorne/CharIterator.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/CharIterator.java (rev 0)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/CharIterator.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2003-2009 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package org.jnode.shell.bjorne;
+
+class CharIterator {
+ private CharSequence str;
+ private int pos, start, limit;
+
+ public CharIterator(CharSequence str) {
+ this.str = str;
+ this.start = pos = 0;
+ this.limit = str.length();
+ }
+
+ public CharIterator(CharSequence str, int start, int limit) {
+ this.str = str;
+ this.start = pos = start;
+ this.limit = limit;
+ }
+
+ public int nextCh() {
+ return (pos >= limit) ? -1 : str.charAt(pos++);
+ }
+
+ public int peekCh() {
+ return (pos >= limit) ? -1 : str.charAt(pos);
+ }
+
+ public int lastCh() {
+ return (pos > start) ? str.charAt(pos - 1) : -1;
+ }
+}
\ No newline at end of file
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/ListCommandNode.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/ListCommandNode.java 2009-02-08 06:42:27 UTC (rev 5005)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/ListCommandNode.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -33,7 +33,6 @@
import org.jnode.shell.ShellException;
import org.jnode.shell.ShellFailureException;
import org.jnode.shell.ThreadExitListener;
-import org.jnode.shell.bjorne.BjorneContext.StreamHolder;
import org.jnode.shell.help.CompletionException;
import org.jnode.shell.io.CommandIO;
import org.jnode.shell.io.CommandInput;
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java 2009-02-08 06:42:27 UTC (rev 5005)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/SimpleCommandNode.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -68,7 +68,7 @@
@Override
public int execute(final BjorneContext context) throws ShellException {
- BjorneContext.StreamHolder[] holders = null;
+ StreamHolder[] holders = null;
int rc;
try {
BjorneToken[] words = getWords();
@@ -98,7 +98,7 @@
}
} finally {
if (holders != null) {
- for (BjorneContext.StreamHolder holder : holders) {
+ for (StreamHolder holder : holders) {
holder.close();
}
}
Added: trunk/shell/src/shell/org/jnode/shell/bjorne/StreamHolder.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/StreamHolder.java (rev 0)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/StreamHolder.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2003-2009 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package org.jnode.shell.bjorne;
+
+import java.io.IOException;
+
+import org.jnode.shell.io.CommandIO;
+
+public class StreamHolder {
+ CommandIO stream;
+ private boolean isMine;
+
+ public StreamHolder(CommandIO stream, boolean isMine) {
+ this.stream = stream;
+ this.isMine = isMine;
+ }
+
+ public StreamHolder(StreamHolder other) {
+ this.stream = other.stream;
+ this.isMine = false;
+ }
+
+ public CommandIO getStream() {
+ return stream;
+ }
+
+ public void setStream(CommandIO stream, boolean isMine) {
+ close();
+ this.stream = stream;
+ this.isMine = isMine;
+ }
+
+ public void close() {
+ if (isMine) {
+ try {
+ isMine = false; // just in case we call close twice
+ stream.close();
+ } catch (IOException ex) {
+ // FIXME - should we squash or report this?
+ }
+ }
+ }
+
+ public boolean isMine() {
+ return isMine;
+ }
+}
\ No newline at end of file
Added: trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java (rev 0)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2003-2009 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jnode.shell.bjorne;
+
+import org.jnode.shell.ShellFailureException;
+
+class VariableSlot {
+ public String value;
+
+ public boolean exported;
+
+ public VariableSlot(String value, boolean exported) {
+ if (value == null) {
+ throw new ShellFailureException("null value");
+ }
+ this.value = value;
+ this.exported = exported;
+ }
+
+ public VariableSlot(VariableSlot other) {
+ this.value = other.value;
+ this.exported = other.exported;
+ }
+}
\ No newline at end of file
Modified: trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTests.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTests.java 2009-02-08 06:42:27 UTC (rev 5005)
+++ trunk/shell/src/test/org/jnode/test/shell/bjorne/BjorneContextTests.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -31,6 +31,7 @@
import org.jnode.shell.ShellException;
import org.jnode.shell.bjorne.BjorneContext;
import org.jnode.shell.bjorne.BjorneToken;
+import org.jnode.shell.bjorne.StreamHolder;
public class BjorneContextTests extends TestCase {
@@ -121,7 +122,7 @@
}
public void testExpand14() throws ShellException {
- BjorneContext parentContext = new BjorneContext(null, new BjorneContext.StreamHolder[0]);
+ BjorneContext parentContext = new BjorneContext(null, new StreamHolder[0]);
parentContext.setVariable("A", "A");
BjorneContext context = new BjorneContext(parentContext);
List<BjorneToken> expansion = context.expandAndSplit("'$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-02-08 06:42:27 UTC (rev 5005)
+++ trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml 2009-02-08 08:01:48 UTC (rev 5006)
@@ -491,22 +491,34 @@
arg1 arg2
</output>
</testSpec>
- <testSpec title="set -x" command="test" runMode="AS_SCRIPT" rc="0">
+ <testSpec title="quote handling" command="test" runMode="AS_SCRIPT" rc="0">
<script>#!bjorne
set -x
echo a b
echo 'a b'
echo "a b"
+ echo $*
+ echo $@
+ echo "$*"
+ echo "$@"
</script>
<arg>arg1</arg>
<arg>arg2</arg>
<output>a b
a b
a b
+arg1 arg2
+arg1 arg2
+arg1 arg2
+arg1 arg2
</output>
<error> + echo a b
+ echo 'a b'
+ echo 'a b'
+ + echo arg1 arg2
+ + echo arg1 arg2
+ + echo 'arg1 arg2'
+ + echo arg1 arg2
</error>
</testSpec>
</testSet>
\ No newline at end of file
Modified: trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java 2009-02-08 06:42:27 UTC (rev 5005)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java 2009-02-08 08:01:48 UTC (rev 5006)
@@ -124,7 +124,6 @@
}
-
public TestSetSpecification loadTestSetSpecification(String specName, String base) throws Exception {
TestSpecificationParser parser = new TestSpecificationParser();
InputStream is = null;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|