changeset 1171:a695e0c1c6b1

7901362: JMH handling of quoted jvmArgs is broken Summary: Revisit the way we deal with quoted arguments.
author shade
date Tue, 31 Mar 2015 14:07:16 +0300
parents b33187f91f94
children fceec061059d
files jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java jmh-core/src/main/java/org/openjdk/jmh/util/Utils.java jmh-core/src/test/java/org/openjdk/jmh/util/TestUtil.java
diffstat 3 files changed, 60 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java	Tue Mar 31 11:14:26 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java	Tue Mar 31 14:07:16 2015 +0300
@@ -36,6 +36,7 @@
 import org.openjdk.jmh.util.HashMultimap;
 import org.openjdk.jmh.util.Multimap;
 import org.openjdk.jmh.util.Optional;
+import org.openjdk.jmh.util.Utils;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -417,23 +418,9 @@
 
             jvm = Optional.eitherOf(optJvm.value(set));
 
-            if (set.hasArgument(optJvmArgs)) {
-                jvmArgs = Optional.<Collection<String>>of(Arrays.asList(optJvmArgs.value(set).trim().split("[ ]+")));
-            } else {
-                jvmArgs = Optional.none();
-            }
-
-            if (set.hasArgument(optJvmArgsAppend)) {
-                jvmArgsAppend = Optional.<Collection<String>>of(Arrays.asList(optJvmArgsAppend.value(set).trim().split("[ ]+")));
-            } else {
-                jvmArgsAppend = Optional.none();
-            }
-
-            if (set.hasArgument(optJvmArgsPrepend)) {
-                jvmArgsPrepend = Optional.<Collection<String>>of(Arrays.asList(optJvmArgsPrepend.value(set).trim().split("[ ]+")));
-            } else {
-                jvmArgsPrepend = Optional.none();
-            }
+            jvmArgs = treatQuoted(set, optJvmArgs);
+            jvmArgsAppend = treatQuoted(set, optJvmArgsAppend);
+            jvmArgsPrepend = treatQuoted(set, optJvmArgsPrepend);
 
             if (set.hasArgument(optParams)) {
                 for (String p : optParams.values(set)) {
@@ -450,6 +437,23 @@
         }
     }
 
+    public Optional<Collection<String>> treatQuoted(OptionSet set, OptionSpec<String> spec) {
+        if (set.hasArgument(spec)) {
+            try {
+                List<String> vals = spec.values(set);
+                if (vals.size() != 1) {
+                    return Optional.<Collection<String>>of(vals);
+                } else {
+                    // Windows launcher somehow ends up here, fall-through to single value treatment
+                }
+            } catch (OptionException e) {
+                // only a single value, fall through
+            }
+            return Optional.of(Utils.splitQuotedEscape(spec.value(set)));
+        }
+        return Optional.none();
+    }
+
     public void showHelp() throws IOException {
         parser.printHelpOn(System.err);
     }
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/Utils.java	Tue Mar 31 11:14:26 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/Utils.java	Tue Mar 31 14:07:16 2015 +0300
@@ -93,6 +93,33 @@
         return join(Arrays.asList(src), delim);
     }
 
+    public static Collection<String> splitQuotedEscape(String src) {
+        List<String> results = new ArrayList<String>();
+
+        StringBuilder sb = new StringBuilder();
+        boolean escaped = false;
+        for (char ch : src.toCharArray()) {
+            if (ch == ' ' && !escaped) {
+                String s = sb.toString();
+                if (!s.isEmpty()) {
+                    results.add(s);
+                    sb = new StringBuilder();
+                }
+            } else if (ch == '\"') {
+                escaped ^= true;
+            } else {
+                sb.append(ch);
+            }
+        }
+
+        String s = sb.toString();
+        if (!s.isEmpty()) {
+            results.add(s);
+        }
+
+        return results;
+    }
+
     public static int sum(int[] arr) {
         int sum = 0;
         for (int i : arr) {
--- a/jmh-core/src/test/java/org/openjdk/jmh/util/TestUtil.java	Tue Mar 31 11:14:26 2015 +0300
+++ b/jmh-core/src/test/java/org/openjdk/jmh/util/TestUtil.java	Tue Mar 31 14:07:16 2015 +0300
@@ -27,6 +27,8 @@
 import junit.framework.Assert;
 import org.junit.Test;
 
+import java.util.Arrays;
+
 public class TestUtil {
 
     @Test
@@ -34,4 +36,14 @@
         Assert.assertFalse(Utils.getPid() == 0);
     }
 
+    @Test
+    public void testSplit() {
+        Assert.assertEquals(Arrays.asList("moo"), Utils.splitQuotedEscape("moo"));
+        Assert.assertEquals(Arrays.asList("moo", "bar"), Utils.splitQuotedEscape("moo bar"));
+        Assert.assertEquals(Arrays.asList("moo", "bar"), Utils.splitQuotedEscape("moo  bar"));
+        Assert.assertEquals(Arrays.asList("moo", "bar", "baz"), Utils.splitQuotedEscape("moo  bar baz"));
+        Assert.assertEquals(Arrays.asList("moo", "bar baz"), Utils.splitQuotedEscape("moo  \"bar baz\""));
+        Assert.assertEquals(Arrays.asList("moo", "-Dopt=bar baz"), Utils.splitQuotedEscape("moo  -Dopt=\"bar baz\""));
+    }
+
 }