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:


  97         Pattern p = Pattern.compile(regexPattern);
  98         Matcher m = p.matcher(argString);
  99         while (m.find()) {
 100             int startPosition = m.start();
 101             int endPosition = m.end();
 102             if (startPosition > 0) {
 103                 /*
 104                  * It is an error if parsing skips over any part of argString.
 105                  */
 106                 throw new IllegalArgumentException
 107                     (MessageOutput.format("Illegal connector argument",
 108                                           argString));
 109             }
 110 
 111             String token = argString.substring(startPosition, endPosition);
 112             int index = token.indexOf('=');
 113             String name = token.substring(0, index);
 114             String value = token.substring(index + 1,
 115                                            token.length() - 1); // Remove comma delimiter
 116 
















 117             Connector.Argument argument = arguments.get(name);
 118             if (argument == null) {
 119                 throw new IllegalArgumentException
 120                     (MessageOutput.format("Argument is not defined for connector:",
 121                                           new Object [] {name, connector.name()}));
 122             }
 123             argument.setValue(value);
 124 
 125             argString = argString.substring(endPosition); // Remove what was just parsed...
 126             m = p.matcher(argString);                     //    and parse again on what is left.
 127         }
 128         if ((! argString.equals(",")) && (argString.length() > 0)) {
 129             /*
 130              * It is an error if any part of argString is left over,
 131              * unless it was empty to begin with.
 132              */
 133             throw new IllegalArgumentException
 134                 (MessageOutput.format("Illegal connector argument", argString));
 135         }
 136         return arguments;
 137     }
 138 














































































































































































 139     VMConnection(String connectSpec, int traceFlags) {
 140         String nameString;
 141         String argString;
 142         int index = connectSpec.indexOf(':');
 143         if (index == -1) {
 144             nameString = connectSpec;
 145             argString = "";
 146         } else {
 147             nameString = connectSpec.substring(0, index);
 148             argString = connectSpec.substring(index + 1);
 149         }
 150 
 151         connector = findConnector(nameString);
 152         if (connector == null) {
 153             throw new IllegalArgumentException
 154                 (MessageOutput.format("No connector named:", nameString));
 155         }
 156 
 157         connectorArgs = parseConnectorArgs(connector, argString);
 158         this.traceFlags = traceFlags;




  97         Pattern p = Pattern.compile(regexPattern);
  98         Matcher m = p.matcher(argString);
  99         while (m.find()) {
 100             int startPosition = m.start();
 101             int endPosition = m.end();
 102             if (startPosition > 0) {
 103                 /*
 104                  * It is an error if parsing skips over any part of argString.
 105                  */
 106                 throw new IllegalArgumentException
 107                     (MessageOutput.format("Illegal connector argument",
 108                                           argString));
 109             }
 110 
 111             String token = argString.substring(startPosition, endPosition);
 112             int index = token.indexOf('=');
 113             String name = token.substring(0, index);
 114             String value = token.substring(index + 1,
 115                                            token.length() - 1); // Remove comma delimiter
 116 
 117             /*
 118              *  unquote values for options (single and/or double quotes)
 119              *  needed for quote enclosed delimited substrings
 120              */
 121             if (name.equals("options")) {
 122                 StringBuilder sb = new StringBuilder();
 123                 for (String s : splitStringAtNonEnclosedWhiteSpace(value)) {
 124                     while (isEnclosed(s, "\"") || isEnclosed(s, "'")) {
 125                         s = s.substring(1, s.length() - 1);
 126                     }
 127                     sb.append(s);
 128                     sb.append(" ");
 129                 }
 130                 value = sb.toString();
 131             }
 132 
 133             Connector.Argument argument = arguments.get(name);
 134             if (argument == null) {
 135                 throw new IllegalArgumentException
 136                     (MessageOutput.format("Argument is not defined for connector:",
 137                                           new Object [] {name, connector.name()}));
 138             }
 139             argument.setValue(value);
 140 
 141             argString = argString.substring(endPosition); // Remove what was just parsed...
 142             m = p.matcher(argString);                     //    and parse again on what is left.
 143         }
 144         if ((! argString.equals(",")) && (argString.length() > 0)) {
 145             /*
 146              * It is an error if any part of argString is left over,
 147              * unless it was empty to begin with.
 148              */
 149             throw new IllegalArgumentException
 150                 (MessageOutput.format("Illegal connector argument", argString));
 151         }
 152         return arguments;
 153     }
 154 
 155     private static boolean isEnclosed(String value, String enclosingChar) {
 156         if (value.indexOf(enclosingChar) == 0) {
 157             int lastIndex = value.lastIndexOf(enclosingChar);
 158             if (lastIndex > 0 && lastIndex  == value.length() - 1) {
 159                 return true;
 160             }
 161         }
 162         return false;
 163     }
 164 
 165     private static ArrayList<String> splitStringAtNonEnclosedWhiteSpace(String value) throws IllegalArgumentException {
 166         ArrayList<String> al = new ArrayList<String>();
 167         char[] arr;
 168         int startPosition = 0;
 169         int endPosition = 0;
 170         final char SPACE = ' ';
 171         final char DOUBLEQ = '"';
 172         final char SINGLEQ = '\'';
 173         boolean activeEnclose = false;
 174         char enclosingTargetChar = '"';
 175 
 176         if (value == null) {
 177             throw new IllegalArgumentException
 178                 (MessageOutput.format("Illegal option values",
 179                     value));
 180         }
 181 
 182         //split parameter string into individual chars
 183         arr = value.toCharArray();
 184 
 185         for (int i = 0; i < arr.length; i++) {
 186             switch (arr[i]) {
 187                 case SPACE: {
 188                     // default is to do nothing for spaces
 189                     // just check if last in string
 190                     if (!isLastChar(arr, i)) {
 191                         //if not last, skip to next
 192                         continue;
 193                     } else {
 194                         //last char in string, need to end here
 195                         endPosition = i;
 196                         //break out for substring creation
 197                         break;
 198                     }
 199                 }
 200                 case DOUBLEQ: {
 201                     //is there an active enclose?
 202                     if (activeEnclose) {
 203                         //enclose is active
 204                         if (enclosingTargetChar != DOUBLEQ) {
 205                             //not our target, skip
 206                             continue;
 207                         }
 208                         //our enclosure target end
 209                         if (isNextCharWhitespace(arr, i)) {
 210                             //if whitespace peek next
 211                             //then a complete enclosing
 212                             endPosition = i;
 213                             activeEnclose = false;
 214                             //break out for substring creation
 215                             break;
 216                         }
 217                         // skip to next
 218                         continue;
 219                     }
 220                     // no active enclosing
 221                     if (isPreviousCharWhitespace(arr, i)) {
 222                         // start a new enclosing
 223                         startPosition = i;
 224                         //set up target char enclosing
 225                         enclosingTargetChar = DOUBLEQ;
 226                         // activate
 227                         activeEnclose = true;
 228                     }
 229                     //skip to next
 230                     continue;
 231                 }
 232                 case SINGLEQ: {
 233                     //an active enclose?
 234                     if (activeEnclose) {
 235                         //enclose is active
 236                         if (enclosingTargetChar != SINGLEQ) {
 237                             //not our target, continue
 238                             continue;
 239                         }
 240                         //our enclosure target end
 241                         if (isNextCharWhitespace(arr, i)) {
 242                             //if whitespace peek next
 243                             //then a complete enclosing
 244                             activeEnclose = false;
 245                             endPosition = i;
 246                             //break out for substring creation
 247                             break;
 248                         }
 249                         //skip to next
 250                         continue;
 251                     }
 252                     //no active enclosing
 253                     if (isPreviousCharWhitespace(arr, i)) {
 254                         // starting a new enclosing
 255                         startPosition = i;
 256                         //set up the target char for ending enclosing
 257                         enclosingTargetChar = SINGLEQ;
 258                         // activate
 259                         activeEnclose = true;
 260                     }
 261                     //skip to next
 262                     continue;
 263                 }
 264                 default: {
 265                     // normal non-space , non-" and non-' chars
 266                     if (!activeEnclose) {
 267                         // might be start of a string (if prev was whitespace)
 268                         if (isPreviousCharWhitespace(arr, i)) {
 269                             // no enclosure is active, start here
 270                             startPosition = i;
 271                             //skip to next
 272                             continue;
 273                         }
 274                         if (isNextCharWhitespace(arr, i)) {
 275                             endPosition = i;
 276                             //break for substring creation
 277                             break;
 278                         }
 279                     }
 280                     //skip to next
 281                     continue;
 282                 }
 283             }
 284             // break's end up here
 285             // handle the substring extraction
 286             if (startPosition > endPosition) {
 287                 throw new IllegalArgumentException
 288                     (MessageOutput.format("Illegal option values",
 289                         value));
 290             }
 291             // skip
 292             if (startPosition == endPosition) {
 293                 continue;
 294             }
 295 
 296             // take out substring from parameter string and add
 297             // to ArrayList<String>
 298             al.add(value.substring(startPosition, endPosition + 1));
 299             // set new start position
 300             startPosition = endPosition + 1;
 301         } // for loop
 302         // return split strings in arraylist
 303         return al;
 304     }
 305 
 306     static private boolean isPreviousCharWhitespace(char[] arr, int curr_pos) {
 307         return isCharWhitespace(arr, curr_pos - 1);
 308     }
 309 
 310     static private boolean isNextCharWhitespace(char[] arr, int curr_pos) {
 311         return isCharWhitespace(arr, curr_pos + 1);
 312     }
 313 
 314     static private boolean isCharWhitespace(char[] arr, int position) {
 315         if (position < 0 || position >= arr.length) {
 316             //outside arraybounds is considered an implicit space
 317             return true;
 318         }
 319         if (arr[position] == ' ') {
 320             return true;
 321         }
 322         return false;
 323     }
 324 
 325     static private boolean isLastChar(char[] arr, int position) {
 326         return (position + 1 == arr.length);
 327     }
 328 
 329     VMConnection(String connectSpec, int traceFlags) {
 330         String nameString;
 331         String argString;
 332         int index = connectSpec.indexOf(':');
 333         if (index == -1) {
 334             nameString = connectSpec;
 335             argString = "";
 336         } else {
 337             nameString = connectSpec.substring(0, index);
 338             argString = connectSpec.substring(index + 1);
 339         }
 340 
 341         connector = findConnector(nameString);
 342         if (connector == null) {
 343             throw new IllegalArgumentException
 344                 (MessageOutput.format("No connector named:", nameString));
 345         }
 346 
 347         connectorArgs = parseConnectorArgs(connector, argString);
 348         this.traceFlags = traceFlags;