xref: /minix3/crypto/external/bsd/netpgp/dist/bindings/lua/optparse.lua (revision ebfedea0ce5bbe81e252ddf32d732e40fb633fae)
1*ebfedea0SLionel Sambuc-- Lua command line option parser.
2*ebfedea0SLionel Sambuc-- Interface based on Pythons optparse.
3*ebfedea0SLionel Sambuc-- http://docs.python.org/lib/module-optparse.html
4*ebfedea0SLionel Sambuc-- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license)
5*ebfedea0SLionel Sambuc--
6*ebfedea0SLionel Sambuc-- To be used like this:
7*ebfedea0SLionel Sambuc-- t={usage="<some usage message>", version="<version string>"}
8*ebfedea0SLionel Sambuc-- op=OptionParser(t)
9*ebfedea0SLionel Sambuc-- op=add_option{"<opt>", action=<action>, dest=<dest>, help="<help message for this option>"}
10*ebfedea0SLionel Sambuc--
11*ebfedea0SLionel Sambuc-- with :
12*ebfedea0SLionel Sambuc--   <opt> the option string to be used (can be anything, if one letter opt, then should be -x val, more letters: -xy=val )
13*ebfedea0SLionel Sambuc--   <action> one of
14*ebfedea0SLionel Sambuc--   - store: store in options as key, val
15*ebfedea0SLionel Sambuc--   - store_true: stores key, true
16*ebfedea0SLionel Sambuc--   - store_false: stores key, false
17*ebfedea0SLionel Sambuc--   <dest> is the key under which the option is saved
18*ebfedea0SLionel Sambuc--
19*ebfedea0SLionel Sambuc-- options,args = op.parse_args()
20*ebfedea0SLionel Sambuc--
21*ebfedea0SLionel Sambuc-- now options is the table of options (key, val) and args is the table with non-option arguments.
22*ebfedea0SLionel Sambuc-- You can use op.fail(message) for failing and op.print_help() for printing the usage as you like.
23*ebfedea0SLionel Sambuc
24*ebfedea0SLionel Sambucfunction OptionParser(t)
25*ebfedea0SLionel Sambuc  local usage = t.usage
26*ebfedea0SLionel Sambuc  local version = t.version
27*ebfedea0SLionel Sambuc
28*ebfedea0SLionel Sambuc  local o = {}
29*ebfedea0SLionel Sambuc  local option_descriptions = {}
30*ebfedea0SLionel Sambuc  local option_of = {}
31*ebfedea0SLionel Sambuc
32*ebfedea0SLionel Sambuc  function o.fail(s) -- extension
33*ebfedea0SLionel Sambuc    io.stderr:write(s .. '\n')
34*ebfedea0SLionel Sambuc    os.exit(1)
35*ebfedea0SLionel Sambuc  end
36*ebfedea0SLionel Sambuc
37*ebfedea0SLionel Sambuc  function o.add_option(optdesc)
38*ebfedea0SLionel Sambuc    option_descriptions[#option_descriptions+1] = optdesc
39*ebfedea0SLionel Sambuc    for _,v in ipairs(optdesc) do
40*ebfedea0SLionel Sambuc      option_of[v] = optdesc
41*ebfedea0SLionel Sambuc    end
42*ebfedea0SLionel Sambuc  end
43*ebfedea0SLionel Sambuc  function o.parse_args()
44*ebfedea0SLionel Sambuc    -- expand options (e.g. "--input=file" -> "--input", "file")
45*ebfedea0SLionel Sambuc    local arg = {unpack(arg)}
46*ebfedea0SLionel Sambuc    for i=#arg,1,-1 do local v = arg[i]
47*ebfedea0SLionel Sambuc      local flag, val = v:match('^(%-%-%w+)=(.*)')
48*ebfedea0SLionel Sambuc      if flag then
49*ebfedea0SLionel Sambuc        arg[i] = flag
50*ebfedea0SLionel Sambuc        table.insert(arg, i+1, val)
51*ebfedea0SLionel Sambuc      end
52*ebfedea0SLionel Sambuc    end
53*ebfedea0SLionel Sambuc
54*ebfedea0SLionel Sambuc    local options = {}
55*ebfedea0SLionel Sambuc    local args = {}
56*ebfedea0SLionel Sambuc    local i = 1
57*ebfedea0SLionel Sambuc    while i <= #arg do local v = arg[i]
58*ebfedea0SLionel Sambuc      local optdesc = option_of[v]
59*ebfedea0SLionel Sambuc      if optdesc then
60*ebfedea0SLionel Sambuc        local action = optdesc.action
61*ebfedea0SLionel Sambuc        local val
62*ebfedea0SLionel Sambuc        if action == 'store' or action == nil then
63*ebfedea0SLionel Sambuc          i = i + 1
64*ebfedea0SLionel Sambuc          val = arg[i]
65*ebfedea0SLionel Sambuc          if not val then o.fail('option requires an argument ' .. v) end
66*ebfedea0SLionel Sambuc        elseif action == 'store_true' then
67*ebfedea0SLionel Sambuc          val = true
68*ebfedea0SLionel Sambuc        elseif action == 'store_false' then
69*ebfedea0SLionel Sambuc          val = false
70*ebfedea0SLionel Sambuc        end
71*ebfedea0SLionel Sambuc        options[optdesc.dest] = val
72*ebfedea0SLionel Sambuc      else
73*ebfedea0SLionel Sambuc        if v:match('^%-') then o.fail('invalid option ' .. v) end
74*ebfedea0SLionel Sambuc        args[#args+1] = v
75*ebfedea0SLionel Sambuc      end
76*ebfedea0SLionel Sambuc      i = i + 1
77*ebfedea0SLionel Sambuc    end
78*ebfedea0SLionel Sambuc    if options.help then
79*ebfedea0SLionel Sambuc      o.print_help()
80*ebfedea0SLionel Sambuc      os.exit()
81*ebfedea0SLionel Sambuc    end
82*ebfedea0SLionel Sambuc    if options.version then
83*ebfedea0SLionel Sambuc      io.stdout:write(t.version .. "\n")
84*ebfedea0SLionel Sambuc      os.exit()
85*ebfedea0SLionel Sambuc    end
86*ebfedea0SLionel Sambuc    return options, args
87*ebfedea0SLionel Sambuc  end
88*ebfedea0SLionel Sambuc
89*ebfedea0SLionel Sambuc  local function flags_str(optdesc)
90*ebfedea0SLionel Sambuc    local sflags = {}
91*ebfedea0SLionel Sambuc    local action = optdesc.action
92*ebfedea0SLionel Sambuc    for _,flag in ipairs(optdesc) do
93*ebfedea0SLionel Sambuc      local sflagend
94*ebfedea0SLionel Sambuc      if action == nil or action == 'store' then
95*ebfedea0SLionel Sambuc        local metavar = optdesc.metavar or optdesc.dest:upper()
96*ebfedea0SLionel Sambuc        sflagend = #flag == 2 and ' ' .. metavar
97*ebfedea0SLionel Sambuc                              or  '=' .. metavar
98*ebfedea0SLionel Sambuc      else
99*ebfedea0SLionel Sambuc        sflagend = ''
100*ebfedea0SLionel Sambuc      end
101*ebfedea0SLionel Sambuc      sflags[#sflags+1] = flag .. sflagend
102*ebfedea0SLionel Sambuc    end
103*ebfedea0SLionel Sambuc    return table.concat(sflags, ', ')
104*ebfedea0SLionel Sambuc  end
105*ebfedea0SLionel Sambuc
106*ebfedea0SLionel Sambuc  function o.print_help()
107*ebfedea0SLionel Sambuc    io.stdout:write("Usage: " .. usage:gsub('%%prog', arg[0]) .. "\n")
108*ebfedea0SLionel Sambuc    io.stdout:write("\n")
109*ebfedea0SLionel Sambuc    io.stdout:write("Options:\n")
110*ebfedea0SLionel Sambuc    for _,optdesc in ipairs(option_descriptions) do
111*ebfedea0SLionel Sambuc      io.stdout:write("  " .. flags_str(optdesc) ..
112*ebfedea0SLionel Sambuc                      "  " .. optdesc.help .. "\n")
113*ebfedea0SLionel Sambuc    end
114*ebfedea0SLionel Sambuc  end
115*ebfedea0SLionel Sambuc  o.add_option{"--help", action="store_true", dest="help",
116*ebfedea0SLionel Sambuc               help="show this help message and exit"}
117*ebfedea0SLionel Sambuc  if t.version then
118*ebfedea0SLionel Sambuc    o.add_option{"--version", action="store_true", dest="version",
119*ebfedea0SLionel Sambuc                 help="output version info."}
120*ebfedea0SLionel Sambuc  end
121*ebfedea0SLionel Sambuc  return o
122*ebfedea0SLionel Sambucend
123*ebfedea0SLionel Sambuc
124