From 42608086c666e23ceac0e9046836a8fefe00e5b2 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 2 Mar 2016 14:27:07 +0800 Subject: add `nerv.print_usage(options)` --- nerv/init.lua | 59 ++++++++++++++++++++++++++++++++++++++++++++---- nerv/test/parse_args.lua | 25 ++++++++++---------- 2 files changed, 67 insertions(+), 17 deletions(-) (limited to 'nerv') diff --git a/nerv/init.lua b/nerv/init.lua index fdfd531..d72d8b8 100644 --- a/nerv/init.lua +++ b/nerv/init.lua @@ -173,6 +173,23 @@ function nerv.include(filename) end --- Parse the command-line options and arguments +-- @param argv the argrument list to parsed +-- @param options The specification of options, should be a list of tables, +-- each one for exactly one available option, say `v`, with `v[1]`, `v[2]`, +-- `v[3]` indicating the full name of the option, the short form of the option +-- (when it is a boolean option) and the type of the value controlled by the +-- option. `default` and `desc` keys can also be specified to set the default +-- value and description of the option. +-- +-- An example of specification: +-- {{"aaa", "a", "bool", default = false, desc = "an option called aaa"}, +-- {"bbb", "b", "bool", default = true, desc = "bbb is set to be true if --bbb=no does not present"}, +-- {"ccc", nil, "int", default = 0, desc = "ccc expects an integeral value"}}` +-- +-- @return args, opts The non-option arguments and parsed options. `opts` is +-- again a list of tables, each of which corresponds to one table in parameter +-- `options`. The parsed value could be accessed by `opts["aaa"].val` (which is +-- `true` if "--aaa" or "-a" is specified). function nerv.parse_args(argv, options) local is_opt_exp = "^[-](.*)$" local sim_opt_exp = "^[-]([a-z]+)$" @@ -190,14 +207,14 @@ function nerv.parse_args(argv, options) v[3] == nil then err() end - opt_full = v[1] - opt_short = v[2] - opt_type = v[3] + local opt_full = v[1] + local opt_short = v[2] + local opt_type = v[3] local opt_meta = {type = opt_type, desc = v.desc or "", val = v.default} if opt_short ~= nil then - if type(opt_short) ~= "string" then err() end + if type(opt_short) ~= "string" or #opt_short ~= 1 then err() end if opt_type ~= "bool" then nerv.error("only boolean option could have short form") end @@ -275,6 +292,40 @@ function nerv.parse_args(argv, options) return args, opts end +--- Print usage information of the command-line options +-- @param options the list of options used in `parse_args` +function nerv.print_usage(options) + local full_maxlen = 0 + local type_maxlen = 0 + local default_maxlen = 0 + for _, v in ipairs(options) do + local opt_full = v[1] + local opt_short = v[2] + local opt_type = v[3] + full_maxlen = math.max(full_maxlen, #opt_full or 0) + type_maxlen = math.max(full_maxlen, #opt_type or 0) + default_maxlen = math.max(full_maxlen, #tostring(v.default) or 0) + end + local function pattern_gen() + return string.format("\t%%-%ds\t%%-2s\t%%-%ds\t%%-%ds\t%%s\n", + full_maxlen, type_maxlen, default_maxlen) + end + nerv.printf("\n") + nerv.printf(pattern_gen(), "Option", "Abbr.", "Type", "Default", "Desc.") + for _, v in ipairs(options) do + local opt_full = v[1] + local opt_short = v[2] + local opt_type = v[3] + nerv.printf(pattern_gen(), + (opt_full and '--' .. opt_full) or "", + (opt_short and '-' .. opt_short) or "", + opt_type, + v.default or "", + v.desc or "") + end + nerv.printf("\n") +end + -- the following lines trigger the initialization of basic modules nerv.include('matrix/init.lua') diff --git a/nerv/test/parse_args.lua b/nerv/test/parse_args.lua index 7146c3b..0d280a1 100644 --- a/nerv/test/parse_args.lua +++ b/nerv/test/parse_args.lua @@ -1,16 +1,15 @@ -args, opts = nerv.parse_args( - {"arg1", "arg2", "-abcd", "arg3", - "--hehe", "--oh=no", "--uid=43", - "highfive", "--str=hello"}, +local options = {{"abandon", "a", "bool", default = false, desc = "abandon your belief"}, + {"bullshit", "b", "bool", default = false, desc = "start to bullshit"}, + {"cheat", "c", "bool", default = false, desc = "try to cheat"}, + {"delete", "d", "bool", default = false, desc = "remove everything"}, + {"hehe", "h", "bool", default = false, desc = "233333"}, + {"oh", "o", "bool", default = true, desc = "oh yes!"}, + {"uid", nil, "int", desc = "user uid"}, + {"str", nil, "string", desc = "test string"}} - {{"abandon", "a", "bool", default = false, desc = "abandon your belief"}, - {"bullshit", "b", "bool", default = false, desc = "start to bullshit"}, - {"cheat", "c", "bool", default = false, desc = "try to cheat"}, - {"delete", "d", "bool", default = false, desc = "remove everything"}, - {"hehe", "h", "bool", default = false, desc = "233333"}, - {"oh", "o", "bool", default = true, desc = "oh yes!"}, - {"uid", nil, "int", desc = "user uid"}, - {"str", nil, "string", desc = "test string"}} - ) +args, opts = nerv.parse_args({"arg1", "arg2", "-abcd", "arg3", + "--hehe", "--oh=no", "--uid=43", + "highfive", "--str=hello"}, options) +nerv.print_usage(options) print(table.tostring(args), table.tostring(opts)) -- cgit v1.2.3