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