Created
July 1, 2021 11:25
-
-
Save takase1121/3b598cfe1e0e15d7ff9fd0770743b7b1 to your computer and use it in GitHub Desktop.
arg parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Very simple arg parser | |
local function resolve(tbl, key) | |
if type(tbl[key]) == "string" then return resolve(tbl, tbl[key]) else return key end | |
end | |
local function consume_long(optlist, stack, opt) | |
local key, value = string.match(opt, "^([%w-_]+)=?(.*)$") | |
local cast = assert(optlist[key], "invalid parameter --" .. key) | |
if cast == true then | |
value = true | |
else | |
if #value == 0 then | |
value = assert(table.remove(stack), "no value is provided for parameter --"..key) | |
end | |
value = cast(value) | |
end | |
return key, value | |
end | |
local function consume_short(optlist, stack, opt) | |
local c, rest = string.match(opt, "^(.)(.+)$") | |
local key = resolve(optlist, c) | |
local cast = assert(optlist[key], "invalid parameter -" .. c) | |
local value = nil | |
if cast == true then | |
value = true | |
if #rest > 0 then | |
local nextc = string.match(rest, "^.") | |
if optlist[nextc] then | |
rest = "-" .. rest | |
end | |
table.insert(stack, rest) | |
end | |
else | |
if #rest > 0 then | |
value = rest | |
else | |
value = assert(table.remove(stack), "no value is provided for parameter -" .. c) | |
end | |
value = cast(value) | |
end | |
return key, value | |
end | |
local function parse(optlist, list, offset) | |
offset = offset or 1 | |
local stop_named = false | |
local named, positional, stack = {}, {}, {} | |
for i = #list, offset, -1 do | |
table.insert(stack, list[i]) | |
end | |
while #stack > 0 do | |
local arg = table.remove(stack) | |
local opttype, opt = string.match(arg, "^%-(.)(.+)$") | |
if not opttype then stop_named = true end | |
if stop_named then | |
table.insert(positional, arg) | |
else | |
local key, value | |
if opttype == "-" then | |
key, value = consume_long(optlist, stack, opt) | |
else | |
key, value = consume_short(optlist, stack, opttype .. opt) | |
end | |
named[key] = value | |
end | |
end | |
return named, positional | |
end | |
return parse |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment