diff --git a/README.md b/README.md index 4b9fb61..9ba3852 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,6 @@ Almost everything is implemented, and a WIP version will be available soon. TODO till first release: * Add `Content` section to this README. -* Add information about the parsing algorithm to the tutorial. -* Add information about the way arguments are stored in the result table to the tutorial. * Add a small example to the beginning of this README. * Check the grammar in this README. * Generate .html file from the tutorial part of this README and put it into `doc` directory. @@ -785,7 +783,20 @@ Error: option '-o' must be used at most 1 time #### Generating usage and help messages -`get_help` and `get_usage` methods of Parser and Command classes can be used to generate their help and usage messages. +`:get_help()` and `get_usage:()` methods of Parser and Command classes can be used to generate their help and usage messages. + +#### Parsing algorithm + +argparse interprets command-line arguments in the following way: + +Argument | Interpretation +--- | --- +`foo` | An argument of an option or a positional argument. +`--foo` | An option. +`--foo=bar` | An option and its argument. The option must be able to take arguments. +`-f` | An option. +`-abcdef` | Letters are interpreted as options. If one of them can take an argument, the rest of the string is passed to it. +`--` | The rest of the command-line arguments will be interpreted as positional arguments. ## Documentation diff --git a/spec/options_spec.lua b/spec/options_spec.lua index 2a624af..ab2d300 100644 --- a/spec/options_spec.lua +++ b/spec/options_spec.lua @@ -88,6 +88,35 @@ describe("tests related to options", function() assert.same({quiet = true, server = "foo"}, args) end) + it("interprets extra option arguments as positional arguments", function() + local parser = Parser() + parser:argument "input" + :args "2+" + parser:option "-s" "--server" + local args = parser:parse{"foo", "-sFROM", "bar"} + assert.same({input = {"foo", "bar"}, server = "FROM"}, args) + end) + + it("does not interpret extra option arguments as other option's arguments", function() + local parser = Parser() + parser:argument "output" + parser:option "--input" + :args "+" + parser:option "-s" "--server" + local args = parser:parse{"--input", "foo", "-sFROM", "bar"} + assert.same({input = {"foo"}, server = "FROM", output = "bar"}, args) + end) + + it("does not pass arguments to options after double hyphen", function() + local parser = Parser() + parser:argument "input" + :args "?" + parser:option "--exclude" + :args "*" + local args = parser:parse{"--exclude", "--", "foo"} + assert.same({input = "foo", exclude = {}}, args) + end) + describe("Special chars set", function() it("handles windows-style options", function() local parser = Parser() @@ -106,8 +135,8 @@ describe("tests related to options", function() :count "*" parser:command "deep" :add_help(false) - :option "\\s" - local args = parser:parse{"-v", "deep", "\\s", "foo", "-vv"} + :option "/s" + local args = parser:parse{"-v", "deep", "/s", "foo", "-vv"} assert.same({verbose = 3, deep = true, s = "foo"}, args) end) end) diff --git a/src/argparse.lua b/src/argparse.lua index 540caaa..d9125ef 100644 --- a/src/argparse.lua +++ b/src/argparse.lua @@ -790,6 +790,10 @@ function Parser:_parse(args, errhandler) plain = false if data:sub(2, 2) == first then if #data == 2 then + if cur_option then + close(cur_option) + end + handle_options = false else local equal = data:find "="