-- Lua command line option parser. -- Interface based on Pythons optparse. -- http://docs.python.org/lib/module-optparse.html -- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license) -- -- To be used like this: -- t={usage="", version=""} -- op=OptionParser(t) -- op=add_option{"", action=, dest=, help=""} -- -- with : -- the option string to be used (can be anything, if one letter opt, then should be -x val, more letters: -xy=val ) -- one of -- - store: store in options as key, val -- - store_true: stores key, true -- - store_false: stores key, false -- is the key under which the option is saved -- -- options,args = op.parse_args() -- -- now options is the table of options (key, val) and args is the table with non-option arguments. -- You can use op.fail(message) for failing and op.print_help() for printing the usage as you like. function OptionParser(t) local usage = t.usage local version = t.version local o = {} local option_descriptions = {} local option_of = {} function o.fail(s) -- extension io.stderr:write(s .. '\n') os.exit(1) end function o.add_option(optdesc) option_descriptions[#option_descriptions+1] = optdesc for _,v in ipairs(optdesc) do option_of[v] = optdesc end end function o.parse_args() -- expand options (e.g. "--input=file" -> "--input", "file") local arg = {table.unpack(arg)} for i=#arg,1,-1 do local v = arg[i] local flag, val = v:match('^(%-%-%w+)=(.*)') if flag then arg[i] = flag table.insert(arg, i+1, val) end end local options = {} local args = {} local i = 1 while i <= #arg do local v = arg[i] local optdesc = option_of[v] if optdesc then local action = optdesc.action local val if action == 'store' or action == nil then i = i + 1 val = arg[i] if not val then o.fail('option requires an argument ' .. v) end elseif action == 'store_true' then val = true elseif action == 'store_false' then val = false end options[optdesc.dest] = val else if v:match('^%-') then o.fail('invalid option ' .. v) end args[#args+1] = v end i = i + 1 end if options.help then o.print_help() os.exit() end if options.version then io.stdout:write(t.version .. "\n") os.exit() end return options, args end local function flags_str(optdesc) local sflags = {} local action = optdesc.action for _,flag in ipairs(optdesc) do local sflagend if action == nil or action == 'store' then local metavar = optdesc.metavar or optdesc.dest:upper() sflagend = #flag == 2 and ' ' .. metavar or '=' .. metavar else sflagend = '' end sflags[#sflags+1] = flag .. sflagend end return table.concat(sflags, ', ') end function o.print_help() io.stdout:write("Usage: " .. usage:gsub('%%prog', arg[0]) .. "\n") io.stdout:write("\n") io.stdout:write("Options:\n") for _,optdesc in ipairs(option_descriptions) do io.stdout:write(" " .. flags_str(optdesc) .. " " .. optdesc.help .. "\n") end end o.add_option{"--help", action="store_true", dest="help", help="show this help message and exit"} if t.version then o.add_option{"--version", action="store_true", dest="version", help="output version info."} end return o end