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 | ||||