Home | History | Annotate | Line # | Download | only in lua
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