| Index: pkg/args/lib/src/parser.dart
|
| diff --git a/pkg/args/lib/src/parser.dart b/pkg/args/lib/src/parser.dart
|
| index d35f9ea4aff1bb67a1c20034b17574168d0c6502..76358411b4053cfbcfd789254e603eee03bb2463 100644
|
| --- a/pkg/args/lib/src/parser.dart
|
| +++ b/pkg/args/lib/src/parser.dart
|
| @@ -14,6 +14,10 @@ final _LONG_OPT = new RegExp(r'^--([a-zA-Z\-_0-9]+)(=(.*))?$');
|
| * The actual parsing class. Unlike [ArgParser] which is really more an "arg
|
| * grammar", this is the class that does the parsing and holds the mutable
|
| * state required during a parse.
|
| + *
|
| + * If [continueParsing] is set, the parser will continue parsing even after it
|
| + * finds an argument that is not an option. This allows you to specify options
|
| + * after your command parameters.
|
| */
|
| class Parser {
|
| /**
|
| @@ -28,21 +32,36 @@ class Parser {
|
| */
|
| final Parser parent;
|
|
|
| + /** If `true`, parser will continue after it sees a non-option argument. */
|
| + final boolean continueParsing;
|
| +
|
| /** The grammar being parsed. */
|
| final ArgParser grammar;
|
|
|
| /** The arguments being parsed. */
|
| final List<String> args;
|
|
|
| + /**
|
| + * The remaining unparsed arguments.
|
| + *
|
| + * This will be passed onto commands so only the last command will use the
|
| + * arguments.
|
| + */
|
| + List<String> rest;
|
| +
|
| /** The accumulated parsed options. */
|
| final Map results = {};
|
|
|
| - Parser(this.commandName, this.grammar, this.args, [this.parent]);
|
| + Parser(this.commandName, this.grammar, this.args,
|
| + [this.continueParsing = false, this.parent, rest])
|
| + : this.rest = rest == null ? [] : rest;
|
|
|
| /** The current argument being parsed. */
|
| String get current => args[0];
|
|
|
| - /** Parses the arguments. This can only be called once. */
|
| + /**
|
| + * Parses the arguments. This can only be called once.
|
| + */
|
| ArgResults parse() {
|
| var commandResults = null;
|
|
|
| @@ -68,9 +87,14 @@ class Parser {
|
| var command = grammar.commands[current];
|
| if (command != null) {
|
| var commandName = args.removeAt(0);
|
| - var commandParser = new Parser(commandName, command, args, this);
|
| + var commandParser = new Parser(commandName, command, args,
|
| + continueParsing, this, rest.toList());
|
| commandResults = commandParser.parse();
|
| - continue;
|
| +
|
| + // All remaining arguments were passed to command so clear them here.
|
| + rest.clear();
|
| +
|
| + break;
|
| }
|
|
|
| // Try to parse the current argument as an option. Note that the order
|
| @@ -79,8 +103,12 @@ class Parser {
|
| if (parseAbbreviation(this)) continue;
|
| if (parseLongOption()) continue;
|
|
|
| - // If we got here, the argument doesn't look like an option, so stop.
|
| - break;
|
| + if (!continueParsing) {
|
| + // If we got here, the argument doesn't look like an option, so stop.
|
| + break;
|
| + } else {
|
| + rest.add(args.removeAt(0));
|
| + }
|
| }
|
|
|
| // Set unspecified multivalued arguments to their default value,
|
| @@ -95,7 +123,7 @@ class Parser {
|
| });
|
|
|
| // Add in the leftover arguments we didn't parse to the innermost command.
|
| - var rest = args.toList();
|
| + rest.addAll(args.toList());
|
| args.clear();
|
| return new ArgResults(results, commandName, commandResults, rest);
|
| }
|
|
|