From f2dfae7ea0258fcde14d9938c00dc894b7b3ec39 Mon Sep 17 00:00:00 2001 From: knu Date: Mon, 4 Mar 2002 21:15:47 +0000 Subject: [PATCH] * lib/getopts.rb: Rewrite to fix some bugs and complete features. - Accept options with the colon in the first argument; getopts("a:bcd:") is equivalent to getopts("bc", "a:", "d:"). - Do not discard the argument that caused an error. - Do not discard '-', which commonly stands for stdin. - Allow specifying a long option with a value using '='. (command --long-option=value) - Stop reading options when it meets a non-option argument. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 11 ++++ lib/getopts.rb | 149 +++++++++++++++++++++++-------------------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4af566e71f..60633b822c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Tue Mar 5 05:56:29 2002 Akinori MUSHA + + * lib/getopts.rb: Rewrite to fix some bugs and complete features. + - Accept options with the colon in the first argument; + getopts("a:bcd:") is equivalent to getopts("bc", "a:", "d:"). + - Do not discard the argument that caused an error. + - Do not discard '-', which commonly stands for stdin. + - Allow specifying a long option with a value using '='. + (command --long-option=value) + - Stop reading options when it meets a non-option argument. + Mon Mar 4 13:19:18 2002 Akinori MUSHA * ext/extmk.rb.in (dir_config): Sync with mkmf.rb: Fix a bug where diff --git a/lib/getopts.rb b/lib/getopts.rb index 8a5917e794..e29e4211e2 100644 --- a/lib/getopts.rb +++ b/lib/getopts.rb @@ -11,117 +11,106 @@ # 2000-03-21 # modified by Minero Aoki # +# 2002-03-05 +# rewritten by Akinori MUSHA +# $RCS_ID=%q$Header$ -def getopts( single_opts, *options ) - single_opts_exp = (single_opts && !single_opts.empty?) ? - /[#{single_opts}]/ : nil - single_colon_exp = nil - single_colon = nil - opt = arg = val = nil +def getopts(single_options = '', *options) boolopts = {} valopts = {} - argv = ARGV - newargv = [] # - # set default + # set defaults # - if single_opts then - single_opts.each_byte do |byte| - boolopts[ byte.chr ] = false - end -end - unless options.empty? then - single_colon = '' - - options.each do |opt| - m = /\A([^:]+):(.*)\z/.match( opt ) - if m then - valopts[ m[1] ] = m[2].empty? ? 0 : m[2] - else - boolopts[ opt ] = false -end - end - valopts.each do |opt, dflt| - if opt.size == 1 then - single_colon << opt -end - end - - if single_colon.empty? then - single_colon = single_colon_exp = nil - else - single_colon_exp = /[#{single_colon}]/ + single_options.scan(/.:?/) do |opt| + if opt.size == 1 + boolopts[opt] = false + else + valopts[opt[0, 1]] = nil end end - + + options.each do |arg| + opt, val = arg.split(':', 2) + + if val + valopts[opt] = val.empty? ? nil : val + else + boolopts[opt] = false + end + end + # # scan # c = 0 - arg = argv.shift - while arg do - case arg - when /\A--?\z/ # xinit -- -bpp 24 - newargv.concat argv - break + argv = ARGV + while arg = argv.shift + case arg when /\A--(.*)/ - opt = $1 - if valopts.key? opt then # imclean --src +trash - return nil if argv.empty? - valopts[ opt ] = argv.shift - elsif boolopts.key? opt then # ruby --verbose - boolopts[ opt ] = true + if $1.empty? # xinit -- -bpp 24 + break + end + + opt, val = $1.split('=', 2) + + if opt.size == 1 + argv.unshift arg + return nil + elsif valopts.key? opt # imclean --src +trash + valopts[opt] = val || argv.shift or return nil + elsif boolopts.key? opt # ruby --verbose + boolopts[opt] = true else + argv.unshift arg return nil end + c += 1 - when /\A-(.+)/ - arg = $1 - 0.upto( arg.size - 1 ) do |idx| - opt = arg[idx, 1] - if single_opts and single_opts_exp === opt then - boolopts[ opt ] = true # ruby -h - c += 1 + opts = $1 - elsif single_colon and single_colon_exp === opt then - val = arg[ (idx+1)..-1 ] - if val.empty? then # ruby -e 'p $:' - return nil if argv.empty? - valopts[ opt ] = argv.shift - else # cc -ohello ... - valopts[ opt ] = val + until opts.empty? + opt = opts.slice!(0, 1) + + if valopts.key? opt + val = opts + + if val.empty? # ruby -e 'p $:' + valopts[opt] = argv.shift or return nil + else # cc -ohello ... + valopts[opt] = val + end + + c += 1 + break + elsif boolopts.key? opt + boolopts[opt] = true # ruby -h + c += 1 + else + argv.unshift arg + return nil + end end - c += 1 - - break - else - return nil - end - end - - else # ruby test.rb - newargv.push arg - end - - arg = argv.shift + else + argv.unshift arg + break end - + end + # # set # boolopts.each do |opt, val| eval "$OPT_#{opt} = val" - end - valopts.each do |opt, val| - eval "$OPT_#{opt} = #{val == 0 ? 'nil' : 'val'}" end - argv.replace newargv + valopts.each do |opt, val| + eval "$OPT_#{opt} = val" + end c end