Home | History | Annotate | Download | only in vendor
      1 -- The MIT License (MIT)
      2 
      3 -- Copyright (c) 2013 - 2015 Peter Melnichenko
      4 
      5 -- Permission is hereby granted, free of charge, to any person obtaining a copy of
      6 -- this software and associated documentation files (the "Software"), to deal in
      7 -- the Software without restriction, including without limitation the rights to
      8 -- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
      9 -- the Software, and to permit persons to whom the Software is furnished to do so,
     10 -- subject to the following conditions:
     11 
     12 -- The above copyright notice and this permission notice shall be included in all
     13 -- copies or substantial portions of the Software.
     14 
     15 -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
     17 -- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
     18 -- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
     19 -- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20 -- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 local function deep_update(t1, t2)
     23    for k, v in pairs(t2) do
     24       if type(v) == "table" then
     25          v = deep_update({}, v)
     26       end
     27 
     28       t1[k] = v
     29    end
     30 
     31    return t1
     32 end
     33 
     34 -- A property is a tuple {name, callback}.
     35 -- properties.args is number of properties that can be set as arguments
     36 -- when calling an object.
     37 local function class(prototype, properties, parent)
     38    -- Class is the metatable of its instances.
     39    local cl = {}
     40    cl.__index = cl
     41 
     42    if parent then
     43       cl.__prototype = deep_update(deep_update({}, parent.__prototype), prototype)
     44    else
     45       cl.__prototype = prototype
     46    end
     47 
     48    if properties then
     49       local names = {}
     50 
     51       -- Create setter methods and fill set of property names.
     52       for _, property in ipairs(properties) do
     53          local name, callback = property[1], property[2]
     54 
     55          cl[name] = function(self, value)
     56             if not callback(self, value) then
     57                self["_" .. name] = value
     58             end
     59 
     60             return self
     61          end
     62 
     63          names[name] = true
     64       end
     65 
     66       function cl.__call(self, ...)
     67          -- When calling an object, if the first argument is a table,
     68          -- interpret keys as property names, else delegate arguments
     69          -- to corresponding setters in order.
     70          if type((...)) == "table" then
     71             for name, value in pairs((...)) do
     72                if names[name] then
     73                   self[name](self, value)
     74                end
     75             end
     76          else
     77             local nargs = select("#", ...)
     78 
     79             for i, property in ipairs(properties) do
     80                if i > nargs or i > properties.args then
     81                   break
     82                end
     83 
     84                local arg = select(i, ...)
     85 
     86                if arg ~= nil then
     87                   self[property[1]](self, arg)
     88                end
     89             end
     90          end
     91 
     92          return self
     93       end
     94    end
     95 
     96    -- If indexing class fails, fallback to its parent.
     97    local class_metatable = {}
     98    class_metatable.__index = parent
     99 
    100    function class_metatable.__call(self, ...)
    101       -- Calling a class returns its instance.
    102       -- Arguments are delegated to the instance.
    103       local object = deep_update({}, self.__prototype)
    104       setmetatable(object, self)
    105       return object(...)
    106    end
    107 
    108    return setmetatable(cl, class_metatable)
    109 end
    110 
    111 local function typecheck(name, types, value)
    112    for _, type_ in ipairs(types) do
    113       if type(value) == type_ then
    114          return true
    115       end
    116    end
    117 
    118    error(("bad property '%s' (%s expected, got %s)"):format(name, table.concat(types, " or "), type(value)))
    119 end
    120 
    121 local function typechecked(name, ...)
    122    local types = {...}
    123    return {name, function(_, value) typecheck(name, types, value) end}
    124 end
    125 
    126 local multiname = {"name", function(self, value)
    127    typecheck("name", {"string"}, value)
    128 
    129    for alias in value:gmatch("%S+") do
    130       self._name = self._name or alias
    131       table.insert(self._aliases, alias)
    132    end
    133 
    134    -- Do not set _name as with other properties.
    135    return true
    136 end}
    137 
    138 local function parse_boundaries(str)
    139    if tonumber(str) then
    140       return tonumber(str), tonumber(str)
    141    end
    142 
    143    if str == "*" then
    144       return 0, math.huge
    145    end
    146 
    147    if str == "+" then
    148       return 1, math.huge
    149    end
    150 
    151    if str == "?" then
    152       return 0, 1
    153    end
    154 
    155    if str:match "^%d+%-%d+$" then
    156       local min, max = str:match "^(%d+)%-(%d+)$"
    157       return tonumber(min), tonumber(max)
    158    end
    159 
    160    if str:match "^%d+%+$" then
    161       local min = str:match "^(%d+)%+$"
    162       return tonumber(min), math.huge
    163    end
    164 end
    165 
    166 local function boundaries(name)
    167    return {name, function(self, value)
    168       typecheck(name, {"number", "string"}, value)
    169 
    170       local min, max = parse_boundaries(value)
    171 
    172       if not min then
    173          error(("bad property '%s'"):format(name))
    174       end
    175 
    176       self["_min" .. name], self["_max" .. name] = min, max
    177    end}
    178 end
    179 
    180 local actions = {}
    181 
    182 local option_action = {"action", function(_, value)
    183    typecheck("action", {"function", "string"}, value)
    184 
    185    if type(value) == "string" and not actions[value] then
    186       error(("unknown action '%s'"):format(value))
    187    end
    188 end}
    189 
    190 local option_init = {"init", function(self)
    191    self._has_init = true
    192 end}
    193 
    194 local option_default = {"default", function(self, value)
    195    if type(value) ~= "string" then
    196       self._init = value
    197       self._has_init = true
    198       return true
    199    end
    200 end}
    201 
    202 local add_help = {"add_help", function(self, value)
    203    typecheck("add_help", {"boolean", "string", "table"}, value)
    204 
    205    if self._has_help then
    206       table.remove(self._options)
    207       self._has_help = false
    208    end
    209 
    210    if value then
    211       local help = self:flag()
    212          :description "Show this help message and exit."
    213          :action(function()
    214             print(self:get_help())
    215             os.exit(0)
    216          end)
    217 
    218       if value ~= true then
    219          help = help(value)
    220       end
    221 
    222       if not help._name then
    223          help "-h" "--help"
    224       end
    225 
    226       self._has_help = true
    227    end
    228 end}
    229 
    230 local Parser = class({
    231    _arguments = {},
    232    _options = {},
    233    _commands = {},
    234    _mutexes = {},
    235    _require_command = true,
    236    _handle_options = true
    237 }, {
    238    args = 3,
    239    typechecked("name", "string"),
    240    typechecked("description", "string"),
    241    typechecked("epilog", "string"),
    242    typechecked("usage", "string"),
    243    typechecked("help", "string"),
    244    typechecked("require_command", "boolean"),
    245    typechecked("handle_options", "boolean"),
    246    typechecked("action", "function"),
    247    typechecked("command_target", "string"),
    248    add_help
    249 })
    250 
    251 local Command = class({
    252    _aliases = {}
    253 }, {
    254    args = 3,
    255    multiname,
    256    typechecked("description", "string"),
    257    typechecked("epilog", "string"),
    258    typechecked("target", "string"),
    259    typechecked("usage", "string"),
    260    typechecked("help", "string"),
    261    typechecked("require_command", "boolean"),
    262    typechecked("handle_options", "boolean"),
    263    typechecked("action", "function"),
    264    typechecked("command_target", "string"),
    265    add_help
    266 }, Parser)
    267 
    268 local Argument = class({
    269    _minargs = 1,
    270    _maxargs = 1,
    271    _mincount = 1,
    272    _maxcount = 1,
    273    _defmode = "unused",
    274    _show_default = true
    275 }, {
    276    args = 5,
    277    typechecked("name", "string"),
    278    typechecked("description", "string"),
    279    option_default,
    280    typechecked("convert", "function", "table"),
    281    boundaries("args"),
    282    typechecked("target", "string"),
    283    typechecked("defmode", "string"),
    284    typechecked("show_default", "boolean"),
    285    typechecked("argname", "string", "table"),
    286    option_action,
    287    option_init
    288 })
    289 
    290 local Option = class({
    291    _aliases = {},
    292    _mincount = 0,
    293    _overwrite = true
    294 }, {
    295    args = 6,
    296    multiname,
    297    typechecked("description", "string"),
    298    option_default,
    299    typechecked("convert", "function", "table"),
    300    boundaries("args"),
    301    boundaries("count"),
    302    typechecked("target", "string"),
    303    typechecked("defmode", "string"),
    304    typechecked("show_default", "boolean"),
    305    typechecked("overwrite", "boolean"),
    306    typechecked("argname", "string", "table"),
    307    option_action,
    308    option_init
    309 }, Argument)
    310 
    311 function Argument:_get_argument_list()
    312    local buf = {}
    313    local i = 1
    314 
    315    while i <= math.min(self._minargs, 3) do
    316       local argname = self:_get_argname(i)
    317 
    318       if self._default and self._defmode:find "a" then
    319          argname = "[" .. argname .. "]"
    320       end
    321 
    322       table.insert(buf, argname)
    323       i = i+1
    324    end
    325 
    326    while i <= math.min(self._maxargs, 3) do
    327       table.insert(buf, "[" .. self:_get_argname(i) .. "]")
    328       i = i+1
    329 
    330       if self._maxargs == math.huge then
    331          break
    332       end
    333    end
    334 
    335    if i < self._maxargs then
    336       table.insert(buf, "...")
    337    end
    338 
    339    return buf
    340 end
    341 
    342 function Argument:_get_usage()
    343    local usage = table.concat(self:_get_argument_list(), " ")
    344 
    345    if self._default and self._defmode:find "u" then
    346       if self._maxargs > 1 or (self._minargs == 1 and not self._defmode:find "a") then
    347          usage = "[" .. usage .. "]"
    348       end
    349    end
    350 
    351    return usage
    352 end
    353 
    354 function actions.store_true(result, target)
    355    result[target] = true
    356 end
    357 
    358 function actions.store_false(result, target)
    359    result[target] = false
    360 end
    361 
    362 function actions.store(result, target, argument)
    363    result[target] = argument
    364 end
    365 
    366 function actions.count(result, target, _, overwrite)
    367    if not overwrite then
    368       result[target] = result[target] + 1
    369    end
    370 end
    371 
    372 function actions.append(result, target, argument, overwrite)
    373    result[target] = result[target] or {}
    374    table.insert(result[target], argument)
    375 
    376    if overwrite then
    377       table.remove(result[target], 1)
    378    end
    379 end
    380 
    381 function actions.concat(result, target, arguments, overwrite)
    382    if overwrite then
    383       error("'concat' action can't handle too many invocations")
    384    end
    385 
    386    result[target] = result[target] or {}
    387 
    388    for _, argument in ipairs(arguments) do
    389       table.insert(result[target], argument)
    390    end
    391 end
    392 
    393 function Argument:_get_action()
    394    local action, init
    395 
    396    if self._maxcount == 1 then
    397       if self._maxargs == 0 then
    398          action, init = "store_true", nil
    399       else
    400          action, init = "store", nil
    401       end
    402    else
    403       if self._maxargs == 0 then
    404          action, init = "count", 0
    405       else
    406          action, init = "append", {}
    407       end
    408    end
    409 
    410    if self._action then
    411       action = self._action
    412    end
    413 
    414    if self._has_init then
    415       init = self._init
    416    end
    417 
    418    if type(action) == "string" then
    419       action = actions[action]
    420    end
    421 
    422    return action, init
    423 end
    424 
    425 -- Returns placeholder for `narg`-th argument.
    426 function Argument:_get_argname(narg)
    427    local argname = self._argname or self:_get_default_argname()
    428 
    429    if type(argname) == "table" then
    430       return argname[narg]
    431    else
    432       return argname
    433    end
    434 end
    435 
    436 function Argument:_get_default_argname()
    437    return "<" .. self._name .. ">"
    438 end
    439 
    440 function Option:_get_default_argname()
    441    return "<" .. self:_get_default_target() .. ">"
    442 end
    443 
    444 -- Returns label to be shown in the help message.
    445 function Argument:_get_label()
    446    return self._name
    447 end
    448 
    449 function Option:_get_label()
    450    local variants = {}
    451    local argument_list = self:_get_argument_list()
    452    table.insert(argument_list, 1, nil)
    453 
    454    for _, alias in ipairs(self._aliases) do
    455       argument_list[1] = alias
    456       table.insert(variants, table.concat(argument_list, " "))
    457    end
    458 
    459    return table.concat(variants, ", ")
    460 end
    461 
    462 function Command:_get_label()
    463    return table.concat(self._aliases, ", ")
    464 end
    465 
    466 function Argument:_get_description()
    467    if self._default and self._show_default then
    468       if self._description then
    469          return ("%s (default: %s)"):format(self._description, self._default)
    470       else
    471          return ("default: %s"):format(self._default)
    472       end
    473    else
    474       return self._description or ""
    475    end
    476 end
    477 
    478 function Command:_get_description()
    479    return self._description or ""
    480 end
    481 
    482 function Option:_get_usage()
    483    local usage = self:_get_argument_list()
    484    table.insert(usage, 1, self._name)
    485    usage = table.concat(usage, " ")
    486 
    487    if self._mincount == 0 or self._default then
    488       usage = "[" .. usage .. "]"
    489    end
    490 
    491    return usage
    492 end
    493 
    494 function Argument:_get_default_target()
    495    return self._name
    496 end
    497 
    498 function Option:_get_default_target()
    499    local res
    500 
    501    for _, alias in ipairs(self._aliases) do
    502       if alias:sub(1, 1) == alias:sub(2, 2) then
    503          res = alias:sub(3)
    504          break
    505       end
    506    end
    507 
    508    res = res or self._name:sub(2)
    509    return (res:gsub("-", "_"))
    510 end
    511 
    512 function Option:_is_vararg()
    513    return self._maxargs ~= self._minargs
    514 end
    515 
    516 function Parser:_get_fullname()
    517    local parent = self._parent
    518    local buf = {self._name}
    519 
    520    while parent do
    521       table.insert(buf, 1, parent._name)
    522       parent = parent._parent
    523    end
    524 
    525    return table.concat(buf, " ")
    526 end
    527 
    528 function Parser:_update_charset(charset)
    529    charset = charset or {}
    530 
    531    for _, command in ipairs(self._commands) do
    532       command:_update_charset(charset)
    533    end
    534 
    535    for _, option in ipairs(self._options) do
    536       for _, alias in ipairs(option._aliases) do
    537          charset[alias:sub(1, 1)] = true
    538       end
    539    end
    540 
    541    return charset
    542 end
    543 
    544 function Parser:argument(...)
    545    local argument = Argument(...)
    546    table.insert(self._arguments, argument)
    547    return argument
    548 end
    549 
    550 function Parser:option(...)
    551    local option = Option(...)
    552 
    553    if self._has_help then
    554       table.insert(self._options, #self._options, option)
    555    else
    556       table.insert(self._options, option)
    557    end
    558 
    559    return option
    560 end
    561 
    562 function Parser:flag(...)
    563    return self:option():args(0)(...)
    564 end
    565 
    566 function Parser:command(...)
    567    local command = Command():add_help(true)(...)
    568    command._parent = self
    569    table.insert(self._commands, command)
    570    return command
    571 end
    572 
    573 function Parser:mutex(...)
    574    local options = {...}
    575 
    576    for i, option in ipairs(options) do
    577       assert(getmetatable(option) == Option, ("bad argument #%d to 'mutex' (Option expected)"):format(i))
    578    end
    579 
    580    table.insert(self._mutexes, options)
    581    return self
    582 end
    583 
    584 local max_usage_width = 70
    585 local usage_welcome = "Usage: "
    586 
    587 function Parser:get_usage()
    588    if self._usage then
    589       return self._usage
    590    end
    591 
    592    local lines = {usage_welcome .. self:_get_fullname()}
    593 
    594    local function add(s)
    595       if #lines[#lines]+1+#s <= max_usage_width then
    596          lines[#lines] = lines[#lines] .. " " .. s
    597       else
    598          lines[#lines+1] = (" "):rep(#usage_welcome) .. s
    599       end
    600    end
    601 
    602    -- This can definitely be refactored into something cleaner
    603    local mutex_options = {}
    604    local vararg_mutexes = {}
    605 
    606    -- First, put mutexes which do not contain vararg options and remember those which do
    607    for _, mutex in ipairs(self._mutexes) do
    608       local buf = {}
    609       local is_vararg = false
    610 
    611       for _, option in ipairs(mutex) do
    612          if option:_is_vararg() then
    613             is_vararg = true
    614          end
    615 
    616          table.insert(buf, option:_get_usage())
    617          mutex_options[option] = true
    618       end
    619 
    620       local repr = "(" .. table.concat(buf, " | ") .. ")"
    621 
    622       if is_vararg then
    623          table.insert(vararg_mutexes, repr)
    624       else
    625          add(repr)
    626       end
    627    end
    628 
    629    -- Second, put regular options
    630    for _, option in ipairs(self._options) do
    631       if not mutex_options[option] and not option:_is_vararg() then
    632          add(option:_get_usage())
    633       end
    634    end
    635 
    636    -- Put positional arguments
    637    for _, argument in ipairs(self._arguments) do
    638       add(argument:_get_usage())
    639    end
    640 
    641    -- Put mutexes containing vararg options
    642    for _, mutex_repr in ipairs(vararg_mutexes) do
    643       add(mutex_repr)
    644    end
    645 
    646    for _, option in ipairs(self._options) do
    647       if not mutex_options[option] and option:_is_vararg() then
    648          add(option:_get_usage())
    649       end
    650    end
    651 
    652    if #self._commands > 0 then
    653       if self._require_command then
    654          add("<command>")
    655       else
    656          add("[<command>]")
    657       end
    658 
    659       add("...")
    660    end
    661 
    662    return table.concat(lines, "\n")
    663 end
    664 
    665 local margin_len = 3
    666 local margin_len2 = 25
    667 local margin = (" "):rep(margin_len)
    668 local margin2 = (" "):rep(margin_len2)
    669 
    670 local function make_two_columns(s1, s2)
    671    if s2 == "" then
    672       return margin .. s1
    673    end
    674 
    675    s2 = s2:gsub("\n", "\n" .. margin2)
    676 
    677    if #s1 < (margin_len2-margin_len) then
    678       return margin .. s1 .. (" "):rep(margin_len2-margin_len-#s1) .. s2
    679    else
    680       return margin .. s1 .. "\n" .. margin2 .. s2
    681    end
    682 end
    683 
    684 function Parser:get_help()
    685    if self._help then
    686       return self._help
    687    end
    688 
    689    local blocks = {self:get_usage()}
    690 
    691    if self._description then
    692       table.insert(blocks, self._description)
    693    end
    694 
    695    local labels = {"Arguments:", "Options:", "Commands:"}
    696 
    697    for i, elements in ipairs{self._arguments, self._options, self._commands} do
    698       if #elements > 0 then
    699          local buf = {labels[i]}
    700 
    701          for _, element in ipairs(elements) do
    702             table.insert(buf, make_two_columns(element:_get_label(), element:_get_description()))
    703          end
    704 
    705          table.insert(blocks, table.concat(buf, "\n"))
    706       end
    707    end
    708 
    709    if self._epilog then
    710       table.insert(blocks, self._epilog)
    711    end
    712 
    713    return table.concat(blocks, "\n\n")
    714 end
    715 
    716 local function get_tip(context, wrong_name)
    717    local context_pool = {}
    718    local possible_name
    719    local possible_names = {}
    720 
    721    for name in pairs(context) do
    722       if type(name) == "string" then
    723          for i = 1, #name do
    724             possible_name = name:sub(1, i - 1) .. name:sub(i + 1)
    725 
    726             if not context_pool[possible_name] then
    727                context_pool[possible_name] = {}
    728             end
    729 
    730             table.insert(context_pool[possible_name], name)
    731          end
    732       end
    733    end
    734 
    735    for i = 1, #wrong_name + 1 do
    736       possible_name = wrong_name:sub(1, i - 1) .. wrong_name:sub(i + 1)
    737 
    738       if context[possible_name] then
    739          possible_names[possible_name] = true
    740       elseif context_pool[possible_name] then
    741          for _, name in ipairs(context_pool[possible_name]) do
    742             possible_names[name] = true
    743          end
    744       end
    745    end
    746 
    747    local first = next(possible_names)
    748 
    749    if first then
    750       if next(possible_names, first) then
    751          local possible_names_arr = {}
    752 
    753          for name in pairs(possible_names) do
    754             table.insert(possible_names_arr, "'" .. name .. "'")
    755          end
    756 
    757          table.sort(possible_names_arr)
    758          return "\nDid you mean one of these: " .. table.concat(possible_names_arr, " ") .. "?"
    759       else
    760          return "\nDid you mean '" .. first .. "'?"
    761       end
    762    else
    763       return ""
    764    end
    765 end
    766 
    767 local ElementState = class({
    768    invocations = 0
    769 })
    770 
    771 function ElementState:__call(state, element)
    772    self.state = state
    773    self.result = state.result
    774    self.element = element
    775    self.target = element._target or element:_get_default_target()
    776    self.action, self.result[self.target] = element:_get_action()
    777    return self
    778 end
    779 
    780 function ElementState:error(fmt, ...)
    781    self.state:error(fmt, ...)
    782 end
    783 
    784 function ElementState:convert(argument)
    785    local converter = self.element._convert
    786 
    787    if converter then
    788       local ok, err
    789 
    790       if type(converter) == "function" then
    791          ok, err = converter(argument)
    792       else
    793          ok = converter[argument]
    794       end
    795 
    796       if ok == nil then
    797          self:error(err and "%s" or "malformed argument '%s'", err or argument)
    798       end
    799 
    800       argument = ok
    801    end
    802 
    803    return argument
    804 end
    805 
    806 function ElementState:default(mode)
    807    return self.element._defmode:find(mode) and self.element._default
    808 end
    809 
    810 local function bound(noun, min, max, is_max)
    811    local res = ""
    812 
    813    if min ~= max then
    814       res = "at " .. (is_max and "most" or "least") .. " "
    815    end
    816 
    817    local number = is_max and max or min
    818    return res .. tostring(number) .. " " .. noun ..  (number == 1 and "" or "s")
    819 end
    820 
    821 function ElementState:invoke(alias)
    822    self.open = true
    823    self.name = ("%s '%s'"):format(alias and "option" or "argument", alias or self.element._name)
    824    self.overwrite = false
    825 
    826    if self.invocations >= self.element._maxcount then
    827       if self.element._overwrite then
    828          self.overwrite = true
    829       else
    830          self:error("%s must be used %s", self.name, bound("time", self.element._mincount, self.element._maxcount, true))
    831       end
    832    else
    833       self.invocations = self.invocations + 1
    834    end
    835 
    836    self.args = {}
    837 
    838    if self.element._maxargs <= 0 then
    839       self:close()
    840    end
    841 
    842    return self.open
    843 end
    844 
    845 function ElementState:pass(argument)
    846    argument = self:convert(argument)
    847    table.insert(self.args, argument)
    848 
    849    if #self.args >= self.element._maxargs then
    850       self:close()
    851    end
    852 
    853    return self.open
    854 end
    855 
    856 function ElementState:complete_invocation()
    857    while #self.args < self.element._minargs do
    858       self:pass(self.element._default)
    859    end
    860 end
    861 
    862 function ElementState:close()
    863    if self.open then
    864       self.open = false
    865 
    866       if #self.args < self.element._minargs then
    867          if self:default("a") then
    868             self:complete_invocation()
    869          else
    870             if #self.args == 0 then
    871                if getmetatable(self.element) == Argument then
    872                   self:error("missing %s", self.name)
    873                elseif self.element._maxargs == 1 then
    874                   self:error("%s requires an argument", self.name)
    875                end
    876             end
    877 
    878             self:error("%s requires %s", self.name, bound("argument", self.element._minargs, self.element._maxargs))
    879          end
    880       end
    881 
    882       local args = self.args
    883 
    884       if self.element._maxargs <= 1 then
    885          args = args[1]
    886       end
    887 
    888       if self.element._maxargs == 1 and self.element._minargs == 0 and self.element._mincount ~= self.element._maxcount then
    889          args = self.args
    890       end
    891 
    892       self.action(self.result, self.target, args, self.overwrite)
    893    end
    894 end
    895 
    896 local ParseState = class({
    897    result = {},
    898    options = {},
    899    arguments = {},
    900    argument_i = 1,
    901    element_to_mutexes = {},
    902    mutex_to_used_option = {},
    903    command_actions = {}
    904 })
    905 
    906 function ParseState:__call(parser, error_handler)
    907    self.parser = parser
    908    self.error_handler = error_handler
    909    self.charset = parser:_update_charset()
    910    self:switch(parser)
    911    return self
    912 end
    913 
    914 function ParseState:error(fmt, ...)
    915    self.error_handler(self.parser, fmt:format(...))
    916 end
    917 
    918 function ParseState:switch(parser)
    919    self.parser = parser
    920 
    921    if parser._action then
    922       table.insert(self.command_actions, {action = parser._action, name = parser._name})
    923    end
    924 
    925    for _, option in ipairs(parser._options) do
    926       option = ElementState(self, option)
    927       table.insert(self.options, option)
    928 
    929       for _, alias in ipairs(option.element._aliases) do
    930          self.options[alias] = option
    931       end
    932    end
    933 
    934    for _, mutex in ipairs(parser._mutexes) do
    935       for _, option in ipairs(mutex) do
    936          if not self.element_to_mutexes[option] then
    937             self.element_to_mutexes[option] = {}
    938          end
    939 
    940          table.insert(self.element_to_mutexes[option], mutex)
    941       end
    942    end
    943 
    944    for _, argument in ipairs(parser._arguments) do
    945       argument = ElementState(self, argument)
    946       table.insert(self.arguments, argument)
    947       argument:invoke()
    948    end
    949 
    950    self.handle_options = parser._handle_options
    951    self.argument = self.arguments[self.argument_i]
    952    self.commands = parser._commands
    953 
    954    for _, command in ipairs(self.commands) do
    955       for _, alias in ipairs(command._aliases) do
    956          self.commands[alias] = command
    957       end
    958    end
    959 end
    960 
    961 function ParseState:get_option(name)
    962    local option = self.options[name]
    963 
    964    if not option then
    965       self:error("unknown option '%s'%s", name, get_tip(self.options, name))
    966    else
    967       return option
    968    end
    969 end
    970 
    971 function ParseState:get_command(name)
    972    local command = self.commands[name]
    973 
    974    if not command then
    975       if #self.commands > 0 then
    976          self:error("unknown command '%s'%s", name, get_tip(self.commands, name))
    977       else
    978          self:error("too many arguments")
    979       end
    980    else
    981       return command
    982    end
    983 end
    984 
    985 function ParseState:invoke(option, name)
    986    self:close()
    987 
    988    if self.element_to_mutexes[option.element] then
    989       for _, mutex in ipairs(self.element_to_mutexes[option.element]) do
    990          local used_option = self.mutex_to_used_option[mutex]
    991 
    992          if used_option and used_option ~= option then
    993             self:error("option '%s' can not be used together with %s", name, used_option.name)
    994          else
    995             self.mutex_to_used_option[mutex] = option
    996          end
    997       end
    998    end
    999 
   1000    if option:invoke(name) then
   1001       self.option = option
   1002    end
   1003 end
   1004 
   1005 function ParseState:pass(arg)
   1006    if self.option then
   1007       if not self.option:pass(arg) then
   1008          self.option = nil
   1009       end
   1010    elseif self.argument then
   1011       if not self.argument:pass(arg) then
   1012          self.argument_i = self.argument_i + 1
   1013          self.argument = self.arguments[self.argument_i]
   1014       end
   1015    else
   1016       local command = self:get_command(arg)
   1017       self.result[command._target or command._name] = true
   1018 
   1019       if self.parser._command_target then
   1020          self.result[self.parser._command_target] = command._name
   1021       end
   1022 
   1023       self:switch(command)
   1024    end
   1025 end
   1026 
   1027 function ParseState:close()
   1028    if self.option then
   1029       self.option:close()
   1030       self.option = nil
   1031    end
   1032 end
   1033 
   1034 function ParseState:finalize()
   1035    self:close()
   1036 
   1037    for i = self.argument_i, #self.arguments do
   1038       local argument = self.arguments[i]
   1039       if #argument.args == 0 and argument:default("u") then
   1040          argument:complete_invocation()
   1041       else
   1042          argument:close()
   1043       end
   1044    end
   1045 
   1046    if self.parser._require_command and #self.commands > 0 then
   1047       self:error("a command is required")
   1048    end
   1049 
   1050    for _, option in ipairs(self.options) do
   1051       local name = option.name or ("option '%s'"):format(option.element._name)
   1052 
   1053       if option.invocations == 0 then
   1054          if option:default("u") then
   1055             option:invoke(name)
   1056             option:complete_invocation()
   1057             option:close()
   1058          end
   1059       end
   1060 
   1061       local mincount = option.element._mincount
   1062 
   1063       if option.invocations < mincount then
   1064          if option:default("a") then
   1065             while option.invocations < mincount do
   1066                option:invoke(name)
   1067                option:close()
   1068             end
   1069          elseif option.invocations == 0 then
   1070             self:error("missing %s", name)
   1071          else
   1072             self:error("%s must be used %s", name, bound("time", mincount, option.element._maxcount))
   1073          end
   1074       end
   1075    end
   1076 
   1077    for i = #self.command_actions, 1, -1 do
   1078       self.command_actions[i].action(self.result, self.command_actions[i].name)
   1079    end
   1080 end
   1081 
   1082 function ParseState:parse(args)
   1083    for _, arg in ipairs(args) do
   1084       local plain = true
   1085 
   1086       if self.handle_options then
   1087          local first = arg:sub(1, 1)
   1088 
   1089          if self.charset[first] then
   1090             if #arg > 1 then
   1091                plain = false
   1092 
   1093                if arg:sub(2, 2) == first then
   1094                   if #arg == 2 then
   1095                      self:close()
   1096                      self.handle_options = false
   1097                   else
   1098                      local equals = arg:find "="
   1099                      if equals then
   1100                         local name = arg:sub(1, equals - 1)
   1101                         local option = self:get_option(name)
   1102 
   1103                         if option.element._maxargs <= 0 then
   1104                            self:error("option '%s' does not take arguments", name)
   1105                         end
   1106 
   1107                         self:invoke(option, name)
   1108                         self:pass(arg:sub(equals + 1))
   1109                      else
   1110                         local option = self:get_option(arg)
   1111                         self:invoke(option, arg)
   1112                      end
   1113                   end
   1114                else
   1115                   for i = 2, #arg do
   1116                      local name = first .. arg:sub(i, i)
   1117                      local option = self:get_option(name)
   1118                      self:invoke(option, name)
   1119 
   1120                      if i ~= #arg and option.element._maxargs > 0 then
   1121                         self:pass(arg:sub(i + 1))
   1122                         break
   1123                      end
   1124                   end
   1125                end
   1126             end
   1127          end
   1128       end
   1129 
   1130       if plain then
   1131          self:pass(arg)
   1132       end
   1133    end
   1134 
   1135    self:finalize()
   1136    return self.result
   1137 end
   1138 
   1139 function Parser:error(msg)
   1140    io.stderr:write(("%s\n\nError: %s\n"):format(self:get_usage(), msg))
   1141    os.exit(1)
   1142 end
   1143 
   1144 -- Compatibility with strict.lua and other checkers:
   1145 local default_cmdline = rawget(_G, "arg") or {}
   1146 
   1147 function Parser:_parse(args, error_handler)
   1148    return ParseState(self, error_handler):parse(args or default_cmdline)
   1149 end
   1150 
   1151 function Parser:parse(args)
   1152    return self:_parse(args, self.error)
   1153 end
   1154 
   1155 local function xpcall_error_handler(err)
   1156    return tostring(err) .. "\noriginal " .. debug.traceback("", 2):sub(2)
   1157 end
   1158 
   1159 function Parser:pparse(args)
   1160    local parse_error
   1161 
   1162    local ok, result = xpcall(function()
   1163       return self:_parse(args, function(_, err)
   1164          parse_error = err
   1165          error(err, 0)
   1166       end)
   1167    end, xpcall_error_handler)
   1168 
   1169    if ok then
   1170       return true, result
   1171    elseif not parse_error then
   1172       error(result, 0)
   1173    else
   1174       return false, parse_error
   1175    end
   1176 end
   1177 
   1178 return function(...)
   1179    return Parser(default_cmdline[0]):add_help(true)(...)
   1180 end
   1181