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,10 +112,26 @@
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,10 +150,184 @@
(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) {