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

Side by Side Diff: lib/args/args.dart

Issue 10383049: Revert "Using arg parsing lib for dart2js." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | lib/compiler/implementation/dart2js.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * This library lets you define parsers for parsing raw command-line arguments 6 * This library lets you define parsers for parsing raw command-line arguments
7 * into a set of options and values using [GNU][] and [POSIX][] style options. 7 * into a set of options and values using [GNU][] and [POSIX][] style options.
8 * 8 *
9 * ## Defining options ## 9 * ## Defining options ##
10 * 10 *
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 167
168 /** 168 /**
169 * A class for taking a list of raw command line arguments and parsing out 169 * A class for taking a list of raw command line arguments and parsing out
170 * options and flags from them. 170 * options and flags from them.
171 */ 171 */
172 class ArgParser { 172 class ArgParser {
173 static final _SOLO_OPT = const RegExp(@'^-([a-z0-9])$'); 173 static final _SOLO_OPT = const RegExp(@'^-([a-z0-9])$');
174 static final _ABBR_OPT = const RegExp(@'^-([a-z0-9]+)(.*)$'); 174 static final _ABBR_OPT = const RegExp(@'^-([a-z0-9]+)(.*)$');
175 static final _LONG_OPT = const RegExp(@'^--([a-z\-_0-9]+)(=(.*))?$'); 175 static final _LONG_OPT = const RegExp(@'^--([a-z\-_0-9]+)(=(.*))?$');
176 176
177 final String _usage;
178 final Map<String, _Option> _options; 177 final Map<String, _Option> _options;
179 178
180 /** 179 /**
181 * The names of the options, in the order that they were added. This way we 180 * The names of the options, in the order that they were added. This way we
182 * can generate usage information in the same order. 181 * can generate usage information in the same order.
183 */ 182 */
184 // TODO(rnystrom): Use an ordered map type, if one appears. 183 // TODO(rnystrom): Use an ordered map type, if one appears.
185 final List<String> _optionNames; 184 final List<String> _optionNames;
186 185
187 /** The current argument list being parsed. Set by [parse()]. */ 186 /** The current argument list being parsed. Set by [parse()]. */
188 List<String> _args; 187 List<String> _args;
189 188
190 /** Index of the current argument being parsed in [_args]. */ 189 /** Index of the current argument being parsed in [_args]. */
191 int _current; 190 int _current;
192 191
193 /** 192 /** Creates a new ArgParser. */
194 * Creates a new ArgParser. If provided [usage] will be included when usage 193 ArgParser()
195 * information is displayed. It is typically the example command-line shown 194 : _options = <_Option>{},
196 * at the top of help documentation like: 195 _optionNames = <String>[];
197 *
198 * myapp [options] <arg> <another>
199 *
200 * If [includeHelp] is `true` (or omitted), it will automatically add a
201 * `--help` flag.
202 */
203 ArgParser([String usage, bool includeHelp = true])
204 : _usage = usage,
205 _options = <_Option>{},
206 _optionNames = <String>[] {
207 if (includeHelp) {
208 addFlag('help', abbr: 'h', help: 'Display usage information');
209 }
210 }
211 196
212 /** 197 /**
213 * Defines a flag. Throws an [IllegalArgumentException] if: 198 * Defines a flag. Throws an [IllegalArgumentException] if:
214 * 199 *
215 * * There is already an option named [name]. 200 * * There is already an option named [name].
216 * * There is already an option using abbreviation [abbr]. 201 * * There is already an option using abbreviation [abbr].
217 */ 202 */
218 void addFlag(String name, [String abbr, String help, bool defaultsTo = false, 203 void addFlag(String name, [String abbr, String help, bool defaultsTo = false,
219 void callback(bool value)]) { 204 void callback(bool value)]) {
220 _addOption(name, abbr, help, null, null, defaultsTo, callback, 205 _addOption(name, abbr, help, null, null, defaultsTo, callback,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 var option = _options[name]; 285 var option = _options[name];
301 if (option.callback != null) option.callback(results[name]); 286 if (option.callback != null) option.callback(results[name]);
302 } 287 }
303 288
304 // Add in the leftover arguments we didn't parse. 289 // Add in the leftover arguments we didn't parse.
305 return new ArgResults(results, 290 return new ArgResults(results,
306 _args.getRange(_current, _args.length - _current)); 291 _args.getRange(_current, _args.length - _current));
307 } 292 }
308 293
309 /** 294 /**
310 * Parses [args], a list of command-line arguments, matches them against the
311 * flags and options defined by this parser, and returns the result. If
312 * `--help` is specified, then it prints usage information to stdout and
313 * exits the process.
314 *
315 * If an error occurs (i.e. an [ArgFormatException] is thrown while parsing),
316 * it prints the error and the usage information and then exits the process
317 * with exit code 1.
318 *
319 * Otherwise, it will return the results of parsing.
320 */
321 ArgResults process(List<String> args) {
322 try {
323 var results = parse(args);
324
325 if (results['help']) {
326 print(getUsage());
327 exit(0);
328 }
329
330 return results;
331 } catch (ArgFormatException ex) {
332 print('${ex.message} Usage:\n\n${getUsage()}');
333 exit(1);
334 }
335 }
336
337 /**
338 * Generates a string displaying usage information for the defined options. 295 * Generates a string displaying usage information for the defined options.
339 * This is basically the help text shown on the command line. 296 * This is basically the help text shown on the command line.
340 */ 297 */
341 String getUsage() { 298 String getUsage() {
342 return new _Usage(this).generate(); 299 return new _Usage(this).generate();
343 } 300 }
344 301
345 /** 302 /**
346 * Called during parsing to validate the arguments. Throws an 303 * Called during parsing to validate the arguments. Throws an
347 * [ArgFormatException] if [condition] is `false`. 304 * [ArgFormatException] if [condition] is `false`.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 * Tries to parse the current argument as a "solo" option, which is a single 341 * Tries to parse the current argument as a "solo" option, which is a single
385 * hyphen followed by a single letter. We treat this differently than 342 * hyphen followed by a single letter. We treat this differently than
386 * collapsed abbreviations (like "-abc") to handle the possible value that 343 * collapsed abbreviations (like "-abc") to handle the possible value that
387 * may follow it. 344 * may follow it.
388 */ 345 */
389 bool _parseSoloOption(Map results) { 346 bool _parseSoloOption(Map results) {
390 var soloOpt = _SOLO_OPT.firstMatch(_args[_current]); 347 var soloOpt = _SOLO_OPT.firstMatch(_args[_current]);
391 if (soloOpt == null) return false; 348 if (soloOpt == null) return false;
392 349
393 var option = _findByAbbr(soloOpt[1]); 350 var option = _findByAbbr(soloOpt[1]);
394 _validate(option != null, 'Unknown option "-${soloOpt[1]}".'); 351 _validate(option != null,
352 'Could not find an option or flag "-${soloOpt[1]}".');
395 353
396 if (option.isFlag) { 354 if (option.isFlag) {
397 _setOption(results, option, true); 355 _setOption(results, option, true);
398 } else { 356 } else {
399 _readNextArgAsValue(results, option); 357 _readNextArgAsValue(results, option);
400 } 358 }
401 359
402 return true; 360 return true;
403 } 361 }
404 362
405 /** 363 /**
406 * Tries to parse the current argument as a series of collapsed abbreviations 364 * Tries to parse the current argument as a series of collapsed abbreviations
407 * (like "-abc") or a single abbreviation with the value directly attached 365 * (like "-abc") or a single abbreviation with the value directly attached
408 * to it (like "-mrelease"). 366 * to it (like "-mrelease").
409 */ 367 */
410 bool _parseAbbreviation(Map results) { 368 bool _parseAbbreviation(Map results) {
411 var abbrOpt = _ABBR_OPT.firstMatch(_args[_current]); 369 var abbrOpt = _ABBR_OPT.firstMatch(_args[_current]);
412 if (abbrOpt == null) return false; 370 if (abbrOpt == null) return false;
413 371
414 // If the first character is the abbreviation for a non-flag option, then 372 // If the first character is the abbreviation for a non-flag option, then
415 // the rest is the value. 373 // the rest is the value.
416 var c = abbrOpt[1].substring(0, 1); 374 var c = abbrOpt[1].substring(0, 1);
417 var first = _findByAbbr(c); 375 var first = _findByAbbr(c);
418 if (first == null) { 376 if (first == null) {
419 _validate(false, 'Unknown option "-$c".'); 377 _validate(false, 'Could not find an option with short name "-$c".');
420 } else if (!first.isFlag) { 378 } else if (!first.isFlag) {
421 // The first character is a non-flag option, so the rest must be the 379 // The first character is a non-flag option, so the rest must be the
422 // value. 380 // value.
423 var value = '${abbrOpt[1].substring(1)}${abbrOpt[2]}'; 381 var value = '${abbrOpt[1].substring(1)}${abbrOpt[2]}';
424 _setOption(results, first, value); 382 _setOption(results, first, value);
425 } else { 383 } else {
426 // If we got some non-flag characters, then it must be a value, but 384 // If we got some non-flag characters, then it must be a value, but
427 // if we got here, it's a flag, which is wrong. 385 // if we got here, it's a flag, which is wrong.
428 _validate(abbrOpt[2] == '', 386 _validate(abbrOpt[2] == '',
429 'Option "-$c" is a flag and cannot handle value ' 387 'Option "-$c" is a flag and cannot handle value '
430 '"${abbrOpt[1].substring(1)}${abbrOpt[2]}".'); 388 '"${abbrOpt[1].substring(1)}${abbrOpt[2]}".');
431 389
432 // Not an option, so all characters should be flags. 390 // Not an option, so all characters should be flags.
433 for (var i = 0; i < abbrOpt[1].length; i++) { 391 for (var i = 0; i < abbrOpt[1].length; i++) {
434 var c = abbrOpt[1].substring(i, i + 1); 392 var c = abbrOpt[1].substring(i, i + 1);
435 var option = _findByAbbr(c); 393 var option = _findByAbbr(c);
436 _validate(option != null, 394 _validate(option != null,
437 'Unknown option "-$c".'); 395 'Could not find an option with short name "-$c".');
438 396
439 // In a list of short options, only the first can be a non-flag. If 397 // In a list of short options, only the first can be a non-flag. If
440 // we get here we've checked that already. 398 // we get here we've checked that already.
441 _validate(option.isFlag, 399 _validate(option.isFlag,
442 'Option "-$c" must be a flag to be in a collapsed "-".'); 400 'Option "-$c" must be a flag to be in a collapsed "-".');
443 401
444 _setOption(results, option, true); 402 _setOption(results, option, true);
445 } 403 }
446 } 404 }
447 405
(...skipping 20 matching lines...) Expand all
468 // We have a value like --foo=bar. 426 // We have a value like --foo=bar.
469 _setOption(results, option, longOpt[3]); 427 _setOption(results, option, longOpt[3]);
470 } else { 428 } else {
471 // Option like --foo, so look for the value as the next arg. 429 // Option like --foo, so look for the value as the next arg.
472 _readNextArgAsValue(results, option); 430 _readNextArgAsValue(results, option);
473 } 431 }
474 } else if (name.startsWith('no-')) { 432 } else if (name.startsWith('no-')) {
475 // See if it's a negated flag. 433 // See if it's a negated flag.
476 name = name.substring('no-'.length); 434 name = name.substring('no-'.length);
477 option = _options[name]; 435 option = _options[name];
478 _validate(option != null, 'Unknown option "$name".'); 436 _validate(option != null, 'Could not find an option named "$name".');
479 _validate(option.isFlag, 'Cannot negate non-flag option "$name.'); 437 _validate(option.isFlag, 'Cannot negate non-flag option "$name.');
480 438
481 _setOption(results, option, false); 439 _setOption(results, option, false);
482 } else { 440 } else {
483 _validate(option != null, 'Unknown option "$name".'); 441 _validate(option != null, 'Could not find an option named "$name".');
484 } 442 }
485 443
486 return true; 444 return true;
487 } 445 }
488 446
489 /** 447 /**
490 * Finds the option whose abbreviation is [abbr], or `null` if no option has 448 * Finds the option whose abbreviation is [abbr], or `null` if no option has
491 * that abbreviation. 449 * that abbreviation.
492 */ 450 */
493 _Option _findByAbbr(String abbr) { 451 _Option _findByAbbr(String abbr) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 557
600 _Usage(this.args); 558 _Usage(this.args);
601 559
602 /** 560 /**
603 * Generates a string displaying usage information for the defined options. 561 * Generates a string displaying usage information for the defined options.
604 * This is basically the help text shown on the command line. 562 * This is basically the help text shown on the command line.
605 */ 563 */
606 String generate() { 564 String generate() {
607 buffer = new StringBuffer(); 565 buffer = new StringBuffer();
608 566
609 if (args._usage != null) buffer.add('${args._usage}\n\n');
610
611 calculateColumnWidths(); 567 calculateColumnWidths();
612 568
613 for (var name in args._optionNames) { 569 for (var name in args._optionNames) {
614 var option = args._options[name]; 570 var option = args._options[name];
615 write(0, getAbbreviation(option)); 571 write(0, getAbbreviation(option));
616 write(1, getLongOption(option)); 572 write(1, getLongOption(option));
617 573
618 if (option.help != null) write(2, option.help); 574 if (option.help != null) write(2, option.help);
619 575
620 if (option.allowedHelp != null) { 576 if (option.allowedHelp != null) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 allowedBuffer.add(allowed); 720 allowedBuffer.add(allowed);
765 if (allowed == option.defaultValue) { 721 if (allowed == option.defaultValue) {
766 allowedBuffer.add(' (default)'); 722 allowedBuffer.add(' (default)');
767 } 723 }
768 first = false; 724 first = false;
769 } 725 }
770 allowedBuffer.add(']'); 726 allowedBuffer.add(']');
771 return allowedBuffer.toString(); 727 return allowedBuffer.toString();
772 } 728 }
773 } 729 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/dart2js.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698