| 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 'arg_parser.dart'; | 7 import 'arg_parser.dart'; |
| 8 import 'arg_results.dart'; | 8 import 'arg_results.dart'; |
| 9 import 'option.dart'; | 9 import 'option.dart'; |
| 10 | 10 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 if (option == null) { | 124 if (option == null) { |
| 125 // Walk up to the parent command if possible. | 125 // Walk up to the parent command if possible. |
| 126 validate( | 126 validate( |
| 127 parent != null, 'Could not find an option or flag "-${soloOpt[1]}".'); | 127 parent != null, 'Could not find an option or flag "-${soloOpt[1]}".'); |
| 128 return parent.parseSoloOption(); | 128 return parent.parseSoloOption(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 args.removeAt(0); | 131 args.removeAt(0); |
| 132 | 132 |
| 133 if (option.isFlag) { | 133 if (option.isFlag) { |
| 134 setOption(results, option, true); | 134 setFlag(results, option, true); |
| 135 } else { | 135 } else { |
| 136 readNextArgAsValue(option); | 136 readNextArgAsValue(option); |
| 137 } | 137 } |
| 138 | 138 |
| 139 return true; | 139 return true; |
| 140 } | 140 } |
| 141 | 141 |
| 142 /// Tries to parse the current argument as a series of collapsed abbreviations | 142 /// Tries to parse the current argument as a series of collapsed abbreviations |
| 143 /// (like "-abc") or a single abbreviation with the value directly attached | 143 /// (like "-abc") or a single abbreviation with the value directly attached |
| 144 /// to it (like "-mrelease"). | 144 /// to it (like "-mrelease"). |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 parent != null, 'Could not find an option with short name "-$c".'); | 189 parent != null, 'Could not find an option with short name "-$c".'); |
| 190 parent.parseShortFlag(c); | 190 parent.parseShortFlag(c); |
| 191 return; | 191 return; |
| 192 } | 192 } |
| 193 | 193 |
| 194 // In a list of short options, only the first can be a non-flag. If | 194 // In a list of short options, only the first can be a non-flag. If |
| 195 // we get here we've checked that already. | 195 // we get here we've checked that already. |
| 196 validate( | 196 validate( |
| 197 option.isFlag, 'Option "-$c" must be a flag to be in a collapsed "-".'); | 197 option.isFlag, 'Option "-$c" must be a flag to be in a collapsed "-".'); |
| 198 | 198 |
| 199 setOption(results, option, true); | 199 setFlag(results, option, true); |
| 200 } | 200 } |
| 201 | 201 |
| 202 /// Tries to parse the current argument as a long-form named option, which | 202 /// Tries to parse the current argument as a long-form named option, which |
| 203 /// may include a value like "--mode=release" or "--mode release". | 203 /// may include a value like "--mode=release" or "--mode release". |
| 204 bool parseLongOption() { | 204 bool parseLongOption() { |
| 205 var longOpt = _LONG_OPT.firstMatch(current); | 205 var longOpt = _LONG_OPT.firstMatch(current); |
| 206 if (longOpt == null) return false; | 206 if (longOpt == null) return false; |
| 207 | 207 |
| 208 var name = longOpt[1]; | 208 var name = longOpt[1]; |
| 209 var option = grammar.options[name]; | 209 var option = grammar.options[name]; |
| 210 if (option != null) { | 210 if (option != null) { |
| 211 args.removeAt(0); | 211 args.removeAt(0); |
| 212 if (option.isFlag) { | 212 if (option.isFlag) { |
| 213 validate(longOpt[3] == null, | 213 validate(longOpt[3] == null, |
| 214 'Flag option "$name" should not be given a value.'); | 214 'Flag option "$name" should not be given a value.'); |
| 215 | 215 |
| 216 setOption(results, option, true); | 216 setFlag(results, option, true); |
| 217 } else if (longOpt[3] != null) { | 217 } else if (longOpt[3] != null) { |
| 218 // We have a value like --foo=bar. | 218 // We have a value like --foo=bar. |
| 219 setOption(results, option, longOpt[3]); | 219 setOption(results, option, longOpt[3]); |
| 220 } else { | 220 } else { |
| 221 // Option like --foo, so look for the value as the next arg. | 221 // Option like --foo, so look for the value as the next arg. |
| 222 readNextArgAsValue(option); | 222 readNextArgAsValue(option); |
| 223 } | 223 } |
| 224 } else if (name.startsWith('no-')) { | 224 } else if (name.startsWith('no-')) { |
| 225 // See if it's a negated flag. | 225 // See if it's a negated flag. |
| 226 name = name.substring('no-'.length); | 226 name = name.substring('no-'.length); |
| 227 option = grammar.options[name]; | 227 option = grammar.options[name]; |
| 228 if (option == null) { | 228 if (option == null) { |
| 229 // Walk up to the parent command if possible. | 229 // Walk up to the parent command if possible. |
| 230 validate(parent != null, 'Could not find an option named "$name".'); | 230 validate(parent != null, 'Could not find an option named "$name".'); |
| 231 return parent.parseLongOption(); | 231 return parent.parseLongOption(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 args.removeAt(0); | 234 args.removeAt(0); |
| 235 validate(option.isFlag, 'Cannot negate non-flag option "$name".'); | 235 validate(option.isFlag, 'Cannot negate non-flag option "$name".'); |
| 236 validate(option.negatable, 'Cannot negate option "$name".'); | 236 validate(option.negatable, 'Cannot negate option "$name".'); |
| 237 | 237 |
| 238 setOption(results, option, false); | 238 setFlag(results, option, false); |
| 239 } else { | 239 } else { |
| 240 // Walk up to the parent command if possible. | 240 // Walk up to the parent command if possible. |
| 241 validate(parent != null, 'Could not find an option named "$name".'); | 241 validate(parent != null, 'Could not find an option named "$name".'); |
| 242 return parent.parseLongOption(); | 242 return parent.parseLongOption(); |
| 243 } | 243 } |
| 244 | 244 |
| 245 return true; | 245 return true; |
| 246 } | 246 } |
| 247 | 247 |
| 248 /// Called during parsing to validate the arguments. | 248 /// Called during parsing to validate the arguments. |
| 249 /// | 249 /// |
| 250 /// Throws a [FormatException] if [condition] is `false`. | 250 /// Throws a [FormatException] if [condition] is `false`. |
| 251 void validate(bool condition, String message) { | 251 void validate(bool condition, String message) { |
| 252 if (!condition) throw new FormatException(message); | 252 if (!condition) throw new FormatException(message); |
| 253 } | 253 } |
| 254 | 254 |
| 255 /// Validates and stores [value] as the value for [option]. | 255 /// Validates and stores [value] as the value for [option], which must not be |
| 256 void setOption(Map results, Option option, value) { | 256 /// a flag. |
| 257 // See if it's one of the allowed values. | 257 void setOption(Map results, Option option, String value) { |
| 258 if (option.allowed != null) { | 258 assert(!option.isFlag); |
| 259 validate(option.allowed.any((allow) => allow == value), | 259 |
| 260 '"$value" is not an allowed value for option "${option.name}".'); | 260 if (!option.isMultiple) { |
| 261 _validateAllowed(option, value); |
| 262 results[option.name] = value; |
| 263 return; |
| 261 } | 264 } |
| 262 | 265 |
| 263 if (option.isMultiple) { | 266 var list = results.putIfAbsent(option.name, () => []); |
| 264 var list = results.putIfAbsent(option.name, () => []); | 267 |
| 268 if (option.splitCommas) { |
| 269 for (var element in value.split(",")) { |
| 270 _validateAllowed(option, element); |
| 271 list.add(element); |
| 272 } |
| 273 } else { |
| 274 _validateAllowed(option, value); |
| 265 list.add(value); | 275 list.add(value); |
| 266 } else { | |
| 267 results[option.name] = value; | |
| 268 } | 276 } |
| 269 } | 277 } |
| 278 |
| 279 /// Validates and stores [value] as the value for [option], which must be a |
| 280 /// flag. |
| 281 void setFlag(Map results, Option option, bool value) { |
| 282 assert(option.isFlag); |
| 283 results[option.name] = value; |
| 284 } |
| 285 |
| 286 /// Validates that [value] is allowed as a value of [option]. |
| 287 void _validateAllowed(Option option, String value) { |
| 288 if (option.allowed == null) return; |
| 289 |
| 290 validate(option.allowed.contains(value), |
| 291 '"$value" is not an allowed value for option "${option.name}".'); |
| 292 } |
| 270 } | 293 } |
| OLD | NEW |