From aec8c7fadcc67a458d523c7dee15873fa8354afd Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Tue, 4 Nov 2008 17:34:34 +0000 Subject: [PATCH] [241072] - added command line parser utility and tests --- .../internal/core/CommonBuilder.java | 69 ++------ .../cdt/utils/CommandLineUtilTest.java | 152 ++++++++++++++++++ .../core/suite/AutomatedIntegrationSuite.java | 3 + .../eclipse/cdt/utils/CommandLineUtil.java | 122 ++++++++++++++ 4 files changed, 292 insertions(+), 54 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/CommandLineUtilTest.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java index 30541f04699..da03a84236d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java @@ -76,6 +76,7 @@ import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator2; import org.eclipse.cdt.newmake.core.IMakeBuilderInfo; import org.eclipse.cdt.newmake.internal.core.StreamMonitor; +import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; @@ -1897,21 +1898,12 @@ public class CommonBuilder extends ACBuilder { // Set the environment String[] env = calcEnvironment(builder); String[] buildArguments = targets; -// if (builder.isDefaultBuildCmd()) { -// if (!builder.isStopOnError()) { -// buildArguments = new String[targets.length + 1]; -// buildArguments[0] = "-k"; //$NON-NLS-1$ -// System.arraycopy(targets, 0, buildArguments, 1, targets.length); -// } -// } else { - String args = builder.getBuildArguments(); - if (args != null && !(args = args.trim()).equals("")) { //$NON-NLS-1$ - String[] newArgs = makeArray(args); - buildArguments = new String[targets.length + newArgs.length]; - System.arraycopy(newArgs, 0, buildArguments, 0, newArgs.length); - System.arraycopy(targets, 0, buildArguments, newArgs.length, targets.length); - } -// } + + String[] newArgs = argumentsToArray(builder.getBuildArguments()); + buildArguments = new String[targets.length + newArgs.length]; + System.arraycopy(newArgs, 0, buildArguments, 0, newArgs.length); + System.arraycopy(targets, 0, buildArguments, newArgs.length, targets.length); + // MakeRecon recon = new MakeRecon(buildCommand, buildArguments, env, workingDirectory, makeMonitor, cos); // recon.invokeMakeRecon(); // cos = recon; @@ -2060,50 +2052,19 @@ public class CommonBuilder extends ACBuilder { break; } - targetsArray = makeArray(targets); + targetsArray = argumentsToArray(targets); } return targetsArray; } - // Turn the string into an array. - private String[] makeArray(String string) { - string = string.trim(); - char[] array = string.toCharArray(); - ArrayList aList = new ArrayList(); - StringBuilder buffer = new StringBuilder(); - boolean inComment = false; - for (int i = 0; i < array.length; i++) { - char c = array[i]; - boolean needsToAdd = true; - if (array[i] == '"' || array[i] == '\'') { - if (i > 0 && array[i - 1] == '\\') { - inComment = false; - } else { - inComment = !inComment; - needsToAdd = false; // skip it - } - } - if (c == ' ' && !inComment) { - if (buffer.length() > 0){ - String str = buffer.toString().trim(); - if(str.length() > 0){ - aList.add(str); - } - } - buffer = new StringBuilder(); - } else { - if (needsToAdd) - buffer.append(c); - } - } - if (buffer.length() > 0){ - String str = buffer.toString().trim(); - if(str.length() > 0){ - aList.add(str); - } - } - return aList.toArray(new String[aList.size()]); + /** + * Parsing arguments in a shell style + * @param builder + * @return + */ + private String[] argumentsToArray(String args) { + return CommandLineUtil.argumentsToArray(args); } private void removeAllMarkers(IProject currProject) throws CoreException { 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 new file mode 100644 index 00000000000..4e4664857bb --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/CommandLineUtilTest.java @@ -0,0 +1,152 @@ +package org.eclipse.cdt.utils; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class CommandLineUtilTest extends TestCase { + + public static Test suite() { + return new TestSuite(CommandLineUtilTest.class); + } + public void testArgumentsToArraySimple() { + // [A=B C] + String[] args = CommandLineUtil.argumentsToArray("A=B C"); + assertEquals(2, args.length); + assertEquals("A=B", args[0]); + assertEquals("C", args[1]); + } + + public void testArgumentsToArraySpaces() { + // [A=B C] + String[] args = CommandLineUtil.argumentsToArray("A=B C"); + assertEquals(2, args.length); + assertEquals("A=B", args[0]); + assertEquals("C", args[1]); + } + + public void testArgumentsToArraySpaces2() { + // [ A=B C ] + String[] args = CommandLineUtil.argumentsToArray(" A=B C "); + assertEquals(2, args.length); + assertEquals("A=B", args[0]); + assertEquals("C", args[1]); + } + + public void testArgumentsToArrayDoubleQuotes() { + // [Arg="a b c"] + String[] args = CommandLineUtil.argumentsToArray("Arg=\"a b c\""); + assertEquals(1, args.length); + assertEquals("Arg=a b c", args[0]); + } + + public void testArgumentsToArrayDoubleQuotes2() { + // [Arg="\"quoted\""] + String[] args = CommandLineUtil.argumentsToArray("Arg=\"\\\"quoted\\\"\""); + assertEquals(1, args.length); + assertEquals("Arg=\"quoted\"", args[0]); + } + + public void testArgumentsToArraySingleQuotes() { + // [Arg='"quoted"'] + String[] args = CommandLineUtil.argumentsToArray("Arg='\"quoted\"'"); + assertEquals(1, args.length); + assertEquals("Arg=\"quoted\"", args[0]); + } + + public void testArgumentsToArrayQuote() { + // [\"] + String[] args = CommandLineUtil.argumentsToArray("\\\""); + assertEquals(1, args.length); + assertEquals("\"", args[0]); + } + + public void testArgumentsToArrayQuotSpaces() { + // [ \"] + String[] args = CommandLineUtil.argumentsToArray(" \\\""); + assertEquals(1, args.length); + assertEquals("\"", args[0]); + } + + public void testArgumentsToArrayOnlySpaces() { + // [" "] + String[] args = CommandLineUtil.argumentsToArray("\" \""); + assertEquals(1, args.length); + assertEquals(" ", args[0]); + } + + public void testArgumentsToArrayJumbledString() { + // ["a b"-c] + String[] args = CommandLineUtil.argumentsToArray("\"a b\"-c"); + assertEquals(1, args.length); + assertEquals("a b-c", args[0]); + } + + public void testArgumentsToArrayJumbledString2() { + // [x "a b"-c] + String[] args = CommandLineUtil.argumentsToArray(" x \"a b\"-c"); + assertEquals(2, args.length); + assertEquals("x", args[0]); + assertEquals("a b-c", args[1]); + } + + public void testArgumentsToArrayJumbledSQ() { + // [x' 'x y] + String[] args = CommandLineUtil.argumentsToArray("x' 'x y"); + assertEquals(2, args.length); + assertEquals("x x", args[0]); + assertEquals("y", args[1]); + } + + public void testArgumentsToArrayEmptyString() { + // [""] + String[] args = CommandLineUtil.argumentsToArray("\"\""); + assertEquals(1, args.length); + assertEquals("", args[0]); + } + + public void testArgumentsToArrayEmptyString2() { + // [''] + String[] args = CommandLineUtil.argumentsToArray("''"); + assertEquals(1, args.length); + assertEquals("", args[0]); + } + + public void testArgumentsToArrayEmpty3() { + // ['' a] + String[] args = CommandLineUtil.argumentsToArray("'' a"); + assertEquals(2, args.length); + assertEquals("", args[0]); + assertEquals("a", args[1]); + } + + public void testArgumentsToArrayQuot1() { + // ['"'] + String[] args = CommandLineUtil.argumentsToArray("'\"'"); + assertEquals(1, args.length); + assertEquals("\"", args[0]); + } + + public void testArgumentsToArrayQuot2() { + // ["\""] + String[] args = CommandLineUtil.argumentsToArray("\"\\\"\""); + assertEquals(1, args.length); + assertEquals("\"", args[0]); + } + + public void testArgumentsToArrayNull() { + // [] + String[] args = CommandLineUtil.argumentsToArray(null); + assertEquals(0, args.length); + } + public void testArgumentsToArrayEmpty() { + // [] + String[] args = CommandLineUtil.argumentsToArray(""); + assertEquals(0, args.length); + } + public void testArgumentsToArrayEmptySpaces() { + // [ ] + String[] args = CommandLineUtil.argumentsToArray(" "); + assertEquals(0, args.length); + } +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java index 66074479d89..6f05ed0db21 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java @@ -30,6 +30,8 @@ import org.eclipse.cdt.core.parser.tests.rewrite.RewriteTests; import org.eclipse.cdt.core.tests.templateengine.AllTemplateEngineTests; import org.eclipse.cdt.internal.index.tests.IndexTests; import org.eclipse.cdt.internal.pdom.tests.PDOMTests; +import org.eclipse.cdt.utils.CommandLineUtil; +import org.eclipse.cdt.utils.CommandLineUtilTest; /** * @author vhirsl @@ -66,6 +68,7 @@ public class AutomatedIntegrationSuite extends TestSuite { suite.addTest(StringBuilderTest.suite()); suite.addTest(AllLanguageTests.suite()); suite.addTest(RewriteTests.suite()); + suite.addTest(CommandLineUtilTest.suite()); // Add in PDOM tests suite.addTest(PDOMTests.suite()); 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 new file mode 100644 index 00000000000..dc2b67dfe85 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java @@ -0,0 +1,122 @@ +package org.eclipse.cdt.utils; + +import java.util.ArrayList; + +/** + * Utils to work with command line, parse arguments, etc. + * @since 5.1 + */ +public class CommandLineUtil { + + /** + * Parsing arguments in a shell 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[] argumentsToArray(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_SINGLE_QUOTES = 4; + 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: + switch (c) { + case ' ': + if (state == INITIAL) break; // ignore extra spaces + // add argument + state = INITIAL; + String arg = buffer.toString(); + buffer = new StringBuilder(); + aList.add(arg); + break; + case '\\': + state = ESCAPED; + break; + case '\'': + state = IN_SINGLE_QUOTES; + 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_SINGLE_QUOTES: + switch (c) { + case '\'': + state = IN_ARG; + break; + default: + buffer.append(c); + break; + } + break; + case IN_DOUBLE_QUOTES_ESCAPED: + switch (c) { + case '\"': + case '\\': + buffer.append(c); + break; + case 'n': + buffer.append('\n'); + break; + default: + buffer.append('\\'); + buffer.append(c); + break; + } + state = IN_DOUBLE_QUOTES; + break; + case ESCAPED: + buffer.append(c); + state = IN_ARG; + break; + } + } + + if (state!=INITIAL) { // this allow to process empty string as an argument + aList.add(buffer.toString()); + } + return aList.toArray(new String[aList.size()]); + } + +}