From fc65c85a1371cfa6a844788e49f3316026f2e01c Mon Sep 17 00:00:00 2001 From: mpeterv Date: Sun, 23 Feb 2014 16:15:49 +0400 Subject: [PATCH] Improved command line parsing The first character after control character is now not required to be a letter --- spec/help_spec.lua | 6 +++--- spec/options_spec.lua | 8 ++++++++ src/argparse.lua | 40 ++++++++++++++++++++-------------------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/spec/help_spec.lua b/spec/help_spec.lua index 0fb2428..fe8aad5 100644 --- a/spec/help_spec.lua +++ b/spec/help_spec.lua @@ -23,12 +23,12 @@ describe("tests related to help message generation", function() it("uses custom help option", function() local parser = Parser "foo" - :add_help {aliases = {"\\?"}} + :add_help {name = "/?"} assert.equal(table.concat({ - "Usage: foo [\\?]", + "Usage: foo [/?]", "", "Options: ", - " \\? Show this help message and exit. " + " /? Show this help message and exit. " }, "\r\n"), parser:prepare():get_help()) end) diff --git a/spec/options_spec.lua b/spec/options_spec.lua index ba0a3f5..81ea0e3 100644 --- a/spec/options_spec.lua +++ b/spec/options_spec.lua @@ -16,6 +16,14 @@ describe("tests related to options", function() assert.same({server = "foo"}, args) end) + it("handles non-standard charset", function() + local parser = Parser() + parser:option "/s" + parser:flag "/?" + local args = parser:parse{"/s", "foo", "/?"} + assert.same({s = "foo", ["?"] = true}, args) + end) + it("handles GNU-style long options", function() local parser = Parser() parser:option("-s", "--server") diff --git a/src/argparse.lua b/src/argparse.lua index 30a6c98..92c307f 100644 --- a/src/argparse.lua +++ b/src/argparse.lua @@ -267,7 +267,11 @@ function Parser:prepare() end) if #self._help_option._aliases == 0 then - self._help_option "-h" "--help" + if self._help_option._name then + self._help_option._aliases[1] = self._help_option._name + else + self._help_option "-h" "--help" + end end if not self._help_option._description then @@ -282,7 +286,7 @@ function Parser:prepare() end for _, command in ipairs(self._commands) do - command._target =command._target or command._name + command._target = command._target or command._name command._name = self._name .. " " .. command._name end @@ -700,26 +704,11 @@ function Parser:_parse(args, errhandler) first = data:sub(1, 1) if charset[first] then if #data > 1 then - if data:sub(2, 2):match "[a-zA-Z]" then - plain = false - - for i = 2, #data do - name = first .. data:sub(i, i) - option = get_option(name) - handle_option(name) - - if i ~= #data and option._minargs > 0 then - handle_argument(data:sub(i+1)) - break - end - end - elseif data:sub(2, 2) == first then + plain = false + if data:sub(2, 2) == first then if #data == 2 then - plain = false handle_options = false - elseif data:sub(3, 3):match "[a-zA-Z]" then - plain = false - + else local equal = data:find "=" if equal then name = data:sub(1, equal-1) @@ -733,6 +722,17 @@ function Parser:_parse(args, errhandler) handle_option(data) end end + else + for i = 2, #data do + name = first .. data:sub(i, i) + option = get_option(name) + handle_option(name) + + if i ~= #data and option._minargs > 0 then + handle_argument(data:sub(i+1)) + break + end + end end end end