Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- [Library] ArgsParser
- @version 1.1, 2016-03-27
- @author TheOddByte
- --]]
- local ArgsParser = {}
- ArgsParser.__index = ArgsParser
- local function len( t )
- assert( type( t ) == "table", "table expected, got " .. type( t ) )
- local length = 0
- for k, v in pairs( t ) do
- length = length + 1
- end
- return length
- end
- local function displayUsage( self, detailed, err )
- local w, h = term.getSize()
- local program = shell.getRunningProgram()
- local length = 0
- term.write( "Usage: " .. program )
- for i = 1, #self.positional do
- write( " <" .. self.positional[i].name .. ">" )
- if #self.positional[i].name + 2 > length then
- length = #self.positional[i].name + 2
- end
- end
- for k, v in pairs( self.optional ) do
- write( " [" .. k .. "]" )
- if #k + 2 > length then
- length = #k + 2
- end
- end
- print( "" )
- local function wr( x, y, text )
- term.setCursorPos( x, y )
- term.write( text )
- end
- --# Show detailed info
- if detailed then
- print( #self.positional > 0 and "\n\nPositional arguments:" or "\n\nNo positional arguments\n" )
- if #self.positional > 0 then
- local x, y = term.getCursorPos()
- for i, v in ipairs( self.positional ) do
- wr( 3, y, v.name )
- wr( 3 + length, y, v.help and v.help or "No help available" )
- y = y + 1
- if y >= h then
- y = h
- os.pullEvent( "key" )
- term.scroll( 1 )
- end
- end
- print( "" )
- end
- print( len( self.optional ) > 0 and "\n\nOptional arguments:" or "\n\nNo optional arguments\n" )
- if len( self.optional ) > 0 then
- local x, y = term.getCursorPos()
- for k, v in pairs( self.optional ) do
- wr( 3, y, k )
- wr( 3 + length, y, v.help and v.help or "No help available" )
- y = y + 1
- if y >= h then
- y = h
- os.pullEvent( "key" )
- term.scroll( 1 )
- end
- end
- print( "" )
- end
- print( #self.examples > 0 and "\n\nExamples:" or "\n\nNo examples\n")
- if #self.examples > 0 then
- local x, y = term.getCursorPos();
- for i, v in ipairs( self.examples ) do
- wr( 3, y, program .. " " .. v )
- y = y + 1
- if y >= h then
- y = h
- os.pullEvent( "key" )
- term.scroll( 1 )
- end
- end
- end
- end
- --# Print the error if it's supplied
- if err then
- print( "\nerror: " .. err )
- end
- print("")
- error()
- end
- ArgsParser.init = function()
- local parser = {
- examples = {};
- positional = {};
- optional = {
- ["--help"] = {
- alt = "-h";
- optional = true;
- help = "Show this help message and exit";
- action = function( self )
- displayUsage( self, true )
- end
- }
- }
- }
- return setmetatable( parser, ArgsParser )
- end
- function ArgsParser:addArgument( name, alt, help, _type )
- --# Check for errors
- assert( type( name ) == "string", "string exptected, got " .. type( name ) )
- --# Check if it was an optional argument
- local optional = name:sub( 1, 1 ) == "-"
- --# Create the argument
- local arg = {
- name = optional and nil or name;
- alt = optional and alt and ( alt:sub( 1, 1 ) == "-" and alt or nil ) or nil;
- optional = optional;
- help = help;
- type = _type;
- }
- if optional then
- self.optional[name] = arg
- else
- table.insert( self.positional, arg )
- end
- end
- function ArgsParser:addExample( example )
- assert( type( example ) == "string", "string exptected, got " .. type( example ) )
- table.insert( self.examples, example )
- end
- function ArgsParser:parse( args )
- local i = 1
- local t = {}
- if #args < 1 then
- displayUsage( self, false, "too few arguments" )
- end
- for i, v in ipairs( args ) do
- if v == "-h" or v == "--help" then
- displayUsage( self, true )
- end
- end
- --# Handle positional arguments first
- if #self.positional > 0 then
- if #args < #self.positional then
- displayUsage( self, false, "too few arguments" )
- end
- for i = 1, #self.positional do
- for k, v in pairs( self.optional ) do
- if args[i] == k then
- displayUsage( self, false, "missing argument parameter" )
- else
- t[self.positional[i].name] = args[i]
- end
- end
- end
- end
- --# Handle the optional arguments
- while i <= #args do
- for k, v in pairs( self.optional ) do
- if args[i] == k or args[i] == v.alt then
- if v.action and type( v.action ) == "function" then
- return v.action( self )
- else
- if args[ i + 1 ] then
- for name, value in pairs( self.optional ) do
- if args[ i + 1 ] == param then
- return
- end
- end
- if v.type then
- if v.type == "number" then
- args[ i + 1 ] = type( tonumber( args[ i + 1 ] ) ) == "number" and tonumber( args[ i + 1 ] ) or displayUsage( self, false, "invalid type, expected number" )
- elseif v.type == "boolean" then
- args[ i + 1 ] = ( args[ i + 1 ] == "true" or args[ i + 1 ] == "false" ) and args[ i + 1 ] or displayUsage( self, false, "invalid type, expected boolean" )
- end
- end
- t[k:gsub( "-", "" )] = args[ i + 1 ]
- i = i + 2
- end
- end
- end
- end
- i = i + 1
- end
- return t
- end
- return ArgsParser
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement