PR: 5906 Don't use <arg line="..." />! git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273209 13f79535-47bb-0310-9956-ffa450edef68master
@@ -25,6 +25,10 @@ Fixed bugs: | |||||
* <property>'s classpathref attribute was broken. | * <property>'s classpathref attribute was broken. | ||||
* <arg line="''" /> would result in no command line argument, will now | |||||
be a single empty argument. Use <arg value="''"/> if you need the | |||||
quotes literally. | |||||
Other changes: | Other changes: | ||||
-------------- | -------------- | ||||
@@ -431,10 +431,6 @@ that contain space characters, nested <code>arg</code> elements can be used.</p> | |||||
characters.</td> | characters.</td> | ||||
<td align="center" rowspan="4">Exactly one of these.</td> | <td align="center" rowspan="4">Exactly one of these.</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">line</td> | |||||
<td valign="top">a space-delimited list of command-line arguments.</td> | |||||
</tr> | |||||
<tr> | <tr> | ||||
<td valign="top">file</td> | <td valign="top">file</td> | ||||
<td valign="top">The name of a file as a single command-line | <td valign="top">The name of a file as a single command-line | ||||
@@ -448,7 +444,17 @@ that contain space characters, nested <code>arg</code> elements can be used.</p> | |||||
path separators and Ant will convert it to the platform's local | path separators and Ant will convert it to the platform's local | ||||
conventions.</td> | conventions.</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">line</td> | |||||
<td valign="top">a space-delimited list of command-line arguments.</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<p>It is highly recommended to avoid the <code>line</code> 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.</p> | |||||
<h4>Examples</h4> | <h4>Examples</h4> | ||||
<blockquote><pre> | <blockquote><pre> | ||||
<arg value="-l -a"/> | <arg value="-l -a"/> | ||||
@@ -356,12 +356,14 @@ public class Commandline implements Cloneable { | |||||
StringTokenizer tok = new StringTokenizer(to_process, "\"\' ", true); | StringTokenizer tok = new StringTokenizer(to_process, "\"\' ", true); | ||||
Vector v = new Vector(); | Vector v = new Vector(); | ||||
StringBuffer current = new StringBuffer(); | StringBuffer current = new StringBuffer(); | ||||
boolean lastTokenHasBeenQuoted = false; | |||||
while (tok.hasMoreTokens()) { | while (tok.hasMoreTokens()) { | ||||
String nextTok = tok.nextToken(); | String nextTok = tok.nextToken(); | ||||
switch (state) { | switch (state) { | ||||
case inQuote: | case inQuote: | ||||
if ("\'".equals(nextTok)) { | if ("\'".equals(nextTok)) { | ||||
lastTokenHasBeenQuoted = true; | |||||
state = normal; | state = normal; | ||||
} else { | } else { | ||||
current.append(nextTok); | current.append(nextTok); | ||||
@@ -369,6 +371,7 @@ public class Commandline implements Cloneable { | |||||
break; | break; | ||||
case inDoubleQuote: | case inDoubleQuote: | ||||
if ("\"".equals(nextTok)) { | if ("\"".equals(nextTok)) { | ||||
lastTokenHasBeenQuoted = true; | |||||
state = normal; | state = normal; | ||||
} else { | } else { | ||||
current.append(nextTok); | current.append(nextTok); | ||||
@@ -380,18 +383,19 @@ public class Commandline implements Cloneable { | |||||
} else if ("\"".equals(nextTok)) { | } else if ("\"".equals(nextTok)) { | ||||
state = inDoubleQuote; | state = inDoubleQuote; | ||||
} else if (" ".equals(nextTok)) { | } else if (" ".equals(nextTok)) { | ||||
if (current.length() != 0) { | |||||
if (lastTokenHasBeenQuoted || current.length() != 0) { | |||||
v.addElement(current.toString()); | v.addElement(current.toString()); | ||||
current.setLength(0); | current.setLength(0); | ||||
} | } | ||||
} else { | } else { | ||||
current.append(nextTok); | current.append(nextTok); | ||||
} | } | ||||
lastTokenHasBeenQuoted = false; | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (current.length() != 0) { | |||||
if (lastTokenHasBeenQuoted || current.length() != 0) { | |||||
v.addElement(current.toString()); | v.addElement(current.toString()); | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* The Apache Software License, Version 1.1 | * 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. | * reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * 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("case with quoted whitespace", 4, s.length); | ||||
assertEquals("backslash included", "2\\", s[1]); | 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 | // now to the expected failures | ||||