diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/CommandLineUtilTest.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/CommandLineUtilTest.java index f8b5e334a83..729d1ae3ed9 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/CommandLineUtilTest.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/CommandLineUtilTest.java @@ -11,9 +11,15 @@ public class CommandLineUtilTest extends TestCase { } private String[] parse(String line) { + return CommandLineUtil.argumentsToArrayUnixStyle(line); + } + private String[] parseWin(String line) { + return CommandLineUtil.argumentsToArrayWindowsStyle(line); + } + private String[] parseU(String line) { return CommandLineUtil.argumentsToArray(line); } - + public void testArgumentsToArraySimple() { String[] args = parse("A=B C"); assertEquals(2, args.length); @@ -166,4 +172,43 @@ public class CommandLineUtilTest extends TestCase { assertEquals(1, args.length); assertEquals("a\nb", args[0]); } + + public void testArgumentsToArraySimpleWin() { + String[] args = parseWin("A=B C"); + assertEquals(2, args.length); + assertEquals("A=B", args[0]); + assertEquals("C", args[1]); + } + + public void testArgumentsToArrayWindowsFiles() { + String[] args = parseWin("my\\file\\path"); + assertEquals(1, args.length); + assertEquals("my\\file\\path", args[0]); + } + + public void testArgumentsToArrayWindowsSpaces() { + String[] args = parseWin("\"my\\file\\path space\""); + assertEquals(1, args.length); + assertEquals("my\\file\\path space", args[0]); + } + + public void testArgumentsToArrayWindowsEmpty() { + String[] args = parseWin("\"\""); + assertEquals(1, args.length); + assertEquals("", args[0]); + } + public void testArgumentsToArrayWindowsQuotes() { + String[] args = parseWin("\\\"a b\\\""); + assertEquals(2, args.length); + assertEquals("\"a", args[0]); + assertEquals("b\"", args[1]); + } + + public void testArgumentsToArraySimpleUniversal() { + String[] args = parseU("A=B C D"); + assertEquals(3, args.length); + assertEquals("A=B", args[0]); + assertEquals("C", args[1]); + assertEquals("D", args[2]); + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java index 99cc09d30da..86a28bb5305 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java @@ -2,6 +2,8 @@ package org.eclipse.cdt.utils; import java.util.ArrayList; +import org.eclipse.osgi.service.environment.Constants; + /** * Utilities to work with command line, parse arguments, etc. * @noextend This class is not intended to be subclassed by clients. @@ -9,7 +11,20 @@ import java.util.ArrayList; * @since 5.1 */ public class CommandLineUtil { - + + public static String[] argumentsToArray(String line) { + boolean osWin; + try { + osWin = Platform.getOS().equals(Constants.OS_WIN32); + } catch (Exception e) { + osWin = false; + } + if (osWin) { + return argumentsToArrayWindowsStyle(line); + } else { + return argumentsToArrayUnixStyle(line); + } + } /** * Parsing arguments in a shell style. * i.e. @@ -23,7 +38,7 @@ public class CommandLineUtil { * @param line * @return array of arguments, or empty array if line is null or empty */ - public static String[] argumentsToArray(String line) { + public static String[] argumentsToArrayUnixStyle(String line) { final int INITIAL = 0; final int IN_DOUBLE_QUOTES = 1; final int IN_DOUBLE_QUOTES_ESCAPED = 2; @@ -122,4 +137,109 @@ public class CommandLineUtil { } return aList.toArray(new String[aList.size()]); } + + + /** + * Parsing arguments in a cmd style. + * i.e. + * + * ["a b c" d] -> [[a b c],[d]] + * [a d] -> [[a],[d]] + * ['"quoted"'] -> [['quoted']] + * [\\ \" \a] -> [[\\],["],[\a]] + * ["str\\str\a"] -> [[str\\str\a]] + * + * @param line + * @return array of arguments, or empty array if line is null or empty + */ + public static String[] argumentsToArrayWindowsStyle(String line) { + final int INITIAL = 0; + final int IN_DOUBLE_QUOTES = 1; + final int IN_DOUBLE_QUOTES_ESCAPED = 2; + final int ESCAPED = 3; + final int IN_ARG = 5; + + if (line == null) { + line = ""; //$NON-NLS-1$ + } + + char[] array = line.trim().toCharArray(); + ArrayList aList = new ArrayList(); + StringBuilder buffer = new StringBuilder(); + int state = INITIAL; + for (int i = 0; i < array.length; i++) { + char c = array[i]; + + switch (state) { + case IN_ARG: + // fall through + case INITIAL: + if (Character.isWhitespace(c)) { + if (state == INITIAL) break; // ignore extra spaces + // add argument + state = INITIAL; + String arg = buffer.toString(); + buffer = new StringBuilder(); + aList.add(arg); + } else { + switch (c) { + case '\\': + state = ESCAPED; + break; + case '\"': + state = IN_DOUBLE_QUOTES; + break; + default: + state = IN_ARG; + buffer.append(c); + break; + } + } + break; + case IN_DOUBLE_QUOTES: + switch (c) { + case '\\': + state = IN_DOUBLE_QUOTES_ESCAPED; + break; + case '\"': + state = IN_ARG; + break; + default: + buffer.append(c); + break; + } + break; + case IN_DOUBLE_QUOTES_ESCAPED: + switch (c) { + case '\"': + buffer.append(c); + break; + default: + buffer.append('\\'); + buffer.append(c); + break; + } + state = IN_DOUBLE_QUOTES; + break; + case ESCAPED: + state = IN_ARG; + switch (c) { + case ' ': + case '\"': + buffer.append(c); + break; + default: + buffer.append('\\'); + buffer.append(c); + break; + } + break; + } + } + + if (state != INITIAL) { // this allow to process empty string as an argument + aList.add(buffer.toString()); + } + return aList.toArray(new String[aList.size()]); + } }