Skip to content

Instantly share code, notes, and snippets.

@IS2511
Last active January 16, 2021 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IS2511/96847fe185278b457505218b1c141f9d to your computer and use it in GitHub Desktop.
Save IS2511/96847fe185278b457505218b1c141f9d to your computer and use it in GitHub Desktop.
parg.lua - parsing command-line arguments with optional callbacks (https://pastebin.com/nSgXWHtp)
--[[
parg https://gist.github.com/IS2511/96847fe185278b457505218b1c141f9d
Parsing command-line arguments with optional callbacks
Pastebin: https://pastebin.com/nSgXWHtp
Author: IS2511
]]--
local parg = {
reg = {}
}
function parg.parse(a)
if type(a) ~= "table" then error("Expected table on 1, got "..type(a)) end
-- [0] Script location, assuming parent script is main
local t = { [0] = debug.getinfo(3, "S").source:sub(2) }
local i = 1
while i <= #a do
-- local v = a[i]
if (a[i]:sub(1, 1) == "-") and (a[i] ~= "--") then
if a[i]:sub(2, 2) == "-" then
local eq, _ = a[i]:find("=", 1, true)
if eq ~= nil then
local n, v = a[i]:sub(3, eq-1), a[i]:sub(eq+1, #(a[i]))
if parg.reg[n] ~= nil then -- REG
if parg.reg[n].type == "value" then
t[n] = v
else
if t[n] == nil then t[n] = 0 end
t[n] = t[n] + 1
end
if parg.reg[n].same ~= nil then -- SAME
for ii, nn in ipairs(parg.reg[n].same) do
t[nn] = t[n]
end
end -- SAME
else -- parg.reg[n] == nil
t[n] = v
end -- parg.reg[n] ~= nil
else -- eq == nil
local n, v = a[i]:sub(3, #(a[i])), a[i+1]
if parg.reg[n] ~= nil then -- REG
if parg.reg[n].type == "value" then
if v ~= nil then
if v:sub(1, 1) ~= "-" then
t[n] = v
i = i + 1
-- else -- TODO: Should I just leave it nil?
-- t[n] = ""
end
-- else -- TODO: Should I just leave it nil?
-- t[n] = ""
end -- v ~= nil
-- parg.reg[n].cb(t[n])
else -- parg.reg[n].type ~= "value"
if t[n] == nil then t[n] = 0 end
t[n] = t[n] + 1
end -- parg.reg[n].type == "value"
if parg.reg[n].same ~= nil then -- SAME
for ii, nn in ipairs(parg.reg[n].same) do
t[nn] = t[n]
end
end -- SAME
else -- parg.reg[n] == nil
if t[n] == nil then t[n] = 0 end
t[n] = t[n] + 1
end -- parg.reg[n] ~= nil
end -- eq ~= nil
else -- if a[i]:sub(2, 2) ~= "-"
for j=2, #(a[i]) do
local b = a[i]:sub(j, j)
if (b == "=") and (j ~= #(a[i])) then
local n, v = a[i]:sub(j-1, j-1), a[i]:sub(j+1, #(a[i]))
if parg.reg[n] ~= nil then -- REG
if parg.reg[n].type == "value" then
t[n] = v
end
if parg.reg[n].same ~= nil then -- SAME
for ii, nn in ipairs(parg.reg[n].same) do
t[nn] = t[n]
end
end -- SAME
break -- for j=2, #(a[i])
else -- parg.reg[n] == nil
t[n] = v
break -- for j=2, #(a[i])
end -- parg.reg[n] ~= nil
else -- (b ~= "=") or (j == #(a[i]))
if parg.reg[b] ~= nil then
if (t[b] == nil) and parg.reg[b].type == "flag" then t[b] = 0 end
else
if t[b] == nil then t[b] = 0 end
end
if type(t[b]) == "number" then
t[b] = t[b] + 1
end
end -- (b == "=") and (j ~= #(a[i]))
end -- for j=2, #(a[i])
local n, v = a[i]:sub(#(a[i]), #(a[i])), a[i+1]
if parg.reg[n] ~= nil then -- REG
if (v ~= nil) and (parg.reg[n].type == "value") then
if v:sub(1, 1) ~= "-" then
t[n] = v
i = i + 1
-- else -- TODO: Should I just leave it nil?
-- t[n] = ""
end -- v:sub(1, 1) ~= "-"
end -- (v ~= nil) and (parg.reg[n].type == "value")
if parg.reg[n].same ~= nil then -- SAME
for ii, nn in ipairs(parg.reg[n].same) do
t[nn] = t[n]
end
end -- SAME
end -- parg.reg[n] ~= nil
end -- if a[i]:sub(2, 2) == "-"
else -- a[i]:sub(1, 1) ~= "-" or (a[i] == "--")
table.insert(t, a[i])
end -- a[i]:sub(1, 1) == "-"
i = i + 1
end -- while i <= #a
for n, r in pairs(parg.reg) do
if parg.reg[n] ~= nil then
if (r.type == "flag") and (t[n] == nil) then
if r.same ~= nil then
for i, v in ipairs(r.same) do
t[v] = 0
end
else -- r.same == nil
t[n] = 0
end -- r.same ~= nil
end -- (r.type == "flag") and (t[n] == nil)
if r.cb ~= nil then r.cb(t[n]) end
if r.same ~= nil then -- Clearing same, cb already done
for i, v in ipairs(r.same) do
parg.reg[v] = nil
end
end
end -- parg.reg ~= nil
end -- for n, r in pairs(parg.reg)
parg.reg = {} -- "Clearing" memory
return t
end
-- Register an argument, or a list of arguments with same values (aliases)
function parg.register(argument, argType, callback)
if type(argument) == "table" then
for i, v in ipairs(argument) do
parg.register(v, argType, callback)
parg.reg[v].same = argument
end
elseif type(argument) == "string" then
parg.reg[argument] = { type = argType, cb = callback, same = nil }
else
error("Expected string or table on 1, got "..type(argument))
end
end
function parg.unregister(argument, clearSame)
if clearSame == nil then clearSame = false end
if type(clearSame) ~= "boolean" then error("Expected boolean on 2, got "..type(clearSame)) end
if type(argument) == "table" then
for i, v in ipairs(argument) do
parg.unregister(v, clearSame)
end
elseif type(argument) == "string" then
if parg.reg[v] ~= nil then
if parg.reg[argument].same ~= nil then
if clearSame then
for i, v in ipairs(parg.reg[argument].same) do
parg.reg[v] = nil
end
else -- not clearSame
for i, v in pairs(parg.reg) do
if v.same ~= nil then
for ii, vv in ipairs(v.same) do
if vv == argument then table.remove(v.same, ii) end
end
end -- v.same ~= nil
end -- for i, v in pairs(parg.reg)
parg.reg[argument] = nil
end
else -- parg.reg[argument].same == nil
parg.reg[argument] = nil
end -- parg.reg[argument].same ~= nil
end -- parg.reg[v] ~= nil
else
error("Expected string or table on 1, got "..type(argument))
end
end
setmetatable(parg, { __call = function (this, a) return parg.parse(a) end } )
return parg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment