Bug #7537 ยป 259.patch
| lib/optparse.rb | ||
|---|---|---|
| 
         class PlacedArgument < self 
   | 
||
| 
           # 
   | 
||
| 
           # Returns nil if argument is not present or begins with '-'. 
   | 
||
| 
           # Returns nil if argument is not present or begins with '-' and is not a negative number. 
   | 
||
| 
           # 
   | 
||
| 
           def parse(arg, argv, &error) 
   | 
||
| 
             if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0])) 
   | 
||
| 
             if !(val = arg) and (argv.empty? or /\A-\D/ =~ (val = argv[0])) 
   | 
||
| 
               return nil, block, nil 
   | 
||
| 
             end 
   | 
||
| 
             opt = (val = parse_arg(val, &error))[1] 
   | 
||
| ... | ... | |
| 
             end 
   | 
||
| 
           end 
   | 
||
| 
         end 
   | 
||
| 
         # 
   | 
||
| 
         # any of keys in list is negative number, such as -2 
   | 
||
| 
         # 
   | 
||
| 
         def has_digit_options? 
   | 
||
| 
           digits = (0..9).map{|x|x.to_s} 
   | 
||
| 
           short.keys.any?{|k| digits.include?(k) } 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       # 
   | 
||
| ... | ... | |
| 
           nolong 
   | 
||
| 
       end 
   | 
||
| 
       # 
   | 
||
| 
       # any of keys is negative number, such as -2 
   | 
||
| 
       # 
   | 
||
| 
       def has_digit_options? 
   | 
||
| 
         @stack.any?{|list| list.has_digit_options? } 
   | 
||
| 
       end 
   | 
||
| 
       def define(*opts, &block) 
   | 
||
| 
         top.append(*(sw = make_switch(opts, block))) 
   | 
||
| 
         sw[0] 
   | 
||
| ... | ... | |
| 
             # short option 
   | 
||
| 
             when /\A-(.)((=).*|.+)?/m 
   | 
||
| 
               # negative digit works as option if any digit-options 
   | 
||
| 
               # were explicitly specified 
   | 
||
| 
               if negative_numeric?(arg) && !has_digit_options? 
   | 
||
| 
                 parse_non_option(arg, &nonopt) 
   | 
||
| 
                 next 
   | 
||
| 
               end 
   | 
||
| 
               opt, has_arg, eq, val, rest = $1, $3, $3, $2, $2 
   | 
||
| 
               begin 
   | 
||
| 
                 sw, = search(:short, opt) 
   | 
||
| ... | ... | |
| 
             # non-option argument 
   | 
||
| 
             else 
   | 
||
| 
               catch(:prune) do 
   | 
||
| 
                 visit(:each_option) do |sw0| 
   | 
||
| 
                   sw = sw0 
   | 
||
| 
                   sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg) 
   | 
||
| 
                 end 
   | 
||
| 
                 nonopt.call(arg) 
   | 
||
| 
               end 
   | 
||
| 
               parse_non_option(arg, &nonopt) 
   | 
||
| 
             end 
   | 
||
| 
           end 
   | 
||
| ... | ... | |
| 
       end 
   | 
||
| 
       private :parse_in_order 
   | 
||
| 
       def parse_non_option(arg, &nonopt) 
   | 
||
| 
         catch(:prune) do 
   | 
||
| 
           visit(:each_option) do |sw0| 
   | 
||
| 
             sw = sw0 
   | 
||
| 
             sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg) 
   | 
||
| 
           end 
   | 
||
| 
           nonopt.call(arg) 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       private :parse_non_option 
   | 
||
| 
       # 
   | 
||
| 
       # Parses command line arguments +argv+ in permutation mode and returns 
   | 
||
| 
       # list of non-option arguments. 
   | 
||
| ... | ... | |
| 
       accept(DecimalNumeric) {|s,| eval(s) if s} 
   | 
||
| 
       # 
   | 
||
| 
       # Pattern for negative numerics matching which shouldn't be accidentally 
   | 
||
| 
       # treated as options 
   | 
||
| 
       # 
   | 
||
| 
       NegativeNumeric = /\A-\d+(\.\d*)?/ 
   | 
||
| 
       # 
   | 
