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