1# frozen_string_literal: true 2# 3# optparse.rb - command-line option analysis with the OptionParser class. 4# 5# Author:: Nobu Nakada 6# Documentation:: Nobu Nakada and Gavin Sinclair. 7# 8# See OptionParser for documentation. 9# 10 11 12#-- 13# == Developer Documentation (not for RDoc output) 14# 15# === Class tree 16# 17# - OptionParser:: front end 18# - OptionParser::Switch:: each switches 19# - OptionParser::List:: options list 20# - OptionParser::ParseError:: errors on parsing 21# - OptionParser::AmbiguousOption 22# - OptionParser::NeedlessArgument 23# - OptionParser::MissingArgument 24# - OptionParser::InvalidOption 25# - OptionParser::InvalidArgument 26# - OptionParser::AmbiguousArgument 27# 28# === Object relationship diagram 29# 30# +--------------+ 31# | OptionParser |<>-----+ 32# +--------------+ | +--------+ 33# | ,-| Switch | 34# on_head -------->+---------------+ / +--------+ 35# accept/reject -->| List |<|>- 36# | |<|>- +----------+ 37# on ------------->+---------------+ `-| argument | 38# : : | class | 39# +---------------+ |==========| 40# on_tail -------->| | |pattern | 41# +---------------+ |----------| 42# OptionParser.accept ->| DefaultList | |converter | 43# reject |(shared between| +----------+ 44# | all instances)| 45# +---------------+ 46# 47#++ 48# 49# == OptionParser 50# 51# === Introduction 52# 53# OptionParser is a class for command-line option analysis. It is much more 54# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented 55# solution. 56# 57# === Features 58# 59# 1. The argument specification and the code to handle it are written in the 60# same place. 61# 2. It can output an option summary; you don't need to maintain this string 62# separately. 63# 3. Optional and mandatory arguments are specified very gracefully. 64# 4. Arguments can be automatically converted to a specified class. 65# 5. Arguments can be restricted to a certain set. 66# 67# All of these features are demonstrated in the examples below. See 68# #make_switch for full documentation. 69# 70# === Minimal example 71# 72# require 'optparse' 73# 74# options = {} 75# OptionParser.new do |opts| 76# opts.banner = "Usage: example.rb [options]" 77# 78# opts.on("-v", "--[no-]verbose", "Run verbosely") do |v| 79# options[:verbose] = v 80# end 81# end.parse! 82# 83# p options 84# p ARGV 85# 86# === Generating Help 87# 88# OptionParser can be used to automatically generate help for the commands you 89# write: 90# 91# require 'optparse' 92# 93# Options = Struct.new(:name) 94# 95# class Parser 96# def self.parse(options) 97# args = Options.new("world") 98# 99# opt_parser = OptionParser.new do |opts| 100# opts.banner = "Usage: example.rb [options]" 101# 102# opts.on("-nNAME", "--name=NAME", "Name to say hello to") do |n| 103# args.name = n 104# end 105# 106# opts.on("-h", "--help", "Prints this help") do 107# puts opts 108# exit 109# end 110# end 111# 112# opt_parser.parse!(options) 113# return args 114# end 115# end 116# options = Parser.parse %w[--help] 117# 118# #=> 119# # Usage: example.rb [options] 120# # -n, --name=NAME Name to say hello to 121# # -h, --help Prints this help 122# 123# === Required Arguments 124# 125# For options that require an argument, option specification strings may include an 126# option name in all caps. If an option is used without the required argument, 127# an exception will be raised. 128# 129# require 'optparse' 130# 131# options = {} 132# OptionParser.new do |parser| 133# parser.on("-r", "--require LIBRARY", 134# "Require the LIBRARY before executing your script") do |lib| 135# puts "You required #{lib}!" 136# end 137# end.parse! 138# 139# Used: 140# 141# $ ruby optparse-test.rb -r 142# optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument) 143# $ ruby optparse-test.rb -r my-library 144# You required my-library! 145# 146# === Type Coercion 147# 148# OptionParser supports the ability to coerce command line arguments 149# into objects for us. 150# 151# OptionParser comes with a few ready-to-use kinds of type 152# coercion. They are: 153# 154# - Date -- Anything accepted by +Date.parse+ 155# - DateTime -- Anything accepted by +DateTime.parse+ 156# - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+ 157# - URI -- Anything accepted by +URI.parse+ 158# - Shellwords -- Anything accepted by +Shellwords.shellwords+ 159# - String -- Any non-empty string 160# - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040) 161# - Float -- Any float. (e.g. 10, 3.14, -100E+13) 162# - Numeric -- Any integer, float, or rational (1, 3.4, 1/3) 163# - DecimalInteger -- Like +Integer+, but no octal format. 164# - OctalInteger -- Like +Integer+, but no decimal format. 165# - DecimalNumeric -- Decimal integer or float. 166# - TrueClass -- Accepts '+, yes, true, -, no, false' and 167# defaults as +true+ 168# - FalseClass -- Same as +TrueClass+, but defaults to +false+ 169# - Array -- Strings separated by ',' (e.g. 1,2,3) 170# - Regexp -- Regular expressions. Also includes options. 171# 172# We can also add our own coercions, which we will cover soon. 173# 174# ==== Using Built-in Conversions 175# 176# As an example, the built-in +Time+ conversion is used. The other built-in 177# conversions behave in the same way. 178# OptionParser will attempt to parse the argument 179# as a +Time+. If it succeeds, that time will be passed to the 180# handler block. Otherwise, an exception will be raised. 181# 182# require 'optparse' 183# require 'optparse/time' 184# OptionParser.new do |parser| 185# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time| 186# p time 187# end 188# end.parse! 189# 190# Used: 191# 192# $ ruby optparse-test.rb -t nonsense 193# ... invalid argument: -t nonsense (OptionParser::InvalidArgument) 194# $ ruby optparse-test.rb -t 10-11-12 195# 2010-11-12 00:00:00 -0500 196# $ ruby optparse-test.rb -t 9:30 197# 2014-08-13 09:30:00 -0400 198# 199# ==== Creating Custom Conversions 200# 201# The +accept+ method on OptionParser may be used to create converters. 202# It specifies which conversion block to call whenever a class is specified. 203# The example below uses it to fetch a +User+ object before the +on+ handler receives it. 204# 205# require 'optparse' 206# 207# User = Struct.new(:id, :name) 208# 209# def find_user id 210# not_found = ->{ raise "No User Found for id #{id}" } 211# [ User.new(1, "Sam"), 212# User.new(2, "Gandalf") ].find(not_found) do |u| 213# u.id == id 214# end 215# end 216# 217# op = OptionParser.new 218# op.accept(User) do |user_id| 219# find_user user_id.to_i 220# end 221# 222# op.on("--user ID", User) do |user| 223# puts user 224# end 225# 226# op.parse! 227# 228# Used: 229# 230# $ ruby optparse-test.rb --user 1 231# #<struct User id=1, name="Sam"> 232# $ ruby optparse-test.rb --user 2 233# #<struct User id=2, name="Gandalf"> 234# $ ruby optparse-test.rb --user 3 235# optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError) 236# 237# === Store options to a Hash 238# 239# The +into+ option of +order+, +parse+ and so on methods stores command line options into a Hash. 240# 241# require 'optparse' 242# 243# params = {} 244# OptionParser.new do |opts| 245# opts.on('-a') 246# opts.on('-b NUM', Integer) 247# opts.on('-v', '--verbose') 248# end.parse!(into: params) 249# 250# p params 251# 252# Used: 253# 254# $ ruby optparse-test.rb -a 255# {:a=>true} 256# $ ruby optparse-test.rb -a -v 257# {:a=>true, :verbose=>true} 258# $ ruby optparse-test.rb -a -b 100 259# {:a=>true, :b=>100} 260# 261# === Complete example 262# 263# The following example is a complete Ruby program. You can run it and see the 264# effect of specifying various options. This is probably the best way to learn 265# the features of +optparse+. 266# 267# require 'optparse' 268# require 'optparse/time' 269# require 'ostruct' 270# require 'pp' 271# 272# class OptparseExample 273# Version = '1.0.0' 274# 275# CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary] 276# CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" } 277# 278# class ScriptOptions 279# attr_accessor :library, :inplace, :encoding, :transfer_type, 280# :verbose, :extension, :delay, :time, :record_separator, 281# :list 282# 283# def initialize 284# self.library = [] 285# self.inplace = false 286# self.encoding = "utf8" 287# self.transfer_type = :auto 288# self.verbose = false 289# end 290# 291# def define_options(parser) 292# parser.banner = "Usage: example.rb [options]" 293# parser.separator "" 294# parser.separator "Specific options:" 295# 296# # add additional options 297# perform_inplace_option(parser) 298# delay_execution_option(parser) 299# execute_at_time_option(parser) 300# specify_record_separator_option(parser) 301# list_example_option(parser) 302# specify_encoding_option(parser) 303# optional_option_argument_with_keyword_completion_option(parser) 304# boolean_verbose_option(parser) 305# 306# parser.separator "" 307# parser.separator "Common options:" 308# # No argument, shows at tail. This will print an options summary. 309# # Try it and see! 310# parser.on_tail("-h", "--help", "Show this message") do 311# puts parser 312# exit 313# end 314# # Another typical switch to print the version. 315# parser.on_tail("--version", "Show version") do 316# puts Version 317# exit 318# end 319# end 320# 321# def perform_inplace_option(parser) 322# # Specifies an optional option argument 323# parser.on("-i", "--inplace [EXTENSION]", 324# "Edit ARGV files in place", 325# "(make backup if EXTENSION supplied)") do |ext| 326# self.inplace = true 327# self.extension = ext || '' 328# self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot. 329# end 330# end 331# 332# def delay_execution_option(parser) 333# # Cast 'delay' argument to a Float. 334# parser.on("--delay N", Float, "Delay N seconds before executing") do |n| 335# self.delay = n 336# end 337# end 338# 339# def execute_at_time_option(parser) 340# # Cast 'time' argument to a Time object. 341# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time| 342# self.time = time 343# end 344# end 345# 346# def specify_record_separator_option(parser) 347# # Cast to octal integer. 348# parser.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger, 349# "Specify record separator (default \\0)") do |rs| 350# self.record_separator = rs 351# end 352# end 353# 354# def list_example_option(parser) 355# # List of arguments. 356# parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list| 357# self.list = list 358# end 359# end 360# 361# def specify_encoding_option(parser) 362# # Keyword completion. We are specifying a specific set of arguments (CODES 363# # and CODE_ALIASES - notice the latter is a Hash), and the user may provide 364# # the shortest unambiguous text. 365# code_list = (CODE_ALIASES.keys + CODES).join(', ') 366# parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding", 367# "(#{code_list})") do |encoding| 368# self.encoding = encoding 369# end 370# end 371# 372# def optional_option_argument_with_keyword_completion_option(parser) 373# # Optional '--type' option argument with keyword completion. 374# parser.on("--type [TYPE]", [:text, :binary, :auto], 375# "Select transfer type (text, binary, auto)") do |t| 376# self.transfer_type = t 377# end 378# end 379# 380# def boolean_verbose_option(parser) 381# # Boolean switch. 382# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v| 383# self.verbose = v 384# end 385# end 386# end 387# 388# # 389# # Return a structure describing the options. 390# # 391# def parse(args) 392# # The options specified on the command line will be collected in 393# # *options*. 394# 395# @options = ScriptOptions.new 396# @args = OptionParser.new do |parser| 397# @options.define_options(parser) 398# parser.parse!(args) 399# end 400# @options 401# end 402# 403# attr_reader :parser, :options 404# end # class OptparseExample 405# 406# example = OptparseExample.new 407# options = example.parse(ARGV) 408# pp options # example.options 409# pp ARGV 410# 411# === Shell Completion 412# 413# For modern shells (e.g. bash, zsh, etc.), you can use shell 414# completion for command line options. 415# 416# === Further documentation 417# 418# The above examples should be enough to learn how to use this class. If you 419# have any questions, file a ticket at http://bugs.ruby-lang.org. 420# 421class OptionParser 422 # :stopdoc: 423 NoArgument = [NO_ARGUMENT = :NONE, nil].freeze 424 RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze 425 OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze 426 # :startdoc: 427 428 # 429 # Keyword completion module. This allows partial arguments to be specified 430 # and resolved against a list of acceptable values. 431 # 432 module Completion 433 def self.regexp(key, icase) 434 Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), icase) 435 end 436 437 def self.candidate(key, icase = false, pat = nil, &block) 438 pat ||= Completion.regexp(key, icase) 439 candidates = [] 440 block.call do |k, *v| 441 (if Regexp === k 442 kn = "" 443 k === key 444 else 445 kn = defined?(k.id2name) ? k.id2name : k 446 pat === kn 447 end) or next 448 v << k if v.empty? 449 candidates << [k, v, kn] 450 end 451 candidates 452 end 453 454 def candidate(key, icase = false, pat = nil) 455 Completion.candidate(key, icase, pat, &method(:each)) 456 end 457 458 public 459 def complete(key, icase = false, pat = nil) 460 candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size} 461 if candidates.size == 1 462 canon, sw, * = candidates[0] 463 elsif candidates.size > 1 464 canon, sw, cn = candidates.shift 465 candidates.each do |k, v, kn| 466 next if sw == v 467 if String === cn and String === kn 468 if cn.rindex(kn, 0) 469 canon, sw, cn = k, v, kn 470 next 471 elsif kn.rindex(cn, 0) 472 next 473 end 474 end 475 throw :ambiguous, key 476 end 477 end 478 if canon 479 block_given? or return key, *sw 480 yield(key, *sw) 481 end 482 end 483 484 def convert(opt = nil, val = nil, *) 485 val 486 end 487 end 488 489 490 # 491 # Map from option/keyword string to object with completion. 492 # 493 class OptionMap < Hash 494 include Completion 495 end 496 497 498 # 499 # Individual switch class. Not important to the user. 500 # 501 # Defined within Switch are several Switch-derived classes: NoArgument, 502 # RequiredArgument, etc. 503 # 504 class Switch 505 attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block 506 507 # 508 # Guesses argument style from +arg+. Returns corresponding 509 # OptionParser::Switch class (OptionalArgument, etc.). 510 # 511 def self.guess(arg) 512 case arg 513 when "" 514 t = self 515 when /\A=?\[/ 516 t = Switch::OptionalArgument 517 when /\A\s+\[/ 518 t = Switch::PlacedArgument 519 else 520 t = Switch::RequiredArgument 521 end 522 self >= t or incompatible_argument_styles(arg, t) 523 t 524 end 525 526 def self.incompatible_argument_styles(arg, t) 527 raise(ArgumentError, "#{arg}: incompatible argument styles\n #{self}, #{t}", 528 ParseError.filter_backtrace(caller(2))) 529 end 530 531 def self.pattern 532 NilClass 533 end 534 535 def initialize(pattern = nil, conv = nil, 536 short = nil, long = nil, arg = nil, 537 desc = ([] if short or long), block = nil, &_block) 538 raise if Array === pattern 539 block ||= _block 540 @pattern, @conv, @short, @long, @arg, @desc, @block = 541 pattern, conv, short, long, arg, desc, block 542 end 543 544 # 545 # Parses +arg+ and returns rest of +arg+ and matched portion to the 546 # argument pattern. Yields when the pattern doesn't match substring. 547 # 548 def parse_arg(arg) 549 pattern or return nil, [arg] 550 unless m = pattern.match(arg) 551 yield(InvalidArgument, arg) 552 return arg, [] 553 end 554 if String === m 555 m = [s = m] 556 else 557 m = m.to_a 558 s = m[0] 559 return nil, m unless String === s 560 end 561 raise InvalidArgument, arg unless arg.rindex(s, 0) 562 return nil, m if s.length == arg.length 563 yield(InvalidArgument, arg) # didn't match whole arg 564 return arg[s.length..-1], m 565 end 566 private :parse_arg 567 568 # 569 # Parses argument, converts and returns +arg+, +block+ and result of 570 # conversion. Yields at semi-error condition instead of raising an 571 # exception. 572 # 573 def conv_arg(arg, val = []) 574 if conv 575 val = conv.call(*val) 576 else 577 val = proc {|v| v}.call(*val) 578 end 579 return arg, block, val 580 end 581 private :conv_arg 582 583 # 584 # Produces the summary text. Each line of the summary is yielded to the 585 # block (without newline). 586 # 587 # +sdone+:: Already summarized short style options keyed hash. 588 # +ldone+:: Already summarized long style options keyed hash. 589 # +width+:: Width of left side (option part). In other words, the right 590 # side (description part) starts after +width+ columns. 591 # +max+:: Maximum width of left side -> the options are filled within 592 # +max+ columns. 593 # +indent+:: Prefix string indents all summarized lines. 594 # 595 def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = "") 596 sopts, lopts = [], [], nil 597 @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short 598 @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long 599 return if sopts.empty? and lopts.empty? # completely hidden 600 601 left = [sopts.join(', ')] 602 right = desc.dup 603 604 while s = lopts.shift 605 l = left[-1].length + s.length 606 l += arg.length if left.size == 1 && arg 607 l < max or sopts.empty? or left << +'' 608 left[-1] << (left[-1].empty? ? ' ' * 4 : ', ') << s 609 end 610 611 if arg 612 left[0] << (left[1] ? arg.sub(/\A(\[?)=/, '\1') + ',' : arg) 613 end 614 mlen = left.collect {|ss| ss.length}.max.to_i 615 while mlen > width and l = left.shift 616 mlen = left.collect {|ss| ss.length}.max.to_i if l.length == mlen 617 if l.length < width and (r = right[0]) and !r.empty? 618 l = l.to_s.ljust(width) + ' ' + r 619 right.shift 620 end 621 yield(indent + l) 622 end 623 624 while begin l = left.shift; r = right.shift; l or r end 625 l = l.to_s.ljust(width) + ' ' + r if r and !r.empty? 626 yield(indent + l) 627 end 628 629 self 630 end 631 632 def add_banner(to) # :nodoc: 633 unless @short or @long 634 s = desc.join 635 to << " [" + s + "]..." unless s.empty? 636 end 637 to 638 end 639 640 def match_nonswitch?(str) # :nodoc: 641 @pattern =~ str unless @short or @long 642 end 643 644 # 645 # Main name of the switch. 646 # 647 def switch_name 648 (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '') 649 end 650 651 def compsys(sdone, ldone) # :nodoc: 652 sopts, lopts = [], [] 653 @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short 654 @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long 655 return if sopts.empty? and lopts.empty? # completely hidden 656 657 (sopts+lopts).each do |opt| 658 # "(-x -c -r)-l[left justify]" 659 if /^--\[no-\](.+)$/ =~ opt 660 o = $1 661 yield("--#{o}", desc.join("")) 662 yield("--no-#{o}", desc.join("")) 663 else 664 yield("#{opt}", desc.join("")) 665 end 666 end 667 end 668 669 # 670 # Switch that takes no arguments. 671 # 672 class NoArgument < self 673 674 # 675 # Raises an exception if any arguments given. 676 # 677 def parse(arg, argv) 678 yield(NeedlessArgument, arg) if arg 679 conv_arg(arg) 680 end 681 682 def self.incompatible_argument_styles(*) 683 end 684 685 def self.pattern 686 Object 687 end 688 end 689 690 # 691 # Switch that takes an argument. 692 # 693 class RequiredArgument < self 694 695 # 696 # Raises an exception if argument is not present. 697 # 698 def parse(arg, argv) 699 unless arg 700 raise MissingArgument if argv.empty? 701 arg = argv.shift 702 end 703 conv_arg(*parse_arg(arg, &method(:raise))) 704 end 705 end 706 707 # 708 # Switch that can omit argument. 709 # 710 class OptionalArgument < self 711 712 # 713 # Parses argument if given, or uses default value. 714 # 715 def parse(arg, argv, &error) 716 if arg 717 conv_arg(*parse_arg(arg, &error)) 718 else 719 conv_arg(arg) 720 end 721 end 722 end 723 724 # 725 # Switch that takes an argument, which does not begin with '-'. 726 # 727 class PlacedArgument < self 728 729 # 730 # Returns nil if argument is not present or begins with '-'. 731 # 732 def parse(arg, argv, &error) 733 if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0])) 734 return nil, block, nil 735 end 736 opt = (val = parse_arg(val, &error))[1] 737 val = conv_arg(*val) 738 if opt and !arg 739 argv.shift 740 else 741 val[0] = nil 742 end 743 val 744 end 745 end 746 end 747 748 # 749 # Simple option list providing mapping from short and/or long option 750 # string to OptionParser::Switch and mapping from acceptable argument to 751 # matching pattern and converter pair. Also provides summary feature. 752 # 753 class List 754 # Map from acceptable argument types to pattern and converter pairs. 755 attr_reader :atype 756 757 # Map from short style option switches to actual switch objects. 758 attr_reader :short 759 760 # Map from long style option switches to actual switch objects. 761 attr_reader :long 762 763 # List of all switches and summary string. 764 attr_reader :list 765 766 # 767 # Just initializes all instance variables. 768 # 769 def initialize 770 @atype = {} 771 @short = OptionMap.new 772 @long = OptionMap.new 773 @list = [] 774 end 775 776 # 777 # See OptionParser.accept. 778 # 779 def accept(t, pat = /.*/m, &block) 780 if pat 781 pat.respond_to?(:match) or 782 raise TypeError, "has no `match'", ParseError.filter_backtrace(caller(2)) 783 else 784 pat = t if t.respond_to?(:match) 785 end 786 unless block 787 block = pat.method(:convert).to_proc if pat.respond_to?(:convert) 788 end 789 @atype[t] = [pat, block] 790 end 791 792 # 793 # See OptionParser.reject. 794 # 795 def reject(t) 796 @atype.delete(t) 797 end 798 799 # 800 # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+. 801 # 802 # +sw+:: OptionParser::Switch instance to be added. 803 # +sopts+:: Short style option list. 804 # +lopts+:: Long style option list. 805 # +nlopts+:: Negated long style options list. 806 # 807 def update(sw, sopts, lopts, nsw = nil, nlopts = nil) 808 sopts.each {|o| @short[o] = sw} if sopts 809 lopts.each {|o| @long[o] = sw} if lopts 810 nlopts.each {|o| @long[o] = nsw} if nsw and nlopts 811 used = @short.invert.update(@long.invert) 812 @list.delete_if {|o| Switch === o and !used[o]} 813 end 814 private :update 815 816 # 817 # Inserts +switch+ at the head of the list, and associates short, long 818 # and negated long options. Arguments are: 819 # 820 # +switch+:: OptionParser::Switch instance to be inserted. 821 # +short_opts+:: List of short style options. 822 # +long_opts+:: List of long style options. 823 # +nolong_opts+:: List of long style options with "no-" prefix. 824 # 825 # prepend(switch, short_opts, long_opts, nolong_opts) 826 # 827 def prepend(*args) 828 update(*args) 829 @list.unshift(args[0]) 830 end 831 832 # 833 # Appends +switch+ at the tail of the list, and associates short, long 834 # and negated long options. Arguments are: 835 # 836 # +switch+:: OptionParser::Switch instance to be inserted. 837 # +short_opts+:: List of short style options. 838 # +long_opts+:: List of long style options. 839 # +nolong_opts+:: List of long style options with "no-" prefix. 840 # 841 # append(switch, short_opts, long_opts, nolong_opts) 842 # 843 def append(*args) 844 update(*args) 845 @list.push(args[0]) 846 end 847 848 # 849 # Searches +key+ in +id+ list. The result is returned or yielded if a 850 # block is given. If it isn't found, nil is returned. 851 # 852 def search(id, key) 853 if list = __send__(id) 854 val = list.fetch(key) {return nil} 855 block_given? ? yield(val) : val 856 end 857 end 858 859 # 860 # Searches list +id+ for +opt+ and the optional patterns for completion 861 # +pat+. If +icase+ is true, the search is case insensitive. The result 862 # is returned or yielded if a block is given. If it isn't found, nil is 863 # returned. 864 # 865 def complete(id, opt, icase = false, *pat, &block) 866 __send__(id).complete(opt, icase, *pat, &block) 867 end 868 869 # 870 # Iterates over each option, passing the option to the +block+. 871 # 872 def each_option(&block) 873 list.each(&block) 874 end 875 876 # 877 # Creates the summary table, passing each line to the +block+ (without 878 # newline). The arguments +args+ are passed along to the summarize 879 # method which is called on every option. 880 # 881 def summarize(*args, &block) 882 sum = [] 883 list.reverse_each do |opt| 884 if opt.respond_to?(:summarize) # perhaps OptionParser::Switch 885 s = [] 886 opt.summarize(*args) {|l| s << l} 887 sum.concat(s.reverse) 888 elsif !opt or opt.empty? 889 sum << "" 890 elsif opt.respond_to?(:each_line) 891 sum.concat([*opt.each_line].reverse) 892 else 893 sum.concat([*opt.each].reverse) 894 end 895 end 896 sum.reverse_each(&block) 897 end 898 899 def add_banner(to) # :nodoc: 900 list.each do |opt| 901 if opt.respond_to?(:add_banner) 902 opt.add_banner(to) 903 end 904 end 905 to 906 end 907 908 def compsys(*args, &block) # :nodoc: 909 list.each do |opt| 910 if opt.respond_to?(:compsys) 911 opt.compsys(*args, &block) 912 end 913 end 914 end 915 end 916 917 # 918 # Hash with completion search feature. See OptionParser::Completion. 919 # 920 class CompletingHash < Hash 921 include Completion 922 923 # 924 # Completion for hash key. 925 # 926 def match(key) 927 *values = fetch(key) { 928 raise AmbiguousArgument, catch(:ambiguous) {return complete(key)} 929 } 930 return key, *values 931 end 932 end 933 934 # :stopdoc: 935 936 # 937 # Enumeration of acceptable argument styles. Possible values are: 938 # 939 # NO_ARGUMENT:: The switch takes no arguments. (:NONE) 940 # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED) 941 # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL) 942 # 943 # Use like --switch=argument (long style) or -Xargument (short style). For 944 # short style, only portion matched to argument pattern is treated as 945 # argument. 946 # 947 ArgumentStyle = {} 948 NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument} 949 RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument} 950 OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument} 951 ArgumentStyle.freeze 952 953 # 954 # Switches common used such as '--', and also provides default 955 # argument classes 956 # 957 DefaultList = List.new 958 DefaultList.short['-'] = Switch::NoArgument.new {} 959 DefaultList.long[''] = Switch::NoArgument.new {throw :terminate} 960 961 962 COMPSYS_HEADER = <<'XXX' # :nodoc: 963 964typeset -A opt_args 965local context state line 966 967_arguments -s -S \ 968XXX 969 970 def compsys(to, name = File.basename($0)) # :nodoc: 971 to << "#compdef #{name}\n" 972 to << COMPSYS_HEADER 973 visit(:compsys, {}, {}) {|o, d| 974 to << %Q[ "#{o}[#{d.gsub(/[\"\[\]]/, '\\\\\&')}]" \\\n] 975 } 976 to << " '*:file:_files' && return 0\n" 977 end 978 979 # 980 # Default options for ARGV, which never appear in option summary. 981 # 982 Officious = {} 983 984 # 985 # --help 986 # Shows option summary. 987 # 988 Officious['help'] = proc do |parser| 989 Switch::NoArgument.new do |arg| 990 puts parser.help 991 exit 992 end 993 end 994 995 # 996 # --*-completion-bash=WORD 997 # Shows candidates for command line completion. 998 # 999 Officious['*-completion-bash'] = proc do |parser| 1000 Switch::RequiredArgument.new do |arg| 1001 puts parser.candidate(arg) 1002 exit 1003 end 1004 end 1005 1006 # 1007 # --*-completion-zsh[=NAME:FILE] 1008 # Creates zsh completion file. 1009 # 1010 Officious['*-completion-zsh'] = proc do |parser| 1011 Switch::OptionalArgument.new do |arg| 1012 parser.compsys(STDOUT, arg) 1013 exit 1014 end 1015 end 1016 1017 # 1018 # --version 1019 # Shows version string if Version is defined. 1020 # 1021 Officious['version'] = proc do |parser| 1022 Switch::OptionalArgument.new do |pkg| 1023 if pkg 1024 begin 1025 require 'optparse/version' 1026 rescue LoadError 1027 else 1028 show_version(*pkg.split(/,/)) or 1029 abort("#{parser.program_name}: no version found in package #{pkg}") 1030 exit 1031 end 1032 end 1033 v = parser.ver or abort("#{parser.program_name}: version unknown") 1034 puts v 1035 exit 1036 end 1037 end 1038 1039 # :startdoc: 1040 1041 # 1042 # Class methods 1043 # 1044 1045 # 1046 # Initializes a new instance and evaluates the optional block in context 1047 # of the instance. Arguments +args+ are passed to #new, see there for 1048 # description of parameters. 1049 # 1050 # This method is *deprecated*, its behavior corresponds to the older #new 1051 # method. 1052 # 1053 def self.with(*args, &block) 1054 opts = new(*args) 1055 opts.instance_eval(&block) 1056 opts 1057 end 1058 1059 # 1060 # Returns an incremented value of +default+ according to +arg+. 1061 # 1062 def self.inc(arg, default = nil) 1063 case arg 1064 when Integer 1065 arg.nonzero? 1066 when nil 1067 default.to_i + 1 1068 end 1069 end 1070 def inc(*args) 1071 self.class.inc(*args) 1072 end 1073 1074 # 1075 # Initializes the instance and yields itself if called with a block. 1076 # 1077 # +banner+:: Banner message. 1078 # +width+:: Summary width. 1079 # +indent+:: Summary indent. 1080 # 1081 def initialize(banner = nil, width = 32, indent = ' ' * 4) 1082 @stack = [DefaultList, List.new, List.new] 1083 @program_name = nil 1084 @banner = banner 1085 @summary_width = width 1086 @summary_indent = indent 1087 @default_argv = ARGV 1088 add_officious 1089 yield self if block_given? 1090 end 1091 1092 def add_officious # :nodoc: 1093 list = base() 1094 Officious.each do |opt, block| 1095 list.long[opt] ||= block.call(self) 1096 end 1097 end 1098 1099 # 1100 # Terminates option parsing. Optional parameter +arg+ is a string pushed 1101 # back to be the first non-option argument. 1102 # 1103 def terminate(arg = nil) 1104 self.class.terminate(arg) 1105 end 1106 def self.terminate(arg = nil) 1107 throw :terminate, arg 1108 end 1109 1110 @stack = [DefaultList] 1111 def self.top() DefaultList end 1112 1113 # 1114 # Directs to accept specified class +t+. The argument string is passed to 1115 # the block in which it should be converted to the desired class. 1116 # 1117 # +t+:: Argument class specifier, any object including Class. 1118 # +pat+:: Pattern for argument, defaults to +t+ if it responds to match. 1119 # 1120 # accept(t, pat, &block) 1121 # 1122 def accept(*args, &blk) top.accept(*args, &blk) end 1123 # 1124 # See #accept. 1125 # 1126 def self.accept(*args, &blk) top.accept(*args, &blk) end 1127 1128 # 1129 # Directs to reject specified class argument. 1130 # 1131 # +t+:: Argument class specifier, any object including Class. 1132 # 1133 # reject(t) 1134 # 1135 def reject(*args, &blk) top.reject(*args, &blk) end 1136 # 1137 # See #reject. 1138 # 1139 def self.reject(*args, &blk) top.reject(*args, &blk) end 1140 1141 # 1142 # Instance methods 1143 # 1144 1145 # Heading banner preceding summary. 1146 attr_writer :banner 1147 1148 # Program name to be emitted in error message and default banner, 1149 # defaults to $0. 1150 attr_writer :program_name 1151 1152 # Width for option list portion of summary. Must be Numeric. 1153 attr_accessor :summary_width 1154 1155 # Indentation for summary. Must be String (or have + String method). 1156 attr_accessor :summary_indent 1157 1158 # Strings to be parsed in default. 1159 attr_accessor :default_argv 1160 1161 # 1162 # Heading banner preceding summary. 1163 # 1164 def banner 1165 unless @banner 1166 @banner = +"Usage: #{program_name} [options]" 1167 visit(:add_banner, @banner) 1168 end 1169 @banner 1170 end 1171 1172 # 1173 # Program name to be emitted in error message and default banner, defaults 1174 # to $0. 1175 # 1176 def program_name 1177 @program_name || File.basename($0, '.*') 1178 end 1179 1180 # for experimental cascading :-) 1181 alias set_banner banner= 1182 alias set_program_name program_name= 1183 alias set_summary_width summary_width= 1184 alias set_summary_indent summary_indent= 1185 1186 # Version 1187 attr_writer :version 1188 # Release code 1189 attr_writer :release 1190 1191 # 1192 # Version 1193 # 1194 def version 1195 (defined?(@version) && @version) || (defined?(::Version) && ::Version) 1196 end 1197 1198 # 1199 # Release code 1200 # 1201 def release 1202 (defined?(@release) && @release) || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE) 1203 end 1204 1205 # 1206 # Returns version string from program_name, version and release. 1207 # 1208 def ver 1209 if v = version 1210 str = +"#{program_name} #{[v].join('.')}" 1211 str << " (#{v})" if v = release 1212 str 1213 end 1214 end 1215 1216 def warn(mesg = $!) 1217 super("#{program_name}: #{mesg}") 1218 end 1219 1220 def abort(mesg = $!) 1221 super("#{program_name}: #{mesg}") 1222 end 1223 1224 # 1225 # Subject of #on / #on_head, #accept / #reject 1226 # 1227 def top 1228 @stack[-1] 1229 end 1230 1231 # 1232 # Subject of #on_tail. 1233 # 1234 def base 1235 @stack[1] 1236 end 1237 1238 # 1239 # Pushes a new List. 1240 # 1241 def new 1242 @stack.push(List.new) 1243 if block_given? 1244 yield self 1245 else 1246 self 1247 end 1248 end 1249 1250 # 1251 # Removes the last List. 1252 # 1253 def remove 1254 @stack.pop 1255 end 1256 1257 # 1258 # Puts option summary into +to+ and returns +to+. Yields each line if 1259 # a block is given. 1260 # 1261 # +to+:: Output destination, which must have method <<. Defaults to []. 1262 # +width+:: Width of left side, defaults to @summary_width. 1263 # +max+:: Maximum length allowed for left side, defaults to +width+ - 1. 1264 # +indent+:: Indentation, defaults to @summary_indent. 1265 # 1266 def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk) 1267 nl = "\n" 1268 blk ||= proc {|l| to << (l.index(nl, -1) ? l : l + nl)} 1269 visit(:summarize, {}, {}, width, max, indent, &blk) 1270 to 1271 end 1272 1273 # 1274 # Returns option summary string. 1275 # 1276 def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end 1277 alias to_s help 1278 1279 # 1280 # Returns option summary list. 1281 # 1282 def to_a; summarize("#{banner}".split(/^/)) end 1283 1284 # 1285 # Checks if an argument is given twice, in which case an ArgumentError is 1286 # raised. Called from OptionParser#switch only. 1287 # 1288 # +obj+:: New argument. 1289 # +prv+:: Previously specified argument. 1290 # +msg+:: Exception message. 1291 # 1292 def notwice(obj, prv, msg) 1293 unless !prv or prv == obj 1294 raise(ArgumentError, "argument #{msg} given twice: #{obj}", 1295 ParseError.filter_backtrace(caller(2))) 1296 end 1297 obj 1298 end 1299 private :notwice 1300 1301 SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc: 1302 # 1303 # Creates an OptionParser::Switch from the parameters. The parsed argument 1304 # value is passed to the given block, where it can be processed. 1305 # 1306 # See at the beginning of OptionParser for some full examples. 1307 # 1308 # +opts+ can include the following elements: 1309 # 1310 # [Argument style:] 1311 # One of the following: 1312 # :NONE, :REQUIRED, :OPTIONAL 1313 # 1314 # [Argument pattern:] 1315 # Acceptable option argument format, must be pre-defined with 1316 # OptionParser.accept or OptionParser#accept, or Regexp. This can appear 1317 # once or assigned as String if not present, otherwise causes an 1318 # ArgumentError. Examples: 1319 # Float, Time, Array 1320 # 1321 # [Possible argument values:] 1322 # Hash or Array. 1323 # [:text, :binary, :auto] 1324 # %w[iso-2022-jp shift_jis euc-jp utf8 binary] 1325 # { "jis" => "iso-2022-jp", "sjis" => "shift_jis" } 1326 # 1327 # [Long style switch:] 1328 # Specifies a long style switch which takes a mandatory, optional or no 1329 # argument. It's a string of the following form: 1330 # "--switch=MANDATORY" or "--switch MANDATORY" 1331 # "--switch[=OPTIONAL]" 1332 # "--switch" 1333 # 1334 # [Short style switch:] 1335 # Specifies short style switch which takes a mandatory, optional or no 1336 # argument. It's a string of the following form: 1337 # "-xMANDATORY" 1338 # "-x[OPTIONAL]" 1339 # "-x" 1340 # There is also a special form which matches character range (not full 1341 # set of regular expression): 1342 # "-[a-z]MANDATORY" 1343 # "-[a-z][OPTIONAL]" 1344 # "-[a-z]" 1345 # 1346 # [Argument style and description:] 1347 # Instead of specifying mandatory or optional arguments directly in the 1348 # switch parameter, this separate parameter can be used. 1349 # "=MANDATORY" 1350 # "=[OPTIONAL]" 1351 # 1352 # [Description:] 1353 # Description string for the option. 1354 # "Run verbosely" 1355 # If you give multiple description strings, each string will be printed 1356 # line by line. 1357 # 1358 # [Handler:] 1359 # Handler for the parsed argument value. Either give a block or pass a 1360 # Proc or Method as an argument. 1361 # 1362 def make_switch(opts, block = nil) 1363 short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], [] 1364 ldesc, sdesc, desc, arg = [], [], [] 1365 default_style = Switch::NoArgument 1366 default_pattern = nil 1367 klass = nil 1368 q, a = nil 1369 has_arg = false 1370 1371 opts.each do |o| 1372 # argument class 1373 next if search(:atype, o) do |pat, c| 1374 klass = notwice(o, klass, 'type') 1375 if not_style and not_style != Switch::NoArgument 1376 not_pattern, not_conv = pat, c 1377 else 1378 default_pattern, conv = pat, c 1379 end 1380 end 1381 1382 # directly specified pattern(any object possible to match) 1383 if (!(String === o || Symbol === o)) and o.respond_to?(:match) 1384 pattern = notwice(o, pattern, 'pattern') 1385 if pattern.respond_to?(:convert) 1386 conv = pattern.method(:convert).to_proc 1387 else 1388 conv = SPLAT_PROC 1389 end 1390 next 1391 end 1392 1393 # anything others 1394 case o 1395 when Proc, Method 1396 block = notwice(o, block, 'block') 1397 when Array, Hash 1398 case pattern 1399 when CompletingHash 1400 when nil 1401 pattern = CompletingHash.new 1402 conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert) 1403 else 1404 raise ArgumentError, "argument pattern given twice" 1405 end 1406 o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}} 1407 when Module 1408 raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4)) 1409 when *ArgumentStyle.keys 1410 style = notwice(ArgumentStyle[o], style, 'style') 1411 when /^--no-([^\[\]=\s]*)(.+)?/ 1412 q, a = $1, $2 1413 o = notwice(a ? Object : TrueClass, klass, 'type') 1414 not_pattern, not_conv = search(:atype, o) unless not_style 1415 not_style = (not_style || default_style).guess(arg = a) if a 1416 default_style = Switch::NoArgument 1417 default_pattern, conv = search(:atype, FalseClass) unless default_pattern 1418 ldesc << "--no-#{q}" 1419 (q = q.downcase).tr!('_', '-') 1420 long << "no-#{q}" 1421 nolong << q 1422 when /^--\[no-\]([^\[\]=\s]*)(.+)?/ 1423 q, a = $1, $2 1424 o = notwice(a ? Object : TrueClass, klass, 'type') 1425 if a 1426 default_style = default_style.guess(arg = a) 1427 default_pattern, conv = search(:atype, o) unless default_pattern 1428 end 1429 ldesc << "--[no-]#{q}" 1430 (o = q.downcase).tr!('_', '-') 1431 long << o 1432 not_pattern, not_conv = search(:atype, FalseClass) unless not_style 1433 not_style = Switch::NoArgument 1434 nolong << "no-#{o}" 1435 when /^--([^\[\]=\s]*)(.+)?/ 1436 q, a = $1, $2 1437 if a 1438 o = notwice(NilClass, klass, 'type') 1439 default_style = default_style.guess(arg = a) 1440 default_pattern, conv = search(:atype, o) unless default_pattern 1441 end 1442 ldesc << "--#{q}" 1443 (o = q.downcase).tr!('_', '-') 1444 long << o 1445 when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/ 1446 q, a = $1, $2 1447 o = notwice(Object, klass, 'type') 1448 if a 1449 default_style = default_style.guess(arg = a) 1450 default_pattern, conv = search(:atype, o) unless default_pattern 1451 else 1452 has_arg = true 1453 end 1454 sdesc << "-#{q}" 1455 short << Regexp.new(q) 1456 when /^-(.)(.+)?/ 1457 q, a = $1, $2 1458 if a 1459 o = notwice(NilClass, klass, 'type') 1460 default_style = default_style.guess(arg = a) 1461 default_pattern, conv = search(:atype, o) unless default_pattern 1462 end 1463 sdesc << "-#{q}" 1464 short << q 1465 when /^=/ 1466 style = notwice(default_style.guess(arg = o), style, 'style') 1467 default_pattern, conv = search(:atype, Object) unless default_pattern 1468 else 1469 desc.push(o) 1470 end 1471 end 1472 1473 default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern 1474 if !(short.empty? and long.empty?) 1475 if has_arg and default_style == Switch::NoArgument 1476 default_style = Switch::RequiredArgument 1477 end 1478 s = (style || default_style).new(pattern || default_pattern, 1479 conv, sdesc, ldesc, arg, desc, block) 1480 elsif !block 1481 if style or pattern 1482 raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller) 1483 end 1484 s = desc 1485 else 1486 short << pattern 1487 s = (style || default_style).new(pattern, 1488 conv, nil, nil, arg, desc, block) 1489 end 1490 return s, short, long, 1491 (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style), 1492 nolong 1493 end 1494 1495 def define(*opts, &block) 1496 top.append(*(sw = make_switch(opts, block))) 1497 sw[0] 1498 end 1499 1500 # 1501 # Add option switch and handler. See #make_switch for an explanation of 1502 # parameters. 1503 # 1504 def on(*opts, &block) 1505 define(*opts, &block) 1506 self 1507 end 1508 alias def_option define 1509 1510 def define_head(*opts, &block) 1511 top.prepend(*(sw = make_switch(opts, block))) 1512 sw[0] 1513 end 1514 1515 # 1516 # Add option switch like with #on, but at head of summary. 1517 # 1518 def on_head(*opts, &block) 1519 define_head(*opts, &block) 1520 self 1521 end 1522 alias def_head_option define_head 1523 1524 def define_tail(*opts, &block) 1525 base.append(*(sw = make_switch(opts, block))) 1526 sw[0] 1527 end 1528 1529 # 1530 # Add option switch like with #on, but at tail of summary. 1531 # 1532 def on_tail(*opts, &block) 1533 define_tail(*opts, &block) 1534 self 1535 end 1536 alias def_tail_option define_tail 1537 1538 # 1539 # Add separator in summary. 1540 # 1541 def separator(string) 1542 top.append(string, nil, nil) 1543 end 1544 1545 # 1546 # Parses command line arguments +argv+ in order. When a block is given, 1547 # each non-option argument is yielded. 1548 # 1549 # Returns the rest of +argv+ left unparsed. 1550 # 1551 def order(*argv, into: nil, &nonopt) 1552 argv = argv[0].dup if argv.size == 1 and Array === argv[0] 1553 order!(argv, into: into, &nonopt) 1554 end 1555 1556 # 1557 # Same as #order, but removes switches destructively. 1558 # Non-option arguments remain in +argv+. 1559 # 1560 def order!(argv = default_argv, into: nil, &nonopt) 1561 setter = ->(name, val) {into[name.to_sym] = val} if into 1562 parse_in_order(argv, setter, &nonopt) 1563 end 1564 1565 def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc: 1566 opt, arg, val, rest = nil 1567 nonopt ||= proc {|a| throw :terminate, a} 1568 argv.unshift(arg) if arg = catch(:terminate) { 1569 while arg = argv.shift 1570 case arg 1571 # long option 1572 when /\A--([^=]*)(?:=(.*))?/m 1573 opt, rest = $1, $2 1574 opt.tr!('_', '-') 1575 begin 1576 sw, = complete(:long, opt, true) 1577 rescue ParseError 1578 raise $!.set_option(arg, true) 1579 end 1580 begin 1581 opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)} 1582 val = cb.call(val) if cb 1583 setter.call(sw.switch_name, val) if setter 1584 rescue ParseError 1585 raise $!.set_option(arg, rest) 1586 end 1587 1588 # short option 1589 when /\A-(.)((=).*|.+)?/m 1590 eq, rest, opt = $3, $2, $1 1591 has_arg, val = eq, rest 1592 begin 1593 sw, = search(:short, opt) 1594 unless sw 1595 begin 1596 sw, = complete(:short, opt) 1597 # short option matched. 1598 val = arg.delete_prefix('-') 1599 has_arg = true 1600 rescue InvalidOption 1601 # if no short options match, try completion with long 1602 # options. 1603 sw, = complete(:long, opt) 1604 eq ||= !rest 1605 end 1606 end 1607 rescue ParseError 1608 raise $!.set_option(arg, true) 1609 end 1610 begin 1611 opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq} 1612 raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}" 1613 argv.unshift(opt) if opt and (!rest or (opt = opt.sub(/\A-*/, '-')) != '-') 1614 val = cb.call(val) if cb 1615 setter.call(sw.switch_name, val) if setter 1616 rescue ParseError 1617 raise $!.set_option(arg, arg.length > 2) 1618 end 1619 1620 # non-option argument 1621 else 1622 catch(:prune) do 1623 visit(:each_option) do |sw0| 1624 sw = sw0 1625 sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg) 1626 end 1627 nonopt.call(arg) 1628 end 1629 end 1630 end 1631 1632 nil 1633 } 1634 1635 visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern} 1636 1637 argv 1638 end 1639 private :parse_in_order 1640 1641 # 1642 # Parses command line arguments +argv+ in permutation mode and returns 1643 # list of non-option arguments. 1644 # 1645 def permute(*argv, into: nil) 1646 argv = argv[0].dup if argv.size == 1 and Array === argv[0] 1647 permute!(argv, into: into) 1648 end 1649 1650 # 1651 # Same as #permute, but removes switches destructively. 1652 # Non-option arguments remain in +argv+. 1653 # 1654 def permute!(argv = default_argv, into: nil) 1655 nonopts = [] 1656 order!(argv, into: into, &nonopts.method(:<<)) 1657 argv[0, 0] = nonopts 1658 argv 1659 end 1660 1661 # 1662 # Parses command line arguments +argv+ in order when environment variable 1663 # POSIXLY_CORRECT is set, and in permutation mode otherwise. 1664 # 1665 def parse(*argv, into: nil) 1666 argv = argv[0].dup if argv.size == 1 and Array === argv[0] 1667 parse!(argv, into: into) 1668 end 1669 1670 # 1671 # Same as #parse, but removes switches destructively. 1672 # Non-option arguments remain in +argv+. 1673 # 1674 def parse!(argv = default_argv, into: nil) 1675 if ENV.include?('POSIXLY_CORRECT') 1676 order!(argv, into: into) 1677 else 1678 permute!(argv, into: into) 1679 end 1680 end 1681 1682 # 1683 # Wrapper method for getopts.rb. 1684 # 1685 # params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option") 1686 # # params["a"] = true # -a 1687 # # params["b"] = "1" # -b1 1688 # # params["foo"] = "1" # --foo 1689 # # params["bar"] = "x" # --bar x 1690 # # params["zot"] = "z" # --zot Z 1691 # 1692 def getopts(*args) 1693 argv = Array === args.first ? args.shift : default_argv 1694 single_options, *long_options = *args 1695 1696 result = {} 1697 1698 single_options.scan(/(.)(:)?/) do |opt, val| 1699 if val 1700 result[opt] = nil 1701 define("-#{opt} VAL") 1702 else 1703 result[opt] = false 1704 define("-#{opt}") 1705 end 1706 end if single_options 1707 1708 long_options.each do |arg| 1709 arg, desc = arg.split(';', 2) 1710 opt, val = arg.split(':', 2) 1711 if val 1712 result[opt] = val.empty? ? nil : val 1713 define("--#{opt}=#{result[opt] || "VAL"}", *[desc].compact) 1714 else 1715 result[opt] = false 1716 define("--#{opt}", *[desc].compact) 1717 end 1718 end 1719 1720 parse_in_order(argv, result.method(:[]=)) 1721 result 1722 end 1723 1724 # 1725 # See #getopts. 1726 # 1727 def self.getopts(*args) 1728 new.getopts(*args) 1729 end 1730 1731 # 1732 # Traverses @stack, sending each element method +id+ with +args+ and 1733 # +block+. 1734 # 1735 def visit(id, *args, &block) 1736 @stack.reverse_each do |el| 1737 el.send(id, *args, &block) 1738 end 1739 nil 1740 end 1741 private :visit 1742 1743 # 1744 # Searches +key+ in @stack for +id+ hash and returns or yields the result. 1745 # 1746 def search(id, key) 1747 block_given = block_given? 1748 visit(:search, id, key) do |k| 1749 return block_given ? yield(k) : k 1750 end 1751 end 1752 private :search 1753 1754 # 1755 # Completes shortened long style option switch and returns pair of 1756 # canonical switch and switch descriptor OptionParser::Switch. 1757 # 1758 # +typ+:: Searching table. 1759 # +opt+:: Searching key. 1760 # +icase+:: Search case insensitive if true. 1761 # +pat+:: Optional pattern for completion. 1762 # 1763 def complete(typ, opt, icase = false, *pat) 1764 if pat.empty? 1765 search(typ, opt) {|sw| return [sw, opt]} # exact match or... 1766 end 1767 raise AmbiguousOption, catch(:ambiguous) { 1768 visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw} 1769 raise InvalidOption, opt 1770 } 1771 end 1772 private :complete 1773 1774 def candidate(word) 1775 list = [] 1776 case word 1777 when '-' 1778 long = short = true 1779 when /\A--/ 1780 word, arg = word.split(/=/, 2) 1781 argpat = Completion.regexp(arg, false) if arg and !arg.empty? 1782 long = true 1783 when /\A-/ 1784 short = true 1785 end 1786 pat = Completion.regexp(word, long) 1787 visit(:each_option) do |opt| 1788 next unless Switch === opt 1789 opts = (long ? opt.long : []) + (short ? opt.short : []) 1790 opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat 1791 if /\A=/ =~ opt.arg 1792 opts.map! {|sw| sw + "="} 1793 if arg and CompletingHash === opt.pattern 1794 if opts = opt.pattern.candidate(arg, false, argpat) 1795 opts.map!(&:last) 1796 end 1797 end 1798 end 1799 list.concat(opts) 1800 end 1801 list 1802 end 1803 1804 # 1805 # Loads options from file names as +filename+. Does nothing when the file 1806 # is not present. Returns whether successfully loaded. 1807 # 1808 # +filename+ defaults to basename of the program without suffix in a 1809 # directory ~/.options. 1810 # 1811 def load(filename = nil) 1812 begin 1813 filename ||= File.expand_path(File.basename($0, '.*'), '~/.options') 1814 rescue 1815 return false 1816 end 1817 begin 1818 parse(*IO.readlines(filename).each {|s| s.chomp!}) 1819 true 1820 rescue Errno::ENOENT, Errno::ENOTDIR 1821 false 1822 end 1823 end 1824 1825 # 1826 # Parses environment variable +env+ or its uppercase with splitting like a 1827 # shell. 1828 # 1829 # +env+ defaults to the basename of the program. 1830 # 1831 def environment(env = File.basename($0, '.*')) 1832 env = ENV[env] || ENV[env.upcase] or return 1833 require 'shellwords' 1834 parse(*Shellwords.shellwords(env)) 1835 end 1836 1837 # 1838 # Acceptable argument classes 1839 # 1840 1841 # 1842 # Any string and no conversion. This is fall-back. 1843 # 1844 accept(Object) {|s,|s or s.nil?} 1845 1846 accept(NilClass) {|s,|s} 1847 1848 # 1849 # Any non-empty string, and no conversion. 1850 # 1851 accept(String, /.+/m) {|s,*|s} 1852 1853 # 1854 # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal 1855 # for 0x, and decimal for others; with optional sign prefix. Converts to 1856 # Integer. 1857 # 1858 decimal = '\d+(?:_\d+)*' 1859 binary = 'b[01]+(?:_[01]+)*' 1860 hex = 'x[\da-f]+(?:_[\da-f]+)*' 1861 octal = "0(?:[0-7]+(?:_[0-7]+)*|#{binary}|#{hex})?" 1862 integer = "#{octal}|#{decimal}" 1863 1864 accept(Integer, %r"\A[-+]?(?:#{integer})\z"io) {|s,| 1865 begin 1866 Integer(s) 1867 rescue ArgumentError 1868 raise OptionParser::InvalidArgument, s 1869 end if s 1870 } 1871 1872 # 1873 # Float number format, and converts to Float. 1874 # 1875 float = "(?:#{decimal}(?=(.)?)(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?" 1876 floatpat = %r"\A[-+]?#{float}\z"io 1877 accept(Float, floatpat) {|s,| s.to_f if s} 1878 1879 # 1880 # Generic numeric format, converts to Integer for integer format, Float 1881 # for float format, and Rational for rational format. 1882 # 1883 real = "[-+]?(?:#{octal}|#{float})" 1884 accept(Numeric, /\A(#{real})(?:\/(#{real}))?\z/io) {|s, d, f, n,| 1885 if n 1886 Rational(d, n) 1887 elsif f 1888 Float(s) 1889 else 1890 Integer(s) 1891 end 1892 } 1893 1894 # 1895 # Decimal integer format, to be converted to Integer. 1896 # 1897 DecimalInteger = /\A[-+]?#{decimal}\z/io 1898 accept(DecimalInteger, DecimalInteger) {|s,| 1899 begin 1900 Integer(s, 10) 1901 rescue ArgumentError 1902 raise OptionParser::InvalidArgument, s 1903 end if s 1904 } 1905 1906 # 1907 # Ruby/C like octal/hexadecimal/binary integer format, to be converted to 1908 # Integer. 1909 # 1910 OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))\z/io 1911 accept(OctalInteger, OctalInteger) {|s,| 1912 begin 1913 Integer(s, 8) 1914 rescue ArgumentError 1915 raise OptionParser::InvalidArgument, s 1916 end if s 1917 } 1918 1919 # 1920 # Decimal integer/float number format, to be converted to Integer for 1921 # integer format, Float for float format. 1922 # 1923 DecimalNumeric = floatpat # decimal integer is allowed as float also. 1924 accept(DecimalNumeric, floatpat) {|s, f| 1925 begin 1926 if f 1927 Float(s) 1928 else 1929 Integer(s) 1930 end 1931 rescue ArgumentError 1932 raise OptionParser::InvalidArgument, s 1933 end if s 1934 } 1935 1936 # 1937 # Boolean switch, which means whether it is present or not, whether it is 1938 # absent or not with prefix no-, or it takes an argument 1939 # yes/no/true/false/+/-. 1940 # 1941 yesno = CompletingHash.new 1942 %w[- no false].each {|el| yesno[el] = false} 1943 %w[+ yes true].each {|el| yesno[el] = true} 1944 yesno['nil'] = false # should be nil? 1945 accept(TrueClass, yesno) {|arg, val| val == nil or val} 1946 # 1947 # Similar to TrueClass, but defaults to false. 1948 # 1949 accept(FalseClass, yesno) {|arg, val| val != nil and val} 1950 1951 # 1952 # List of strings separated by ",". 1953 # 1954 accept(Array) do |s, | 1955 if s 1956 s = s.split(',').collect {|ss| ss unless ss.empty?} 1957 end 1958 s 1959 end 1960 1961 # 1962 # Regular expression with options. 1963 # 1964 accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o| 1965 f = 0 1966 if o 1967 f |= Regexp::IGNORECASE if /i/ =~ o 1968 f |= Regexp::MULTILINE if /m/ =~ o 1969 f |= Regexp::EXTENDED if /x/ =~ o 1970 k = o.delete("imx") 1971 k = nil if k.empty? 1972 end 1973 Regexp.new(s || all, f, k) 1974 end 1975 1976 # 1977 # Exceptions 1978 # 1979 1980 # 1981 # Base class of exceptions from OptionParser. 1982 # 1983 class ParseError < RuntimeError 1984 # Reason which caused the error. 1985 Reason = 'parse error' 1986 1987 def initialize(*args) 1988 @args = args 1989 @reason = nil 1990 end 1991 1992 attr_reader :args 1993 attr_writer :reason 1994 1995 # 1996 # Pushes back erred argument(s) to +argv+. 1997 # 1998 def recover(argv) 1999 argv[0, 0] = @args 2000 argv 2001 end 2002 2003 def self.filter_backtrace(array) 2004 unless $DEBUG 2005 array.delete_if(&%r"\A#{Regexp.quote(__FILE__)}:"o.method(:=~)) 2006 end 2007 array 2008 end 2009 2010 def set_backtrace(array) 2011 super(self.class.filter_backtrace(array)) 2012 end 2013 2014 def set_option(opt, eq) 2015 if eq 2016 @args[0] = opt 2017 else 2018 @args.unshift(opt) 2019 end 2020 self 2021 end 2022 2023 # 2024 # Returns error reason. Override this for I18N. 2025 # 2026 def reason 2027 @reason || self.class::Reason 2028 end 2029 2030 def inspect 2031 "#<#{self.class}: #{args.join(' ')}>" 2032 end 2033 2034 # 2035 # Default stringizing method to emit standard error message. 2036 # 2037 def message 2038 reason + ': ' + args.join(' ') 2039 end 2040 2041 alias to_s message 2042 end 2043 2044 # 2045 # Raises when ambiguously completable string is encountered. 2046 # 2047 class AmbiguousOption < ParseError 2048 const_set(:Reason, 'ambiguous option') 2049 end 2050 2051 # 2052 # Raises when there is an argument for a switch which takes no argument. 2053 # 2054 class NeedlessArgument < ParseError 2055 const_set(:Reason, 'needless argument') 2056 end 2057 2058 # 2059 # Raises when a switch with mandatory argument has no argument. 2060 # 2061 class MissingArgument < ParseError 2062 const_set(:Reason, 'missing argument') 2063 end 2064 2065 # 2066 # Raises when switch is undefined. 2067 # 2068 class InvalidOption < ParseError 2069 const_set(:Reason, 'invalid option') 2070 end 2071 2072 # 2073 # Raises when the given argument does not match required format. 2074 # 2075 class InvalidArgument < ParseError 2076 const_set(:Reason, 'invalid argument') 2077 end 2078 2079 # 2080 # Raises when the given argument word can't be completed uniquely. 2081 # 2082 class AmbiguousArgument < InvalidArgument 2083 const_set(:Reason, 'ambiguous argument') 2084 end 2085 2086 # 2087 # Miscellaneous 2088 # 2089 2090 # 2091 # Extends command line arguments array (ARGV) to parse itself. 2092 # 2093 module Arguable 2094 2095 # 2096 # Sets OptionParser object, when +opt+ is +false+ or +nil+, methods 2097 # OptionParser::Arguable#options and OptionParser::Arguable#options= are 2098 # undefined. Thus, there is no ways to access the OptionParser object 2099 # via the receiver object. 2100 # 2101 def options=(opt) 2102 unless @optparse = opt 2103 class << self 2104 undef_method(:options) 2105 undef_method(:options=) 2106 end 2107 end 2108 end 2109 2110 # 2111 # Actual OptionParser object, automatically created if nonexistent. 2112 # 2113 # If called with a block, yields the OptionParser object and returns the 2114 # result of the block. If an OptionParser::ParseError exception occurs 2115 # in the block, it is rescued, a error message printed to STDERR and 2116 # +nil+ returned. 2117 # 2118 def options 2119 @optparse ||= OptionParser.new 2120 @optparse.default_argv = self 2121 block_given? or return @optparse 2122 begin 2123 yield @optparse 2124 rescue ParseError 2125 @optparse.warn $! 2126 nil 2127 end 2128 end 2129 2130 # 2131 # Parses +self+ destructively in order and returns +self+ containing the 2132 # rest arguments left unparsed. 2133 # 2134 def order!(&blk) options.order!(self, &blk) end 2135 2136 # 2137 # Parses +self+ destructively in permutation mode and returns +self+ 2138 # containing the rest arguments left unparsed. 2139 # 2140 def permute!() options.permute!(self) end 2141 2142 # 2143 # Parses +self+ destructively and returns +self+ containing the 2144 # rest arguments left unparsed. 2145 # 2146 def parse!() options.parse!(self) end 2147 2148 # 2149 # Substitution of getopts is possible as follows. Also see 2150 # OptionParser#getopts. 2151 # 2152 # def getopts(*args) 2153 # ($OPT = ARGV.getopts(*args)).each do |opt, val| 2154 # eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val" 2155 # end 2156 # rescue OptionParser::ParseError 2157 # end 2158 # 2159 def getopts(*args) 2160 options.getopts(self, *args) 2161 end 2162 2163 # 2164 # Initializes instance variable. 2165 # 2166 def self.extend_object(obj) 2167 super 2168 obj.instance_eval {@optparse = nil} 2169 end 2170 def initialize(*args) 2171 super 2172 @optparse = nil 2173 end 2174 end 2175 2176 # 2177 # Acceptable argument classes. Now contains DecimalInteger, OctalInteger 2178 # and DecimalNumeric. See Acceptable argument classes (in source code). 2179 # 2180 module Acceptables 2181 const_set(:DecimalInteger, OptionParser::DecimalInteger) 2182 const_set(:OctalInteger, OptionParser::OctalInteger) 2183 const_set(:DecimalNumeric, OptionParser::DecimalNumeric) 2184 end 2185end 2186 2187# ARGV is arguable by OptionParser 2188ARGV.extend(OptionParser::Arguable) 2189 2190# An alias for OptionParser. 2191OptParse = OptionParser # :nodoc: 2192