||
| 
       # this method is used to create a local scope 
   | 
||
| 
       # and not to clear old values of regex variables such as $~ 
   | 
||
| 
       # 
   | 
||
| 
       def negative_numeric?(arg) 
   | 
||
| 
         NegativeNumeric === arg 
   | 
||
| 
       end 
   | 
||
| 
       # 
   | 
||
| 
       # Boolean switch, which means whether it is present or not, whether it is 
   | 
||
| 
       # absent or not with prefix no-, or it takes an argument 
   | 
||
| 
       # yes/no/true/false/+/-. 
   | 
||
| test/optparse/test_digitarg.rb | ||
|---|---|---|
| 
     require_relative 'test_optparse' 
   | 
||
| 
     class WithDigitOptions < TestOptionParser 
   | 
||
| 
       def setup 
   | 
||
| 
         super 
   | 
||
| 
         @flags = {} 
   | 
||
| 
         @opt.def_option("-x"){|x| @flag = @flags[:x] = x } 
   | 
||
| 
         @opt.def_option("-o VAL"){|x| @flag = @flags[:o] = x} 
   | 
||
| 
         @opt.def_option("-p [VAL]"){|x| @flag = @flags[:p] = x} 
   | 
||
| 
         @opt.def_option("-2"){|x| @flag = @flags[2] = x} 
   | 
||
| 
         @opt.def_option("-4"){|x| @flag = @flags[4] = x} 
   | 
||
| 
       end 
   | 
||
| 
     | 
||
| 
       def test_negative_digits 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-2 -4")}) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         assert_equal(true, @flags[4]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
     | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-42")}) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         assert_equal(true, @flags[4]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_raise(OptionParser::InvalidOption) {@opt.parse!(%w"-x -1")} 
   | 
||
| 
         assert_raise(OptionParser::InvalidOption) {@opt.parse!(%w"-x -2 -1")} 
   | 
||
| 
         assert_raise(OptionParser::InvalidOption) {@opt.parse!(%w"-x -12")} 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
     | 
||
| 
       def test_negative_digits_with_noargs 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-x -2 -4")}) 
   | 
