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

Side by Side Diff: pkg/fasta/lib/src/command_line.dart

Issue 2634453004: Fasta infrastructure. (Closed)
Patch Set: Address review comments. Created 3 years, 11 months 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 unified diff | Download patch
« no previous file with comments | « pkg/fasta/lib/src/colors.dart ('k') | pkg/fasta/lib/src/compile_platform.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4
5 library fasta.command_line;
6
7 import 'errors.dart' show
8 inputError,
9 internalError;
10
11 argumentError(String usage, String message) {
12 if (usage != null) print(usage);
13 inputError(null, null, message);
14 }
15
16 class ParsedArguments {
17 final Map<String, dynamic> options = <String, dynamic>{};
18 final List<String> arguments = <String>[];
19
20 toString() => "ParsedArguments($options, $arguments)";
21 }
22
23 class CommandLine {
24 final Map<String, dynamic> options;
25
26 final List<String> arguments;
27
28 final String usage;
29
30 CommandLine.parsed(ParsedArguments p, this.usage)
31 : this.options = p.options,
32 this.arguments = p.arguments {
33 validate();
34 if (verbose) {
35 print(p);
36 }
37 }
38
39 CommandLine(List<String> arguments,
40 {Map<String, dynamic> specification, String usage})
41 : this.parsed(parse(arguments, specification, usage), usage);
42
43 bool get verbose {
44 return options.containsKey("-v") || options.containsKey("--verbose");
45 }
46
47 /// Override to validate arguments and options.
48 void validate() {
49 }
50
51 /// Parses a list of command-line [arguments] into options and arguments.
52 ///
53 /// An /option/ is something that, normally, starts with `-` or `--` (one or
54 /// two dashes). However, as a special case `/?` and `/h` are also recognized
55 /// as options for increased compatibility with Windows. An option can have a
56 /// value.
57 ///
58 /// An /argument/ is something that isn't an option, for example, a file name.
59 ///
60 /// The specification is a map of options to one of the type literals `Uri`,
61 /// `int`, `bool`, or `String`, or a comma (`","`) that represents option
62 /// values of type [Uri], [int], [bool], [String], or a comma-separated list
63 /// of [String], respectively.
64 ///
65 /// If [arguments] contains `"--"`, anything before is parsed as options, and
66 /// arguments; anything following is treated as arguments (even if starting
67 /// with, for example, a `-`).
68 ///
69 /// Anything that looks like an option is assumed to be a `bool` option set
70 /// to true, unless it's mentioned in [specification] in which case the
71 /// option requires a value, either on the form `--option value` or
72 /// `--option=value`.
73 ///
74 /// This method performs only a limited amount of validation, but if an error
75 /// occurs, it will print [usage] along with a specific error message.
76 static ParsedArguments parse(List<String> arguments,
77 Map<String, dynamic> specification, String usage) {
78 specification ??= const <String, dynamic>{};
79 ParsedArguments result = new ParsedArguments();
80 int index = arguments.indexOf("--");
81 Iterable<String> nonOptions = const <String>[];
82 Iterator<String> iterator = arguments.iterator;
83 if (index != -1) {
84 nonOptions = arguments.skip(index + 1);
85 iterator = arguments.take(index).iterator;
86 }
87 while (iterator.moveNext()) {
88 String argument = iterator.current;
89 if (argument.startsWith("-")) {
90 var valueSpecification = specification[argument];
91 String value;
92 if (valueSpecification != null) {
93 if (!iterator.moveNext()) {
94 return argumentError(usage, "Expected value after '$argument'.");
95 }
96 value = iterator.current;
97 } else {
98 index = argument.indexOf("=");
99 if (index != -1) {
100 value = argument.substring(index + 1);
101 argument = argument.substring(0, index);
102 valueSpecification = specification[argument];
103 }
104 }
105 if (valueSpecification == null) {
106 if (value != null) {
107 return argumentError(usage,
108 "Argument '$argument' doesn't take a value: '$value'.");
109 }
110 result.options[argument] = true;
111 } else {
112 if (valueSpecification is! String && valueSpecification is! Type) {
113 return argumentError(usage, "Unrecognized type of value "
114 "specification: ${valueSpecification.runtimeType}.");
115 }
116 switch ("$valueSpecification") {
117 case ",":
118 result.options.putIfAbsent(argument, () => <String>[])
119 .addAll(value.split(","));
120 break;
121
122 case "int":
123 case "bool":
124 case "String":
125 case "Uri":
126 if (result.options.containsKey(argument)) {
127 return argumentError(usage, "Multiple values for '$argument': "
128 "'${result.options[argument]}' and '$value'.");
129 }
130 var parsedValue;
131 if (valueSpecification == int) {
132 parsedValue = int.parse(value, onError: (_) {
133 return argumentError(usage,
134 "Value for '$argument', '$value', isn't an int.");
135 });
136 } else if (valueSpecification == bool) {
137 if (value == "true" || value == "yes") {
138 parsedValue = true;
139 } else if (value == "false" || value == "no") {
140 parsedValue = false;
141 } else {
142 return argumentError(usage,
143 "Value for '$argument' is '$value', "
144 "but expected one of: 'true', 'false', 'yes', or 'no'.");
145 }
146 } else if (valueSpecification == Uri) {
147 parsedValue = Uri.base.resolve(value);
148 } else if (valueSpecification == String) {
149 parsedValue = value;
150 } else if (valueSpecification is String) {
151 return argumentError(usage, "Unrecognized value specification: "
152 "'$valueSpecification', try using a type literal instead.");
153 } else {
154 // All possible cases should have been handled above.
155 return internalError("assertion failure");
156 }
157 result.options[argument] = parsedValue;
158 break;
159
160 default:
161 return argumentError(usage,
162 "Unrecognized value specification: '$valueSpecification'.");
163 }
164 }
165 } else if (argument == "/?" || argument == "/h") {
166 result.options[argument] = true;
167 } else {
168 result.arguments.add(argument);
169 }
170 }
171 result.arguments.addAll(nonOptions);
172 return result;
173 }
174 }
OLDNEW
« no previous file with comments | « pkg/fasta/lib/src/colors.dart ('k') | pkg/fasta/lib/src/compile_platform.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698