PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Util/IronRuby/lib/ruby/1.8/optparse.rb

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