Last active
January 16, 2021 19:11
-
-
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)
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
--[[ | |
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