From f9010939a1debceb22152672df2bc1585c57ceec Mon Sep 17 00:00:00 2001 From: Lee Jarvis Date: Sun, 29 Jan 2017 21:57:04 +0000 Subject: Fix support for parsing -x5 Thanks to @RickHull for the "smashing" terminology and various conversations Fixes #199 --- lib/slop/parser.rb | 27 ++++++++++++++++++++------- test/parser_test.rb | 13 +++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/slop/parser.rb b/lib/slop/parser.rb index 0b33d55..142540a 100644 --- a/lib/slop/parser.rb +++ b/lib/slop/parser.rb @@ -111,13 +111,7 @@ module Slop elsif flag.start_with?("--no-") && option = matching_option(flag.sub("no-", "")) process(option, false) elsif flag =~ /\A-[^-]{2,}/ - # try and process as a set of grouped short flags. drop(1) removes - # the prefixed -, then we add them back to each flag separately. - flags = flag.split("").drop(1).map { |f| "-#{f}" } - last = flags.pop - - flags.each { |f| try_process(f, nil) } - try_process(last, arg) # send the argument to the last flag + try_process_smashed_arg(flag) || try_process_grouped_flags(flag, arg) else if flag.start_with?("-") && !suppress_errors? raise UnknownOption.new("unknown option `#{flag}'", "#{flag}") @@ -125,6 +119,25 @@ module Slop end end + # try and process a flag with a "smashed" argument, e.g. + # -nFoo or -i5 + def try_process_smashed_arg(flag) + option = matching_option(flag[0, 2]) + if option && option.expects_argument? + process(option, flag[2..-1]) + end + end + + # try and process as a set of grouped short flags. drop(1) removes + # the prefixed -, then we add them back to each flag separately. + def try_process_grouped_flags(flag, arg) + flags = flag.split("").drop(1).map { |f| "-#{f}" } + last = flags.pop + + flags.each { |f| try_process(f, nil) } + try_process(last, arg) # send the argument to the last flag + end + def suppress_errors? config[:suppress_errors] end diff --git a/test/parser_test.rb b/test/parser_test.rb index 339a522..fa372cf 100644 --- a/test/parser_test.rb +++ b/test/parser_test.rb @@ -66,6 +66,19 @@ describe Slop::Parser do end end + describe "short flags with arguments" do + before do + @options.integer "-i" + @options.string "-s" + end + + it "parses the argument" do + @result.parser.parse %w(-i5 -sfoo) + assert_equal 5, @result[:i] + assert_equal "foo", @result[:s] + end + end + describe "#used_options" do it "returns all options that were parsed" do assert_equal [@verbose, @name], @parser.used_options -- cgit v1.2.1