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