| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library args.src.parser; | 5 library args.src.parser; |
| 6 | 6 |
| 7 import '../args.dart'; | 7 import '../args.dart'; |
| 8 | 8 |
| 9 final _SOLO_OPT = new RegExp(r'^-([a-zA-Z0-9])$'); | 9 final _SOLO_OPT = new RegExp(r'^-([a-zA-Z0-9])$'); |
| 10 final _ABBR_OPT = new RegExp(r'^-([a-zA-Z0-9]+)(.*)$'); | 10 final _ABBR_OPT = new RegExp(r'^-([a-zA-Z0-9]+)(.*)$'); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 if (rest != null) this.rest.addAll(rest); | 39 if (rest != null) this.rest.addAll(rest); |
| 40 } | 40 } |
| 41 | 41 |
| 42 /// The current argument being parsed. | 42 /// The current argument being parsed. |
| 43 String get current => args[0]; | 43 String get current => args[0]; |
| 44 | 44 |
| 45 /// Parses the arguments. This can only be called once. | 45 /// Parses the arguments. This can only be called once. |
| 46 ArgResults parse() { | 46 ArgResults parse() { |
| 47 var commandResults = null; | 47 var commandResults = null; |
| 48 | 48 |
| 49 // Initialize flags to their defaults. | |
| 50 grammar.options.forEach((name, option) { | |
| 51 if (option.allowMultiple) { | |
| 52 results[name] = []; | |
| 53 } else { | |
| 54 results[name] = option.defaultValue; | |
| 55 } | |
| 56 }); | |
| 57 | |
| 58 // Parse the args. | 49 // Parse the args. |
| 59 while (args.length > 0) { | 50 while (args.length > 0) { |
| 60 if (current == '--') { | 51 if (current == '--') { |
| 61 // Reached the argument terminator, so stop here. | 52 // Reached the argument terminator, so stop here. |
| 62 args.removeAt(0); | 53 args.removeAt(0); |
| 63 break; | 54 break; |
| 64 } | 55 } |
| 65 | 56 |
| 66 // Try to parse the current argument as a command. This happens before | 57 // Try to parse the current argument as a command. This happens before |
| 67 // options so that commands can have option-like names. | 58 // options so that commands can have option-like names. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 82 if (parseSoloOption()) continue; | 73 if (parseSoloOption()) continue; |
| 83 if (parseAbbreviation(this)) continue; | 74 if (parseAbbreviation(this)) continue; |
| 84 if (parseLongOption()) continue; | 75 if (parseLongOption()) continue; |
| 85 | 76 |
| 86 // This argument is neither option nor command, so stop parsing unless | 77 // This argument is neither option nor command, so stop parsing unless |
| 87 // the [allowTrailingOptions] option is set. | 78 // the [allowTrailingOptions] option is set. |
| 88 if (!grammar.allowTrailingOptions) break; | 79 if (!grammar.allowTrailingOptions) break; |
| 89 rest.add(args.removeAt(0)); | 80 rest.add(args.removeAt(0)); |
| 90 } | 81 } |
| 91 | 82 |
| 92 // Set unspecified multivalued arguments to their default value, | 83 // Invoke the callbacks. |
| 93 // if any, and invoke the callbacks. | |
| 94 grammar.options.forEach((name, option) { | 84 grammar.options.forEach((name, option) { |
| 95 if (option.allowMultiple && | 85 if (option.callback == null) return; |
| 96 results[name].length == 0 && | 86 option.callback(option.getOrDefault(results[name])); |
| 97 option.defaultValue != null) { | |
| 98 results[name].add(option.defaultValue); | |
| 99 } | |
| 100 if (option.callback != null) option.callback(results[name]); | |
| 101 }); | 87 }); |
| 102 | 88 |
| 103 // Add in the leftover arguments we didn't parse to the innermost command. | 89 // Add in the leftover arguments we didn't parse to the innermost command. |
| 104 rest.addAll(args); | 90 rest.addAll(args); |
| 105 args.clear(); | 91 args.clear(); |
| 106 return new ArgResults(results, commandName, commandResults, rest); | 92 return new ArgResults(grammar, results, commandName, commandResults, rest); |
| 107 } | 93 } |
| 108 | 94 |
| 109 /// Pulls the value for [option] from the second argument in [args]. | 95 /// Pulls the value for [option] from the second argument in [args]. |
| 110 /// | 96 /// |
| 111 /// Validates that there is a valid value there. | 97 /// Validates that there is a valid value there. |
| 112 void readNextArgAsValue(Option option) { | 98 void readNextArgAsValue(Option option) { |
| 113 // Take the option argument from the next command line arg. | 99 // Take the option argument from the next command line arg. |
| 114 validate(args.length > 0, | 100 validate(args.length > 0, |
| 115 'Missing argument for "${option.name}".'); | 101 'Missing argument for "${option.name}".'); |
| 116 | 102 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 250 } |
| 265 | 251 |
| 266 /// Validates and stores [value] as the value for [option]. | 252 /// Validates and stores [value] as the value for [option]. |
| 267 void setOption(Map results, Option option, value) { | 253 void setOption(Map results, Option option, value) { |
| 268 // See if it's one of the allowed values. | 254 // See if it's one of the allowed values. |
| 269 if (option.allowed != null) { | 255 if (option.allowed != null) { |
| 270 validate(option.allowed.any((allow) => allow == value), | 256 validate(option.allowed.any((allow) => allow == value), |
| 271 '"$value" is not an allowed value for option "${option.name}".'); | 257 '"$value" is not an allowed value for option "${option.name}".'); |
| 272 } | 258 } |
| 273 | 259 |
| 274 if (option.allowMultiple) { | 260 if (option.isMultiple) { |
| 275 results[option.name].add(value); | 261 var list = results.putIfAbsent(option.name, () => []); |
| 262 list.add(value); |
| 276 } else { | 263 } else { |
| 277 results[option.name] = value; | 264 results[option.name] = value; |
| 278 } | 265 } |
| 279 } | 266 } |
| 280 } | 267 } |
| OLD | NEW |