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