PageRenderTime 78ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/optparse.rb

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