diff --git a/WHATSNEW b/WHATSNEW index f579ffb56..4d84668c5 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -25,6 +25,10 @@ Fixed bugs: * 's classpathref attribute was broken. +* would result in no command line argument, will now + be a single empty argument. Use if you need the + quotes literally. + Other changes: -------------- diff --git a/docs/manual/using.html b/docs/manual/using.html index e5fe44d7f..1a9b93eaf 100644 --- a/docs/manual/using.html +++ b/docs/manual/using.html @@ -431,10 +431,6 @@ that contain space characters, nested arg elements can be used.

characters. Exactly one of these. - - line - a space-delimited list of command-line arguments. - file The name of a file as a single command-line @@ -448,7 +444,17 @@ that contain space characters, nested arg elements can be used.

path separators and Ant will convert it to the platform's local conventions. + + line + a space-delimited list of command-line arguments. + + +

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.

+

Examples

   <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