src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java

Print this page
rev 5157 : 7154809: JDI: update JDI/JDB debugee commandline option parsing (allow
nested comma delimited options)
Summary: update debugee commandline parsing to allow for delimited
suboptions
Reviewed-by:

*** 112,121 **** --- 112,137 ---- int index = token.indexOf('='); String name = token.substring(0, index); String value = token.substring(index + 1, token.length() - 1); // Remove comma delimiter + /* + * unquote values for options (single and/or double quotes) + * 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 (MessageOutput.format("Argument is not defined for connector:", new Object [] {name, connector.name()}));
*** 134,143 **** --- 150,333 ---- (MessageOutput.format("Illegal connector argument", argString)); } 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 ArrayList<String> splitStringAtNonEnclosedWhiteSpace(String value) throws IllegalArgumentException { + ArrayList<String> al = new ArrayList<String>(); + char[] arr; + int startPosition = 0; + int endPosition = 0; + final char SPACE = ' '; + final char DOUBLEQ = '"'; + final char SINGLEQ = '\''; + boolean activeEnclose = false; + char enclosingTargetChar = '"'; + + if (value == null) { + throw new IllegalArgumentException + (MessageOutput.format("Illegal option values", + value)); + } + + //split parameter string into individual chars + arr = value.toCharArray(); + + for (int i = 0; i < arr.length; i++) { + switch (arr[i]) { + case SPACE: { + // default is to do nothing for spaces + // just check if last in string + if (!isLastChar(arr, i)) { + //if not last, skip to next + continue; + } else { + //last char in string, need to end here + endPosition = i; + //break out for substring creation + break; + } + } + case DOUBLEQ: { + //is there an active enclose? + if (activeEnclose) { + //enclose is active + if (enclosingTargetChar != DOUBLEQ) { + //not our target, skip + continue; + } + //our enclosure target end + if (isNextCharWhitespace(arr, i)) { + //if whitespace peek next + //then a complete enclosing + endPosition = i; + activeEnclose = false; + //break out for substring creation + break; + } + // skip to next + continue; + } + // no active enclosing + if (isPreviousCharWhitespace(arr, i)) { + // start a new enclosing + startPosition = i; + //set up target char enclosing + enclosingTargetChar = DOUBLEQ; + // activate + activeEnclose = true; + } + //skip to next + continue; + } + case SINGLEQ: { + //an active enclose? + if (activeEnclose) { + //enclose is active + if (enclosingTargetChar != SINGLEQ) { + //not our target, continue + continue; + } + //our enclosure target end + if (isNextCharWhitespace(arr, i)) { + //if whitespace peek next + //then a complete enclosing + activeEnclose = false; + endPosition = i; + //break out for substring creation + break; + } + //skip to next + continue; + } + //no active enclosing + if (isPreviousCharWhitespace(arr, i)) { + // starting a new enclosing + startPosition = i; + //set up the target char for ending enclosing + enclosingTargetChar = SINGLEQ; + // activate + activeEnclose = true; + } + //skip to next + continue; + } + default: { + // normal non-space , non-" and non-' chars + if (!activeEnclose) { + // might be start of a string (if prev was whitespace) + if (isPreviousCharWhitespace(arr, i)) { + // no enclosure is active, start here + startPosition = i; + //skip to next + continue; + } + if (isNextCharWhitespace(arr, i)) { + endPosition = i; + //break for substring creation + break; + } + } + //skip to next + continue; + } + } + // break's end up here + // handle the substring extraction + if (startPosition > endPosition) { + throw new IllegalArgumentException + (MessageOutput.format("Illegal option values", + value)); + } + // skip + if (startPosition == endPosition) { + continue; + } + + // take out substring from parameter string and add + // to ArrayList<String> + al.add(value.substring(startPosition, endPosition + 1)); + // set new start position + startPosition = endPosition + 1; + } // for loop + // return split strings in arraylist + 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 position) { + if (position < 0 || position >= arr.length) { + //outside arraybounds is considered an implicit space + return true; + } + if (arr[position] == ' ') { + return true; + } + return false; + } + + static private boolean isLastChar(char[] arr, int position) { + return (position + 1 == arr.length); + } + VMConnection(String connectSpec, int traceFlags) { String nameString; String argString; int index = connectSpec.indexOf(':'); if (index == -1) {