diff --git a/WHATSNEW b/WHATSNEW
index f579ffb56..4d84668c5 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -25,6 +25,10 @@ Fixed bugs:
* arg elements can be used.
arg elements can be used.
path separators and Ant will convert it to the platform's local
conventions.It is highly recommended to avoid the line version
+when possible. Ant will try to split the command line in a way
+similar to what a (Unix) shell would do, but may create something that
+is very different from what you expect under some circumstances.
<arg value="-l -a"/>
diff --git a/src/main/org/apache/tools/ant/types/Commandline.java b/src/main/org/apache/tools/ant/types/Commandline.java
index 32b0cfd97..c651b17a4 100644
--- a/src/main/org/apache/tools/ant/types/Commandline.java
+++ b/src/main/org/apache/tools/ant/types/Commandline.java
@@ -356,12 +356,14 @@ public class Commandline implements Cloneable {
StringTokenizer tok = new StringTokenizer(to_process, "\"\' ", true);
Vector v = new Vector();
StringBuffer current = new StringBuffer();
+ boolean lastTokenHasBeenQuoted = false;
while (tok.hasMoreTokens()) {
String nextTok = tok.nextToken();
switch (state) {
case inQuote:
if ("\'".equals(nextTok)) {
+ lastTokenHasBeenQuoted = true;
state = normal;
} else {
current.append(nextTok);
@@ -369,6 +371,7 @@ public class Commandline implements Cloneable {
break;
case inDoubleQuote:
if ("\"".equals(nextTok)) {
+ lastTokenHasBeenQuoted = true;
state = normal;
} else {
current.append(nextTok);
@@ -380,18 +383,19 @@ public class Commandline implements Cloneable {
} else if ("\"".equals(nextTok)) {
state = inDoubleQuote;
} else if (" ".equals(nextTok)) {
- if (current.length() != 0) {
+ if (lastTokenHasBeenQuoted || current.length() != 0) {
v.addElement(current.toString());
current.setLength(0);
}
} else {
current.append(nextTok);
}
+ lastTokenHasBeenQuoted = false;
break;
}
}
- if (current.length() != 0) {
+ if (lastTokenHasBeenQuoted || current.length() != 0) {
v.addElement(current.toString());
}
diff --git a/src/testcases/org/apache/tools/ant/types/CommandlineTest.java b/src/testcases/org/apache/tools/ant/types/CommandlineTest.java
index 67c92319f..334ed9797 100644
--- a/src/testcases/org/apache/tools/ant/types/CommandlineTest.java
+++ b/src/testcases/org/apache/tools/ant/types/CommandlineTest.java
@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
+ * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -118,6 +118,31 @@ public class CommandlineTest extends TestCase {
assertEquals("case with quoted whitespace", 4, s.length);
assertEquals("backslash included", "2\\", s[1]);
+ // "" should become a single empty argument, same for ''
+ // PR 5906
+ s = Commandline.translateCommandline("\"\" a");
+ assertEquals("Doublequoted null arg prepend", 2, s.length);
+ assertEquals("Doublequoted null arg prepend", "", s[0]);
+ assertEquals("Doublequoted null arg prepend", "a", s[1]);
+ s = Commandline.translateCommandline("a \"\"");
+ assertEquals("Doublequoted null arg append", 2, s.length);
+ assertEquals("Doublequoted null arg append", "a", s[0]);
+ assertEquals("Doublequoted null arg append", "", s[1]);
+ s = Commandline.translateCommandline("\"\"");
+ assertEquals("Doublequoted null arg", 1, s.length);
+ assertEquals("Doublequoted null arg", "", s[0]);
+
+ s = Commandline.translateCommandline("\'\' a");
+ assertEquals("Singlequoted null arg prepend", 2, s.length);
+ assertEquals("Singlequoted null arg prepend", "", s[0]);
+ assertEquals("Singlequoted null arg prepend", "a", s[1]);
+ s = Commandline.translateCommandline("a \'\'");
+ assertEquals("Singlequoted null arg append", 2, s.length);
+ assertEquals("Singlequoted null arg append", "a", s[0]);
+ assertEquals("Singlequoted null arg append", "", s[1]);
+ s = Commandline.translateCommandline("\'\'");
+ assertEquals("Singlequoted null arg", 1, s.length);
+ assertEquals("Singlequoted null arg", "", s[0]);
// now to the expected failures