7154809: JDI: update JDI/JDB debugee commandline option parsing
authormgronlun
Tue, 10 Apr 2012 10:32:00 +0200
changeset 12424 32365a68919e
parent 12423 a69d7fadb9f8
child 12425 b0f67d3873ea
7154809: JDI: update JDI/JDB debugee commandline option parsing Summary: update debugee commandline parsing Reviewed-by: dcubed, dsamersoff, sla
jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java
--- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java	Tue Apr 10 12:15:03 2012 +0800
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java	Tue Apr 10 10:32:00 2012 +0200
@@ -114,6 +114,23 @@
             String value = token.substring(index + 1,
                                            token.length() - 1); // Remove comma delimiter
 
+            /*
+             * for values enclosed in quotes (single and/or double quotes)
+             * strip off enclosing quote chars
+             * needed for quote enclosed delimited substrings
+             */
+            if (name.equals("options")) {
+                StringBuilder sb = new StringBuilder();
+                for (String s : splitStringAtNonEnclosedWhiteSpace(value)) {
+                    while (isEnclosed(s, "\"") || isEnclosed(s, "'")) {
+                        s = s.substring(1, s.length() - 1);
+                    }
+                    sb.append(s);
+                    sb.append(" ");
+                }
+                value = sb.toString();
+            }
+
             Connector.Argument argument = arguments.get(name);
             if (argument == null) {
                 throw new IllegalArgumentException
@@ -136,6 +153,152 @@
         return arguments;
     }
 
+    private static boolean isEnclosed(String value, String enclosingChar) {
+        if (value.indexOf(enclosingChar) == 0) {
+            int lastIndex = value.lastIndexOf(enclosingChar);
+            if (lastIndex > 0 && lastIndex  == value.length() - 1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static List<String> splitStringAtNonEnclosedWhiteSpace(String value) throws IllegalArgumentException {
+        List<String> al = new ArrayList<String>();
+        char[] arr;
+        int startPosition = 0;
+        int endPosition = 0;
+        final char SPACE = ' ';
+        final char DOUBLEQ = '"';
+        final char SINGLEQ = '\'';
+
+        /*
+         * An "open" or "active" enclosing state is where
+         * the first valid start quote qualifier is found,
+         * and there is a search in progress for the
+         * relevant end matching quote
+         *
+         * enclosingTargetChar set to SPACE
+         * is used to signal a non open enclosing state
+         */
+        char enclosingTargetChar = SPACE;
+
+        if (value == null) {
+            throw new IllegalArgumentException
+                (MessageOutput.format("value string is null"));
+        }
+
+        // split parameter string into individual chars
+        arr = value.toCharArray();
+
+        for (int i = 0; i < arr.length; i++) {
+            switch (arr[i]) {
+                case SPACE: {
+                    // do nothing for spaces
+                    // unless last in array
+                    if (isLastChar(arr, i)) {
+                        endPosition = i;
+                        // break for substring creation
+                        break;
+                    }
+                    continue;
+                }
+                case DOUBLEQ:
+                case SINGLEQ: {
+                    if (enclosingTargetChar == arr[i]) {
+                        // potential match to close open enclosing
+                        if (isNextCharWhitespace(arr, i)) {
+                            // if peek next is whitespace
+                            // then enclosing is a valid substring
+                            endPosition = i;
+                            // reset enclosing target char
+                            enclosingTargetChar = SPACE;
+                            // break for substring creation
+                            break;
+                        }
+                    }
+                    if (enclosingTargetChar == SPACE) {
+                        // no open enclosing state
+                        // handle as normal char
+                        if (isPreviousCharWhitespace(arr, i)) {
+                            startPosition = i;
+                            // peek forward for end candidates
+                            if (value.indexOf(arr[i], i + 1) >= 0) {
+                                // set open enclosing state by
+                                // setting up the target char
+                                enclosingTargetChar = arr[i];
+                            } else {
+                                // no more target chars left to match
+                                // end enclosing, handle as normal char
+                                if (isNextCharWhitespace(arr, i)) {
+                                    endPosition = i;
+                                    // break for substring creation
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    continue;
+                }
+                default: {
+                    // normal non-space, non-" and non-' chars
+                    if (enclosingTargetChar == SPACE) {
+                        // no open enclosing state
+                        if (isPreviousCharWhitespace(arr, i)) {
+                            // start of space delim substring
+                            startPosition = i;
+                        }
+                        if (isNextCharWhitespace(arr, i)) {
+                            // end of space delim substring
+                            endPosition = i;
+                            // break for substring creation
+                            break;
+                        }
+                    }
+                    continue;
+                }
+            }
+
+            // break's end up here
+            if (startPosition > endPosition) {
+                throw new IllegalArgumentException
+                    (MessageOutput.format("Illegal option values"));
+            }
+
+            // extract substring and add to List<String>
+            al.add(value.substring(startPosition, ++endPosition));
+
+            // set new start position
+            i = startPosition = endPosition;
+
+        } // for loop
+
+        return al;
+    }
+
+    static private boolean isPreviousCharWhitespace(char[] arr, int curr_pos) {
+        return isCharWhitespace(arr, curr_pos - 1);
+    }
+
+    static private boolean isNextCharWhitespace(char[] arr, int curr_pos) {
+        return isCharWhitespace(arr, curr_pos + 1);
+    }
+
+    static private boolean isCharWhitespace(char[] arr, int pos) {
+        if (pos < 0 || pos >= arr.length) {
+            // outside arraybounds is considered an implicit space
+            return true;
+        }
+        if (arr[pos] == ' ') {
+            return true;
+        }
+        return false;
+    }
+
+    static private boolean isLastChar(char[] arr, int pos) {
+        return (pos + 1 == arr.length);
+    }
+
     VMConnection(String connectSpec, int traceFlags) {
         String nameString;
         String argString;