Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Unified Diff: pkg/args/lib/src/parser.dart

Issue 814113004: Pull args, intl, logging, shelf, and source_maps out of the SDK. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Also csslib. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/args/lib/src/option.dart ('k') | pkg/args/lib/src/usage.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/args/lib/src/parser.dart
diff --git a/pkg/args/lib/src/parser.dart b/pkg/args/lib/src/parser.dart
deleted file mode 100644
index 9cd141c00a334b63b6ac491d5c38deb05aea510b..0000000000000000000000000000000000000000
--- a/pkg/args/lib/src/parser.dart
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library args.src.parser;
-
-import 'arg_parser.dart';
-import 'arg_results.dart';
-import 'option.dart';
-
-final _SOLO_OPT = new RegExp(r'^-([a-zA-Z0-9])$');
-final _ABBR_OPT = new RegExp(r'^-([a-zA-Z0-9]+)(.*)$');
-final _LONG_OPT = new RegExp(r'^--([a-zA-Z\-_0-9]+)(=(.*))?$');
-
-/// The actual argument 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.
-class Parser {
- /// If parser is parsing a command's options, this will be the name of the
- /// command. For top-level results, this returns `null`.
- final String commandName;
-
- /// The parser for the supercommand of this command parser, or `null` if this
- /// is the top-level parser.
- final Parser parent;
-
- /// The grammar being parsed.
- final ArgParser grammar;
-
- /// The arguments being parsed.
- final List<String> args;
-
- /// The remaining non-option, non-command arguments.
- final rest = <String>[];
-
- /// The accumulated parsed options.
- final Map<String, dynamic> results = <String, dynamic>{};
-
- Parser(this.commandName, this.grammar, this.args, this.parent, rest) {
- if (rest != null) this.rest.addAll(rest);
- }
-
- /// The current argument being parsed.
- String get current => args[0];
-
- /// Parses the arguments. This can only be called once.
- ArgResults parse() {
- var arguments = args.toList();
- var commandResults = null;
-
- // Parse the args.
- while (args.length > 0) {
- if (current == '--') {
- // Reached the argument terminator, so stop here.
- args.removeAt(0);
- break;
- }
-
- // Try to parse the current argument as a command. This happens before
- // options so that commands can have option-like names.
- var command = grammar.commands[current];
- if (command != null) {
- validate(rest.isEmpty, 'Cannot specify arguments before a command.');
- var commandName = args.removeAt(0);
- var commandParser = new Parser(commandName, command, args, this, rest);
- commandResults = commandParser.parse();
-
- // 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
- // here matters.
- if (parseSoloOption()) continue;
- if (parseAbbreviation(this)) continue;
- if (parseLongOption()) continue;
-
- // This argument is neither option nor command, so stop parsing unless
- // the [allowTrailingOptions] option is set.
- if (!grammar.allowTrailingOptions) break;
- rest.add(args.removeAt(0));
- }
-
- // Invoke the callbacks.
- grammar.options.forEach((name, option) {
- if (option.callback == null) return;
- option.callback(option.getOrDefault(results[name]));
- });
-
- // Add in the leftover arguments we didn't parse to the innermost command.
- rest.addAll(args);
- args.clear();
- return newArgResults(grammar, results, commandName, commandResults, rest,
- arguments);
- }
-
- /// Pulls the value for [option] from the second argument in [args].
- ///
- /// Validates that there is a valid value there.
- void readNextArgAsValue(Option option) {
- // Take the option argument from the next command line arg.
- validate(args.length > 0,
- 'Missing argument for "${option.name}".');
-
- // Make sure it isn't an option itself.
- validate(!_ABBR_OPT.hasMatch(current) && !_LONG_OPT.hasMatch(current),
- 'Missing argument for "${option.name}".');
-
- setOption(results, option, current);
- args.removeAt(0);
- }
-
- /// Tries to parse the current argument as a "solo" option, which is a single
- /// hyphen followed by a single letter.
- ///
- /// We treat this differently than collapsed abbreviations (like "-abc") to
- /// handle the possible value that may follow it.
- bool parseSoloOption() {
- var soloOpt = _SOLO_OPT.firstMatch(current);
- if (soloOpt == null) return false;
-
- var option = grammar.findByAbbreviation(soloOpt[1]);
- if (option == null) {
- // Walk up to the parent command if possible.
- validate(parent != null,
- 'Could not find an option or flag "-${soloOpt[1]}".');
- return parent.parseSoloOption();
- }
-
- args.removeAt(0);
-
- if (option.isFlag) {
- setOption(results, option, true);
- } else {
- readNextArgAsValue(option);
- }
-
- return true;
- }
-
- /// Tries to parse the current argument as a series of collapsed abbreviations
- /// (like "-abc") or a single abbreviation with the value directly attached
- /// to it (like "-mrelease").
- bool parseAbbreviation(Parser innermostCommand) {
- var abbrOpt = _ABBR_OPT.firstMatch(current);
- if (abbrOpt == null) return false;
-
- // If the first character is the abbreviation for a non-flag option, then
- // the rest is the value.
- var c = abbrOpt[1].substring(0, 1);
- var first = grammar.findByAbbreviation(c);
- if (first == null) {
- // Walk up to the parent command if possible.
- validate(parent != null,
- 'Could not find an option with short name "-$c".');
- return parent.parseAbbreviation(innermostCommand);
- } else if (!first.isFlag) {
- // The first character is a non-flag option, so the rest must be the
- // value.
- var value = '${abbrOpt[1].substring(1)}${abbrOpt[2]}';
- setOption(results, first, value);
- } else {
- // If we got some non-flag characters, then it must be a value, but
- // if we got here, it's a flag, which is wrong.
- validate(abbrOpt[2] == '',
- 'Option "-$c" is a flag and cannot handle value '
- '"${abbrOpt[1].substring(1)}${abbrOpt[2]}".');
-
- // Not an option, so all characters should be flags.
- // We use "innermostCommand" here so that if a parent command parses the
- // *first* letter, subcommands can still be found to parse the other
- // letters.
- for (var i = 0; i < abbrOpt[1].length; i++) {
- var c = abbrOpt[1].substring(i, i + 1);
- innermostCommand.parseShortFlag(c);
- }
- }
-
- args.removeAt(0);
- return true;
- }
-
- void parseShortFlag(String c) {
- var option = grammar.findByAbbreviation(c);
- if (option == null) {
- // Walk up to the parent command if possible.
- validate(parent != null,
- 'Could not find an option with short name "-$c".');
- parent.parseShortFlag(c);
- return;
- }
-
- // In a list of short options, only the first can be a non-flag. If
- // we get here we've checked that already.
- validate(option.isFlag,
- 'Option "-$c" must be a flag to be in a collapsed "-".');
-
- setOption(results, option, true);
- }
-
- /// Tries to parse the current argument as a long-form named option, which
- /// may include a value like "--mode=release" or "--mode release".
- bool parseLongOption() {
- var longOpt = _LONG_OPT.firstMatch(current);
- if (longOpt == null) return false;
-
- var name = longOpt[1];
- var option = grammar.options[name];
- if (option != null) {
- args.removeAt(0);
- if (option.isFlag) {
- validate(longOpt[3] == null,
- 'Flag option "$name" should not be given a value.');
-
- setOption(results, option, true);
- } else if (longOpt[3] != null) {
- // We have a value like --foo=bar.
- setOption(results, option, longOpt[3]);
- } else {
- // Option like --foo, so look for the value as the next arg.
- readNextArgAsValue(option);
- }
- } else if (name.startsWith('no-')) {
- // See if it's a negated flag.
- name = name.substring('no-'.length);
- option = grammar.options[name];
- if (option == null) {
- // Walk up to the parent command if possible.
- validate(parent != null, 'Could not find an option named "$name".');
- return parent.parseLongOption();
- }
-
- args.removeAt(0);
- validate(option.isFlag, 'Cannot negate non-flag option "$name".');
- validate(option.negatable, 'Cannot negate option "$name".');
-
- setOption(results, option, false);
- } else {
- // Walk up to the parent command if possible.
- validate(parent != null, 'Could not find an option named "$name".');
- return parent.parseLongOption();
- }
-
- return true;
- }
-
- /// Called during parsing to validate the arguments.
- ///
- /// Throws a [FormatException] if [condition] is `false`.
- void validate(bool condition, String message) {
- if (!condition) throw new FormatException(message);
- }
-
- /// Validates and stores [value] as the value for [option].
- void setOption(Map results, Option option, value) {
- // See if it's one of the allowed values.
- if (option.allowed != null) {
- validate(option.allowed.any((allow) => allow == value),
- '"$value" is not an allowed value for option "${option.name}".');
- }
-
- if (option.isMultiple) {
- var list = results.putIfAbsent(option.name, () => []);
- list.add(value);
- } else {
- results[option.name] = value;
- }
- }
-}
« no previous file with comments | « pkg/args/lib/src/option.dart ('k') | pkg/args/lib/src/usage.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698