|
From: <cr...@us...> - 2009-07-07 14:20:34
|
Revision: 5598
http://jnode.svn.sourceforge.net/jnode/?rev=5598&view=rev
Author: crawley
Date: 2009-07-07 14:07:37 +0000 (Tue, 07 Jul 2009)
Log Message:
-----------
Implement special handling of quoting in HERE document markers.
Modified Paths:
--------------
trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java
trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java
trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java
trunk/shell/src/shell/org/jnode/shell/bjorne/RedirectionNode.java
trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-07-07 10:50:37 UTC (rev 5597)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-07-07 14:07:37 UTC (rev 5598)
@@ -423,40 +423,55 @@
return wordTokens;
}
+ /**
+ * Do quote removal on a list of tokens
+ *
+ * @param wordTokens the tokens to be processed.
+ * @return the de-quoted tokens
+ */
private List<BjorneToken> dequote(List<BjorneToken> wordTokens) {
List<BjorneToken> resTokens = new LinkedList<BjorneToken>();
for (BjorneToken token : wordTokens) {
- String text = token.getText();
- int len = text.length();
- StringBuffer sb = new StringBuffer(len);
- int quote = 0;
- for (int i = 0; i < len; i++) {
- char ch = text.charAt(i);
- switch (ch) {
- case '"':
- case '\'':
- if (quote == 0) {
- quote = ch;
- } else if (quote == ch) {
- quote = 0;
- } else {
- sb.append(ch);
- }
- break;
- case '\\':
- if (i + 1 < len) {
- ch = text.charAt(++i);
- }
+ resTokens.add(token.remake(dequote(token.getText())));
+ }
+ return resTokens;
+ }
+
+ /**
+ * Do quote removal on a String
+ *
+ * @param text the text to be processed.
+ * @return the de-quoted text
+ */
+ static StringBuffer dequote(String text) {
+ int len = text.length();
+ StringBuffer sb = new StringBuffer(len);
+ int quote = 0;
+ for (int i = 0; i < len; i++) {
+ char ch = text.charAt(i);
+ switch (ch) {
+ case '"':
+ case '\'':
+ if (quote == 0) {
+ quote = ch;
+ } else if (quote == ch) {
+ quote = 0;
+ } else {
sb.append(ch);
- break;
- default:
- sb.append(ch);
- break;
- }
+ }
+ break;
+ case '\\':
+ if (i + 1 < len) {
+ ch = text.charAt(++i);
+ }
+ sb.append(ch);
+ break;
+ default:
+ sb.append(ch);
+ break;
}
- resTokens.add(token.remake(sb));
}
- return resTokens;
+ return sb;
}
/**
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java 2009-07-07 10:50:37 UTC (rev 5597)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java 2009-07-07 14:07:37 UTC (rev 5598)
@@ -766,6 +766,12 @@
this.allowLineBreaks = true;
}
+ /**
+ * Skip optional linebreaks.
+ * @param expectedSet the tokens expected after the line breaks
+ * @param needMore if {@code true} we need a token after the line breaks,
+ * otherwise, it is OK to have no more tokens.
+ */
private void doLineBreaks(long expectedSet, boolean needMore) throws ShellSyntaxException {
// NB: use tokens.peek() / next() rather than the wrappers here!!
this.allowLineBreaks = false;
@@ -800,23 +806,40 @@
}
}
+ /**
+ * Capture all current HERE documents, dealing with TAB stripping (if required)
+ * and recording on the relevant redirection object. We don't do expansions at
+ * this point, but we set the flag to say if expansion is required.
+ *
+ * @throws ShellSyntaxException
+ */
private void captureHereDocuments() throws ShellSyntaxException {
for (RedirectionNode redirection : hereRedirections) {
StringBuilder sb = new StringBuilder();
- String marker = redirection.getArg().getText();
+ String rawMarker = redirection.getArg().getText();
+ String marker = BjorneContext.dequote(rawMarker).toString();
boolean trimTabs = redirection.getRedirectionType() == TOK_DLESSDASH;
while (true) {
- String line = tokens.readHereLine(trimTabs);
+ String line = tokens.readRawLine();
if (line == null) {
throw new ShellSyntaxException("EOF reached while looking for '" +
marker + "' to end a HERE document");
}
+ if (trimTabs) {
+ int len = line.length();
+ int i;
+ for (i = 0; i < len && line.charAt(i) == '\t'; i++) { /**/ }
+ if (i > 0) {
+ line = line.substring(i);
+ }
+ }
if (line.equals(marker)) {
break;
}
sb.append(line).append('\n');
}
redirection.setHereDocument(sb.toString());
+ redirection.setHereDocumentExpandable(marker.equals(rawMarker));
}
hereRedirections.clear();
}
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java 2009-07-07 10:50:37 UTC (rev 5597)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java 2009-07-07 14:07:37 UTC (rev 5598)
@@ -222,11 +222,10 @@
* This method bypasses normal tokenization and reads a raw line of
* text up to the next NL (or the end of stream).
*
- * @param trimTabs if {@code true}, trim any leading TABs from the line
* @return the line read without the terminating NL. If we got an
* end of stream immediately, return {@code null}.
*/
- public String readHereLine(boolean trimTabs) {
+ public String readRawLine() {
StringBuilder sb = new StringBuilder(40);
while (true) {
int ch = nextCh();
@@ -235,11 +234,6 @@
return sb.toString();
case EOS:
return (sb.length() > 0) ? sb.toString() : null;
- case '\t':
- if (!trimTabs || sb.length() > 0) {
- sb.append('\t');
- }
- break;
default:
sb.append((char) ch);
}
Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/RedirectionNode.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/bjorne/RedirectionNode.java 2009-07-07 10:50:37 UTC (rev 5597)
+++ trunk/shell/src/shell/org/jnode/shell/bjorne/RedirectionNode.java 2009-07-07 14:07:37 UTC (rev 5598)
@@ -31,8 +31,7 @@
private boolean expandable = true;
- public RedirectionNode(final int redirectionType, BjorneToken io,
- BjorneToken arg) {
+ public RedirectionNode(final int redirectionType, BjorneToken io, BjorneToken arg) {
super();
this.redirectionType = redirectionType;
this.io = io;
@@ -78,4 +77,9 @@
public boolean isHereDocumentExpandable() {
return expandable;
}
+
+ public void setHereDocumentExpandable(boolean expandable) {
+ this.expandable = expandable;
+ }
+
}
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-07-07 10:50:37 UTC (rev 5597)
+++ trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml 2009-07-07 14:07:37 UTC (rev 5598)
@@ -735,6 +735,19 @@
Hi mum 5
</output>
</testSpec>
+ <testSpec title="here 4" command="test" runMode="AS_SCRIPT" rc="0">
+ <script>#!bjorne
+ for i in 1 2 3 4 5 ; do cat << "EOF" ; done
+Hi mum `echo $i`
+EOF
+ </script>
+ <output>Hi mum `echo $i`
+Hi mum `echo $i`
+Hi mum `echo $i`
+Hi mum `echo $i`
+Hi mum `echo $i`
+</output>
+ </testSpec>
<testSpec title="pipeline" command="test" runMode="AS_SCRIPT" rc="0">
<script>#!bjorne
echo > @TEMP_DIR@/1 Hi mum
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|