Project

General

Profile

Bug #7537 ยป 259.patch

zzak (zzak _), 04/05/2013 11:38 AM

View differences:

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
    (1-1/1)