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.2 sevan 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