Minor refactoring

This commit is contained in:
mpeterv
2014-03-02 02:10:46 +04:00
parent f24cfe9627
commit 9441804c3f

View File

@@ -1,34 +1,9 @@
local class = require "30log" local Parser, Command, Argument, Option
local function parse_boundaries(boundaries) do -- Create classes with setters
if tonumber(boundaries) then local class = require "30log"
return tonumber(boundaries), tonumber(boundaries)
end
if boundaries == "*" then local function add_setters(cl, fields)
return 0, math.huge
end
if boundaries == "+" then
return 1, math.huge
end
if boundaries == "?" then
return 0, 1
end
if boundaries:match "^%d+%-%d+$" then
local min, max = boundaries:match "^(%d+)%-(%d+)$"
return tonumber(min), tonumber(max)
end
if boundaries:match "^%d+%+$" then
local min = boundaries:match "^(%d+)%+$"
return tonumber(min), math.huge
end
end
local function add_setters(cl, fields)
for field, setter in pairs(fields) do for field, setter in pairs(fields) do
cl[field] = function(self, value) cl[field] = function(self, value)
if setter then if setter then
@@ -71,9 +46,9 @@ local function add_setters(cl, fields)
end end
return cl return cl
end end
local typecheck = setmetatable({}, { local typecheck = setmetatable({}, {
__index = function(self, type_) __index = function(self, type_)
local typechecker_factory = function(field) local typechecker_factory = function(field)
return function(_, value) return function(_, value)
@@ -86,23 +61,51 @@ local typecheck = setmetatable({}, {
self[type_] = typechecker_factory self[type_] = typechecker_factory
return typechecker_factory return typechecker_factory
end end
}) })
local function aliased_name(self, name) local function aliased_name(self, name)
typecheck.string "name" (self, name) typecheck.string "name" (self, name)
table.insert(self._aliases, name) table.insert(self._aliases, name)
end end
local function aliased_aliases(self, aliases) local function aliased_aliases(self, aliases)
typecheck.table "aliases" (self, aliases) typecheck.table "aliases" (self, aliases)
if not self._name then if not self._name then
self._name = aliases[1] self._name = aliases[1]
end end
end end
local function boundaries(field) local function parse_boundaries(boundaries)
if tonumber(boundaries) then
return tonumber(boundaries), tonumber(boundaries)
end
if boundaries == "*" then
return 0, math.huge
end
if boundaries == "+" then
return 1, math.huge
end
if boundaries == "?" then
return 0, 1
end
if boundaries:match "^%d+%-%d+$" then
local min, max = boundaries:match "^(%d+)%-(%d+)$"
return tonumber(min), tonumber(max)
end
if boundaries:match "^%d+%+$" then
local min = boundaries:match "^(%d+)%+$"
return tonumber(min), math.huge
end
end
local function boundaries(field)
return function(self, value) return function(self, value)
local min, max = parse_boundaries(value) local min, max = parse_boundaries(value)
@@ -112,35 +115,35 @@ local function boundaries(field)
self["_min"..field], self["_max"..field] = min, max self["_min"..field], self["_max"..field] = min, max
end end
end end
local function convert(self, value) local function convert(self, value)
if type(value) ~= "function" then if type(value) ~= "function" then
if type(value) ~= "table" then if type(value) ~= "table" then
error(("bad field 'convert' (function or table expected, got %s)"):format(type(value))) error(("bad field 'convert' (function or table expected, got %s)"):format(type(value)))
end end
end end
end end
local Parser = add_setters(class { Parser = add_setters(class {
__name = "Parser", __name = "Parser",
_arguments = {}, _arguments = {},
_options = {}, _options = {},
_commands = {}, _commands = {},
_require_command = true _require_command = true
}, { }, {
name = typecheck.string "name", name = typecheck.string "name",
description = typecheck.string "description", description = typecheck.string "description",
epilog = typecheck.string "epilog", epilog = typecheck.string "epilog",
require_command = typecheck.boolean "require_command", require_command = typecheck.boolean "require_command",
usage = typecheck.string "usage", usage = typecheck.string "usage",
help = typecheck.string "help" help = typecheck.string "help"
}) })
local Command = add_setters(Parser:extends { Command = add_setters(Parser:extends {
__name = "Command", __name = "Command",
_aliases = {} _aliases = {}
}, { }, {
name = aliased_name, name = aliased_name,
aliases = aliased_aliases, aliases = aliased_aliases,
description = typecheck.string "description", description = typecheck.string "description",
@@ -150,16 +153,16 @@ local Command = add_setters(Parser:extends {
action = typecheck["function"] "action", action = typecheck["function"] "action",
usage = typecheck.string "usage", usage = typecheck.string "usage",
help = typecheck.string "help" help = typecheck.string "help"
}) })
local Argument = add_setters(class { Argument = add_setters(class {
__name = "Argument", __name = "Argument",
_minargs = 1, _minargs = 1,
_maxargs = 1, _maxargs = 1,
_mincount = 1, _mincount = 1,
_maxcount = 1, _maxcount = 1,
_defmode = "unused" _defmode = "unused"
}, { }, {
name = typecheck.string "name", name = typecheck.string "name",
description = typecheck.string "description", description = typecheck.string "description",
target = typecheck.string "target", target = typecheck.string "target",
@@ -169,14 +172,14 @@ local Argument = add_setters(class {
convert = convert, convert = convert,
usage = typecheck.string "usage", usage = typecheck.string "usage",
argname = typecheck.string "argname" argname = typecheck.string "argname"
}) })
local Option = add_setters(Argument:extends { Option = add_setters(Argument:extends {
__name = "Option", __name = "Option",
_aliases = {}, _aliases = {},
_mincount = 0, _mincount = 0,
_overwrite = true _overwrite = true
}, { }, {
name = aliased_name, name = aliased_name,
aliases = aliased_aliases, aliases = aliased_aliases,
description = typecheck.string "description", description = typecheck.string "description",
@@ -190,7 +193,8 @@ local Option = add_setters(Argument:extends {
action = typecheck["function"] "action", action = typecheck["function"] "action",
usage = typecheck.string "usage", usage = typecheck.string "usage",
argname = typecheck.string "argname" argname = typecheck.string "argname"
}) })
end
function Argument:_get_arg_usage(argname) function Argument:_get_arg_usage(argname)
argname = self._argname or argname argname = self._argname or argname
@@ -290,6 +294,34 @@ function Option:_get_target()
return self._name:sub(2) return self._name:sub(2)
end end
function Parser:_get_fullname()
local parent = self._parent
local buf = {self._name}
while parent do
table.insert(buf, 1, parent._name)
parent = parent._parent
end
return table.concat(buf, " ")
end
function Parser:_update_charset(charset)
charset = charset or {}
for _, command in ipairs(self._commands) do
command:_update_charset(charset)
end
for _, option in ipairs(self._options) do
for _, alias in ipairs(option._aliases) do
charset[alias:sub(1, 1)] = true
end
end
return charset
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)
@@ -344,34 +376,6 @@ function Parser:add_help(param)
return self return self
end end
function Parser:_get_fullname()
local parent = self._parent
local buf = {self._name}
while parent do
table.insert(buf, 1, parent._name)
parent = parent._parent
end
return table.concat(buf, " ")
end
function Parser:_update_charset(charset)
charset = charset or {}
for _, command in ipairs(self._commands) do
command:_update_charset(charset)
end
for _, option in ipairs(self._options) do
for _, alias in ipairs(option._aliases) do
charset[alias:sub(1, 1)] = true
end
end
return charset
end
local max_usage_width = 70 local max_usage_width = 70
local usage_welcome = "Usage: " local usage_welcome = "Usage: "