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