||
| 
         assert_equal(true, @flags[:x]) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         assert_equal(true, @flags[4]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-x2")}) 
   | 
||
| 
         assert_equal(true, @flags[:x]) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-2x")}) 
   | 
||
| 
         assert_equal(true, @flags[:x]) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
     | 
||
| 
       def test_negative_digits_with_reqargs 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-o -4 -2")}) 
   | 
||
| 
         assert_equal('-4', @flags[:o]) 
   | 
||
| 
         assert_equal(false, @flags.has_key?(4)) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-o42")}) 
   | 
||
| 
         assert_equal('42', @flags[:o]) 
   | 
||
| 
         assert_equal(false, @flags.has_key?(4)) 
   | 
||
| 
         assert_equal(false, @flags.has_key?(2)) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
       # negative numerics after optional arguments are treated as argument  
   | 
||
| 
       # even if it can be an option 
   | 
||
| 
       def test_negative_digits_with_optargs 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-p -4 -2")}) 
   | 
||
| 
         assert_equal('-4', @flags[:p]) 
   | 
||
| 
         assert_equal(false, @flags.has_key?(4)) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-p-4 -2")}) 
   | 
||
| 
         assert_equal('-4', @flags[:p]) 
   | 
||
| 
         assert_equal(false, @flags.has_key?(4)) 
   | 
||
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
     end 
   | 
||
| 
     class WithoutDigitOptions < TestOptionParser 
   | 
||
| 
       def setup 
   | 
||
| 
         super 
   | 
||
| 
         @flags = {} 
   | 
||
| 
         @opt.def_option("-x"){|x| @flag = @flags[:x] = x} 
   | 
||
| 
         @opt.def_option("-o VAL"){|x| @flag = @flags[:o] = x} 
   | 
||
| 
         @opt.def_option("-p [VAL]"){|x| @flag = @flags[:p] = x} 
   | 
||
| 
       end 
   | 
||
| 
     | 
||
| 
       def test_negative_digits 
   | 
||
| 
         assert_equal(%w"-1 -2", no_error {@opt.parse!(%w"-1 -2")}) 
   | 
||
| 
         assert_equal(%w"-12", no_error {@opt.parse!(%w"-12")}) 
   | 
||
| 
         assert_equal(%w"-3.14", no_error {@opt.parse!(%w"-3.14")}) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
       def test_negative_digits_with_noargs 
   | 
||
| 
         assert_equal(%w"-1 -2", no_error {@opt.parse!(%w"-x -1 -2")}) 
   | 
||
| 
         assert_equal(true, @flags[:x]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
       def test_negative_digits_with_reqargs 
   | 
||
| 
         assert_equal(%w"-2", no_error {@opt.parse!(%w"-o -1 -2")}) 
   | 
||
| 
         assert_equal('-1', @flags[:o]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-o -3.14")}) 
   | 
||
| 
         assert_equal('-3.14', @flags[:o]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
       def test_negative_digits_with_optargs 
   | 
||
| 
         assert_equal(%w"-2", no_error {@opt.parse!(%w"-p -1 -2")}) 
   | 
||
| 
         assert_equal('-1', @flags[:p]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"-2", no_error {@opt.parse!(%w"-p-1 -2")}) 
   | 
||
| 
         assert_equal('-1', @flags[:p]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
     end 
   | 
||
| 
     -  
   | 
||
| test/optparse/test_digitarg.rb | ||
|---|---|---|
| 
         @opt.def_option("-x"){|x| @flag = @flags[:x] = x } 
   | 
||
| 
         @opt.def_option("-o VAL"){|x| @flag = @flags[:o] = x} 
   | 
||
| 
         @opt.def_option("-p [VAL]"){|x| @flag = @flags[:p] = x} 
   | 
||
| 
         @opt.def_option("-q=[VAL]"){|x| @flag = @flags[:q] = x} 
   | 
||
| 
         @opt.def_option("-2"){|x| @flag = @flags[2] = x} 
   | 
||
| 
         @opt.def_option("-4"){|x| @flag = @flags[4] = x} 
   | 
||
| 
       end 
   | 
||
| ... | ... | |
| 
         assert_equal(true, @flags[2]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
       # When one uses option with optional argument 
   | 
||
| 
       # with equal sign in its specification (instead of spaces) 
   | 
||
| 
       # argument should be just after option letter without any spaces 
   | 
||
| 
       def test_negative_digits_with_optargs_with_eq_sign 
   | 
||
| 
         assert_raise(OptionParser::InvalidOption) {@opt.parse!(%w"-q -1")} 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"", no_error {@opt.parse!(%w"-q-1")}) 
   | 
||
| 
         assert_equal('-1', @flags[:q]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
     end 
   | 
||
| 
     class WithoutDigitOptions < TestOptionParser 
   | 
||
| ... | ... | |
| 
         @opt.def_option("-x"){|x| @flag = @flags[:x] = x} 
   | 
||
| 
         @opt.def_option("-o VAL"){|x| @flag = @flags[:o] = x} 
   | 
||
| 
         @opt.def_option("-p [VAL]"){|x| @flag = @flags[:p] = x} 
   | 
||
| 
         @opt.def_option("-q=[VAL]"){|x| @flag = @flags[:q] = x} 
   | 
||
| 
       end 
   | 
||
| 
     | 
||
| 
       def test_negative_digits 
   | 
||
| ... | ... | |
| 
         assert_equal('-1', @flags[:p]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
       # When one uses option with optional argument 
   | 
||
| 
       # with equal sign in its specification (instead of spaces) 
   | 
||
| 
       # argument should be just after option letter without any spaces 
   | 
||
| 
       def test_negative_digits_with_optargs_with_eq_sign 
   | 
||
| 
         assert_equal(%w"-1 -2", no_error {@opt.parse!(%w"-q -1 -2")}) 
   | 
||
| 
         assert_equal(true, @flags.has_key?(:q)) 
   | 
||
| 
         assert_equal(nil, @flags[:q]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
         assert_equal(%w"-2", no_error {@opt.parse!(%w"-q-1 -2")}) 
   | 
||
| 
         assert_equal('-1', @flags[:q]) 
   | 
||
| 
         @flags.clear 
   | 
||
| 
       end 
   | 
||
| 
     end 
   | 
||