mirror of
https://github.com/TangentFoxy/argparse.git
synced 2025-07-28 02:52:20 +00:00
add even more sugar
This commit is contained in:
@@ -49,7 +49,7 @@ describe("tests related to commands", function()
|
|||||||
local args = parser:parse{}
|
local args = parser:parse{}
|
||||||
assert.same({}, args)
|
assert.same({}, args)
|
||||||
|
|
||||||
parser.require_command = true
|
parser:require_command(true)
|
||||||
assert.has_error(function() parser:parse{} end, "command is required")
|
assert.has_error(function() parser:parse{} end, "command is required")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
279
src/argparse.lua
279
src/argparse.lua
@@ -5,6 +5,17 @@ local class = require "30log"
|
|||||||
local Declarative = {}
|
local Declarative = {}
|
||||||
|
|
||||||
function Declarative:__init(...)
|
function Declarative:__init(...)
|
||||||
|
local cl = getmetatable(self)
|
||||||
|
|
||||||
|
for _, field in ipairs(self._fields) do
|
||||||
|
if not cl[field] then
|
||||||
|
cl[field] = function(s, value)
|
||||||
|
s["_" .. field] = value
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
self(...)
|
self(...)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -15,17 +26,17 @@ function Declarative:__call(...)
|
|||||||
name_or_options = select(i, ...)
|
name_or_options = select(i, ...)
|
||||||
|
|
||||||
if type(name_or_options) == "string" then
|
if type(name_or_options) == "string" then
|
||||||
if self.aliases then
|
if self._aliases then
|
||||||
table.insert(self.aliases, name_or_options)
|
table.insert(self._aliases, name_or_options)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.name then
|
if not self._name then
|
||||||
self.name = name_or_options
|
self._name = name_or_options
|
||||||
end
|
end
|
||||||
elseif type(name_or_options) == "table" then
|
elseif type(name_or_options) == "table" then
|
||||||
for _, field in ipairs(self.fields) do
|
for _, field in ipairs(self._fields) do
|
||||||
if name_or_options[field] ~= nil then
|
if name_or_options[field] ~= nil then
|
||||||
self[field] = name_or_options[field]
|
self["_" .. field] = name_or_options[field]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -36,11 +47,11 @@ end
|
|||||||
|
|
||||||
local Parser = class {
|
local Parser = class {
|
||||||
__name = "Parser",
|
__name = "Parser",
|
||||||
arguments = {},
|
_arguments = {},
|
||||||
options = {},
|
_options = {},
|
||||||
commands = {},
|
_commands = {},
|
||||||
require_command = false,
|
_require_command = false,
|
||||||
fields = {
|
_fields = {
|
||||||
"name", "description", "target", "require_command",
|
"name", "description", "target", "require_command",
|
||||||
"action", "usage"
|
"action", "usage"
|
||||||
}
|
}
|
||||||
@@ -48,14 +59,14 @@ local Parser = class {
|
|||||||
|
|
||||||
local Command = Parser:extends {
|
local Command = Parser:extends {
|
||||||
__name = "Command",
|
__name = "Command",
|
||||||
aliases = {}
|
_aliases = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
local Argument = class {
|
local Argument = class {
|
||||||
__name = "Argument",
|
__name = "Argument",
|
||||||
args = 1,
|
_args = 1,
|
||||||
count = 1,
|
_count = 1,
|
||||||
fields = {
|
_fields = {
|
||||||
"name", "description", "target", "args",
|
"name", "description", "target", "args",
|
||||||
"minargs", "maxargs", "default", "convert",
|
"minargs", "maxargs", "default", "convert",
|
||||||
"action", "usage", "argname"
|
"action", "usage", "argname"
|
||||||
@@ -64,10 +75,10 @@ local Argument = class {
|
|||||||
|
|
||||||
local Option = Argument:extends {
|
local Option = Argument:extends {
|
||||||
__name = "Option",
|
__name = "Option",
|
||||||
aliases = {},
|
_aliases = {},
|
||||||
count = "?",
|
_count = "?",
|
||||||
overwrite = true,
|
_overwrite = true,
|
||||||
fields = {
|
_fields = {
|
||||||
"name", "aliases", "description", "target",
|
"name", "aliases", "description", "target",
|
||||||
"args", "minargs", "maxargs", "count",
|
"args", "minargs", "maxargs", "count",
|
||||||
"mincount", "maxcount", "default", "convert",
|
"mincount", "maxcount", "default", "convert",
|
||||||
@@ -77,29 +88,29 @@ local Option = Argument:extends {
|
|||||||
|
|
||||||
local Flag = Option:extends {
|
local Flag = Option:extends {
|
||||||
__name = "Flag",
|
__name = "Flag",
|
||||||
args = 0
|
_args = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function Argument:get_arg_usage(argname)
|
function Argument:get_arg_usage(argname)
|
||||||
argname = self.argname or argname
|
argname = self._argname or argname
|
||||||
local buf = {}
|
local buf = {}
|
||||||
local i = 1
|
local i = 1
|
||||||
|
|
||||||
while i <= math.min(self.minargs, 3) do
|
while i <= math.min(self._minargs, 3) do
|
||||||
table.insert(buf, argname)
|
table.insert(buf, argname)
|
||||||
i = i+1
|
i = i+1
|
||||||
end
|
end
|
||||||
|
|
||||||
while i <= math.min(self.maxargs, 3) do
|
while i <= math.min(self._maxargs, 3) do
|
||||||
table.insert(buf, "[" .. argname .. "]")
|
table.insert(buf, "[" .. argname .. "]")
|
||||||
i = i+1
|
i = i+1
|
||||||
|
|
||||||
if self.maxargs == math.huge then
|
if self._maxargs == math.huge then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if i < self.maxargs then
|
if i < self._maxargs then
|
||||||
table.insert(buf, "...")
|
table.insert(buf, "...")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -107,48 +118,48 @@ function Argument:get_arg_usage(argname)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Argument:get_usage()
|
function Argument:get_usage()
|
||||||
if not self.usage then
|
if not self._usage then
|
||||||
self.usage = table.concat(self:get_arg_usage("<" .. self.name .. ">"), " ")
|
self._usage = table.concat(self:get_arg_usage("<" .. self._name .. ">"), " ")
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.usage
|
return self._usage
|
||||||
end
|
end
|
||||||
|
|
||||||
function Option:get_usage()
|
function Option:get_usage()
|
||||||
if not self.usage then
|
if not self._usage then
|
||||||
self.usage = self:get_arg_usage("<" .. self.target .. ">")
|
self._usage = self:get_arg_usage("<" .. self._target .. ">")
|
||||||
table.insert(self.usage, 1, self.name)
|
table.insert(self._usage, 1, self._name)
|
||||||
self.usage = table.concat(self.usage, " ")
|
self._usage = table.concat(self._usage, " ")
|
||||||
|
|
||||||
if self.mincount == 0 then
|
if self._mincount == 0 then
|
||||||
self.usage = "[" .. self.usage .. "]"
|
self._usage = "[" .. self._usage .. "]"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.usage
|
return self._usage
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:argument(...)
|
function Parser:argument(...)
|
||||||
local argument = Argument:new(...)
|
local argument = Argument:new(...)
|
||||||
table.insert(self.arguments, argument)
|
table.insert(self._arguments, argument)
|
||||||
return argument
|
return argument
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:option(...)
|
function Parser:option(...)
|
||||||
local option = Option:new(...)
|
local option = Option:new(...)
|
||||||
table.insert(self.options, option)
|
table.insert(self._options, option)
|
||||||
return option
|
return option
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:flag(...)
|
function Parser:flag(...)
|
||||||
local flag = Flag:new(...)
|
local flag = Flag:new(...)
|
||||||
table.insert(self.options, flag)
|
table.insert(self._options, flag)
|
||||||
return flag
|
return flag
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:command(...)
|
function Parser:command(...)
|
||||||
local command = Command:new(...)
|
local command = Command:new(...)
|
||||||
table.insert(self.commands, command)
|
table.insert(self._commands, command)
|
||||||
return command
|
return command
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -168,45 +179,45 @@ function Parser:assert(assertion, ...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Parser:make_charset()
|
function Parser:make_charset()
|
||||||
if not self.charset then
|
if not self._charset then
|
||||||
self.charset = {["-"] = true}
|
self._charset = {["-"] = true}
|
||||||
|
|
||||||
for _, command in ipairs(self.commands) do
|
for _, command in ipairs(self._commands) do
|
||||||
command:make_charset()
|
command:make_charset()
|
||||||
|
|
||||||
for char in pairs(command.charset) do
|
for char in pairs(command._charset) do
|
||||||
self.charset[char] = true
|
self._charset[char] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, option in ipairs(self.options) do
|
for _, option in ipairs(self._options) do
|
||||||
for _, alias in ipairs(option.aliases) do
|
for _, alias in ipairs(option._aliases) do
|
||||||
self.charset[alias:sub(1, 1)] = true
|
self._charset[alias:sub(1, 1)] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:make_targets()
|
function Parser:make_targets()
|
||||||
for _, option in ipairs(self.options) do
|
for _, option in ipairs(self._options) do
|
||||||
if not option.target then
|
if not option._target then
|
||||||
for _, alias in ipairs(option.aliases) do
|
for _, alias in ipairs(option._aliases) do
|
||||||
if alias:sub(1, 1) == alias:sub(2, 2) then
|
if alias:sub(1, 1) == alias:sub(2, 2) then
|
||||||
option.target = alias:sub(3)
|
option._target = alias:sub(3)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
option.target = option.target or option.aliases[1]:sub(2)
|
option._target = option._target or option._aliases[1]:sub(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, argument in ipairs(self.arguments) do
|
for _, argument in ipairs(self._arguments) do
|
||||||
argument.target = argument.target or argument.name
|
argument._target = argument._target or argument._name
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, command in ipairs(self.commands) do
|
for _, command in ipairs(self._commands) do
|
||||||
command.target = command.target or command.name
|
command._target = command._target or command._name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -239,43 +250,43 @@ local function parse_boundaries(boundaries)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Parser:make_boundaries()
|
function Parser:make_boundaries()
|
||||||
for _, elements in ipairs{self.arguments, self.options} do
|
for _, elements in ipairs{self._arguments, self._options} do
|
||||||
for _, element in ipairs(elements) do
|
for _, element in ipairs(elements) do
|
||||||
if not element.minargs or not element.maxargs then
|
if not element._minargs or not element._maxargs then
|
||||||
element.minargs, element.maxargs = parse_boundaries(element.args)
|
element._minargs, element._maxargs = parse_boundaries(element._args)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not element.mincount or not element.maxcount then
|
if not element._mincount or not element._maxcount then
|
||||||
element.mincount, element.maxcount = parse_boundaries(element.count)
|
element._mincount, element._maxcount = parse_boundaries(element._count)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:make_command_names()
|
function Parser:make_command_names()
|
||||||
for _, command in ipairs(self.commands) do
|
for _, command in ipairs(self._commands) do
|
||||||
command.name = self.name .. " " .. command.name
|
command._name = self._name .. " " .. command._name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:make_types()
|
function Parser:make_types()
|
||||||
for _, elements in ipairs{self.arguments, self.options} do
|
for _, elements in ipairs{self._arguments, self._options} do
|
||||||
for _, element in ipairs(elements) do
|
for _, element in ipairs(elements) do
|
||||||
if element.maxcount == 1 then
|
if element._maxcount == 1 then
|
||||||
if element.maxargs == 0 then
|
if element._maxargs == 0 then
|
||||||
element.type = "flag"
|
element._type = "flag"
|
||||||
elseif element.maxargs == 1 and element.minargs == 1 then
|
elseif element._maxargs == 1 and element._minargs == 1 then
|
||||||
element.type = "arg"
|
element._type = "arg"
|
||||||
else
|
else
|
||||||
element.type = "multi-arg"
|
element._type = "multi-arg"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if element.maxargs == 0 then
|
if element._maxargs == 0 then
|
||||||
element.type = "counter"
|
element._type = "counter"
|
||||||
elseif element.maxargs == 1 and element.minargs == 1 then
|
elseif element._maxargs == 1 and element._minargs == 1 then
|
||||||
element.type = "multi-count"
|
element._type = "multi-count"
|
||||||
else
|
else
|
||||||
element.type = "multi-count multi-arg"
|
element._type = "multi-count multi-arg"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -292,17 +303,17 @@ function Parser:prepare()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Parser:get_usage()
|
function Parser:get_usage()
|
||||||
if not self.usage then
|
if not self._usage then
|
||||||
local buf = {"Usage:", self.name}
|
local buf = {"Usage:", self._name}
|
||||||
|
|
||||||
for _, elements in ipairs{self.options, self.arguments} do
|
for _, elements in ipairs{self._options, self._arguments} do
|
||||||
for _, element in ipairs(elements) do
|
for _, element in ipairs(elements) do
|
||||||
table.insert(buf, element:get_usage())
|
table.insert(buf, element:get_usage())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #self.commands > 0 then
|
if #self._commands > 0 then
|
||||||
if self.require_command then
|
if self._require_command then
|
||||||
table.insert(buf, "<command>")
|
table.insert(buf, "<command>")
|
||||||
else
|
else
|
||||||
table.insert(buf, "[<command>]")
|
table.insert(buf, "[<command>]")
|
||||||
@@ -312,15 +323,15 @@ function Parser:get_usage()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: prettify
|
-- TODO: prettify
|
||||||
self.usage = table.concat(buf, " ")
|
self._usage = table.concat(buf, " ")
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.usage
|
return self._usage
|
||||||
end
|
end
|
||||||
|
|
||||||
function Parser:parse(args)
|
function Parser:parse(args)
|
||||||
args = args or arg
|
args = args or arg
|
||||||
self.name = self.name or args[0]
|
self._name = self._name or args[0]
|
||||||
|
|
||||||
local parser
|
local parser
|
||||||
local charset
|
local charset
|
||||||
@@ -338,8 +349,8 @@ function Parser:parse(args)
|
|||||||
local cur_arg
|
local cur_arg
|
||||||
|
|
||||||
local function convert(element, data)
|
local function convert(element, data)
|
||||||
if element.convert then
|
if element._convert then
|
||||||
local ok, err = element.convert(data)
|
local ok, err = element._convert(data)
|
||||||
|
|
||||||
return parser:assert(ok, "%s", err or "malformed argument " .. data)
|
return parser:assert(ok, "%s", err or "malformed argument " .. data)
|
||||||
else
|
else
|
||||||
@@ -352,11 +363,11 @@ function Parser:parse(args)
|
|||||||
function invoke(element)
|
function invoke(element)
|
||||||
local overwrite = false
|
local overwrite = false
|
||||||
|
|
||||||
if invocations[element] == element.maxcount then
|
if invocations[element] == element._maxcount then
|
||||||
if element.overwrite then
|
if element._overwrite then
|
||||||
overwrite = true
|
overwrite = true
|
||||||
else
|
else
|
||||||
parser:error("option %s must be used at most %d times", element.name, element.maxcount)
|
parser:error("option %s must be used at most %d times", element._name, element._maxcount)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
invocations[element] = invocations[element]+1
|
invocations[element] = invocations[element]+1
|
||||||
@@ -364,27 +375,27 @@ function Parser:parse(args)
|
|||||||
|
|
||||||
passed[element] = 0
|
passed[element] = 0
|
||||||
|
|
||||||
if element.type == "flag" then
|
if element._type == "flag" then
|
||||||
result[element.target] = true
|
result[element._target] = true
|
||||||
elseif element.type == "multi-arg" then
|
elseif element._type == "multi-arg" then
|
||||||
result[element.target] = {}
|
result[element._target] = {}
|
||||||
elseif element.type == "counter" then
|
elseif element._type == "counter" then
|
||||||
if not overwrite then
|
if not overwrite then
|
||||||
result[element.target] = result[element.target]+1
|
result[element._target] = result[element._target]+1
|
||||||
end
|
end
|
||||||
elseif element.type == "multi-count" then
|
elseif element._type == "multi-count" then
|
||||||
if overwrite then
|
if overwrite then
|
||||||
table.remove(result[element.target], 1)
|
table.remove(result[element._target], 1)
|
||||||
end
|
end
|
||||||
elseif element.type == "multi-count multi-arg" then
|
elseif element._type == "multi-count multi-arg" then
|
||||||
table.insert(result[element.target], {})
|
table.insert(result[element._target], {})
|
||||||
|
|
||||||
if overwrite then
|
if overwrite then
|
||||||
table.remove(result[element.target], 1)
|
table.remove(result[element._target], 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if element.maxargs == 0 then
|
if element._maxargs == 0 then
|
||||||
close(element)
|
close(element)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -393,24 +404,24 @@ function Parser:parse(args)
|
|||||||
passed[element] = passed[element]+1
|
passed[element] = passed[element]+1
|
||||||
data = convert(element, data)
|
data = convert(element, data)
|
||||||
|
|
||||||
if element.type == "arg" then
|
if element._type == "arg" then
|
||||||
result[element.target] = data
|
result[element._target] = data
|
||||||
elseif element.type == "multi-arg" or element.type == "multi-count" then
|
elseif element._type == "multi-arg" or element._type == "multi-count" then
|
||||||
table.insert(result[element.target], data)
|
table.insert(result[element._target], data)
|
||||||
elseif element.type == "multi-count multi-arg" then
|
elseif element._type == "multi-count multi-arg" then
|
||||||
table.insert(result[element.target][#result[element.target]], data)
|
table.insert(result[element._target][#result[element._target]], data)
|
||||||
end
|
end
|
||||||
|
|
||||||
if passed[element] == element.maxargs then
|
if passed[element] == element._maxargs then
|
||||||
close(element)
|
close(element)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function close(element)
|
function close(element)
|
||||||
if passed[element] < element.minargs then
|
if passed[element] < element._minargs then
|
||||||
if element.default then
|
if element._default then
|
||||||
while passed[element] < element.minargs do
|
while passed[element] < element._minargs do
|
||||||
pass(element, element.default)
|
pass(element, element._default)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
parser:error("too few arguments")
|
parser:error("too few arguments")
|
||||||
@@ -423,11 +434,11 @@ function Parser:parse(args)
|
|||||||
cur_arg = arguments[cur_arg_i]
|
cur_arg = arguments[cur_arg_i]
|
||||||
end
|
end
|
||||||
|
|
||||||
if element.action then
|
if element._action then
|
||||||
if element.type == "multi-count" or element.type == "multi-count multi-arg" then
|
if element._type == "multi-count" or element._type == "multi-count multi-arg" then
|
||||||
element.action(result[element.target][#result[element.target]])
|
element._action(result[element._target][#result[element._target]])
|
||||||
else
|
else
|
||||||
element.action(result[element.target])
|
element._action(result[element._target])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -435,40 +446,40 @@ function Parser:parse(args)
|
|||||||
|
|
||||||
local function switch(p)
|
local function switch(p)
|
||||||
parser = p:prepare()
|
parser = p:prepare()
|
||||||
charset = p.charset
|
charset = parser._charset
|
||||||
|
|
||||||
if p.action then
|
if parser._action then
|
||||||
table.insert(com_callbacks, p.action)
|
table.insert(com_callbacks, parser._action)
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, option in ipairs(p.options) do
|
for _, option in ipairs(parser._options) do
|
||||||
table.insert(options, option)
|
table.insert(options, option)
|
||||||
|
|
||||||
for _, alias in ipairs(option.aliases) do
|
for _, alias in ipairs(option._aliases) do
|
||||||
opt_context[alias] = option
|
opt_context[alias] = option
|
||||||
end
|
end
|
||||||
|
|
||||||
if option.type == "counter" then
|
if option._type == "counter" then
|
||||||
result[option.target] = 0
|
result[option._target] = 0
|
||||||
elseif option.type == "multi-count" or option.type == "multi-count multi-arg" then
|
elseif option._type == "multi-count" or option._type == "multi-count multi-arg" then
|
||||||
result[option.target] = {}
|
result[option._target] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
invocations[option] = 0
|
invocations[option] = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, argument in ipairs(p.arguments) do
|
for _, argument in ipairs(parser._arguments) do
|
||||||
table.insert(arguments, argument)
|
table.insert(arguments, argument)
|
||||||
invocations[argument] = 0
|
invocations[argument] = 0
|
||||||
invoke(argument)
|
invoke(argument)
|
||||||
end
|
end
|
||||||
|
|
||||||
cur_arg = arguments[cur_arg_i]
|
cur_arg = arguments[cur_arg_i]
|
||||||
commands = p.commands
|
commands = parser._commands
|
||||||
com_context = {}
|
com_context = {}
|
||||||
|
|
||||||
for _, command in ipairs(p.commands) do
|
for _, command in ipairs(commands) do
|
||||||
for _, alias in ipairs(command.aliases) do
|
for _, alias in ipairs(command._aliases) do
|
||||||
com_context[alias] = command
|
com_context[alias] = command
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -489,7 +500,7 @@ function Parser:parse(args)
|
|||||||
parser:error("too many arguments")
|
parser:error("too many arguments")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result[com.target] = true
|
result[com._target] = true
|
||||||
switch(com)
|
switch(com)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -523,7 +534,7 @@ function Parser:parse(args)
|
|||||||
option = parser:assert(opt_context[name], "unknown option %s", name)
|
option = parser:assert(opt_context[name], "unknown option %s", name)
|
||||||
handle_option(name)
|
handle_option(name)
|
||||||
|
|
||||||
if i ~= #data and option.minargs > 0 then
|
if i ~= #data and option._minargs > 0 then
|
||||||
handle_argument(data:sub(i+1))
|
handle_argument(data:sub(i+1))
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@@ -539,7 +550,7 @@ function Parser:parse(args)
|
|||||||
if equal then
|
if equal then
|
||||||
name = data:sub(1, equal-1)
|
name = data:sub(1, equal-1)
|
||||||
option = parser:assert(opt_context[name], "unknown option %s", name)
|
option = parser:assert(opt_context[name], "unknown option %s", name)
|
||||||
parser:assert(option.maxargs > 0, "option %s doesn't take arguments", name)
|
parser:assert(option._maxargs > 0, "option %s doesn't take arguments", name)
|
||||||
|
|
||||||
handle_option(data:sub(1, equal-1))
|
handle_option(data:sub(1, equal-1))
|
||||||
handle_argument(data:sub(equal+1))
|
handle_argument(data:sub(equal+1))
|
||||||
@@ -570,13 +581,13 @@ function Parser:parse(args)
|
|||||||
close(cur_arg)
|
close(cur_arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
if parser.require_command and #commands > 0 then
|
if parser._require_command and #commands > 0 then
|
||||||
parser:error("command is required")
|
parser:error("command is required")
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, option in ipairs(options) do
|
for _, option in ipairs(options) do
|
||||||
parser:assert(invocations[option] >= option.mincount,
|
parser:assert(invocations[option] >= option._mincount,
|
||||||
"option %s must be used at least %d times", option.name, option.mincount
|
"option %s must be used at least %d times", option._name, option._mincount
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user