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 |