IS2511

parg.lua

Jul 14th, 2020
1,130
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2.   parg https://gist.github.com/IS2511/96847fe185278b457505218b1c141f9d
  3.   Parsing command-line arguments with optional callbacks
  4.   Pastebin: https://pastebin.com/nSgXWHtp
  5.   Author: IS2511
  6. ]]--
  7.  
  8. local parg = {
  9.   reg = {}
  10. }
  11.  
  12. function parg.parse(a)
  13.   if type(a) ~= "table" then error("Expected table on 1, got "..type(a)) end
  14.  
  15.   -- [0] Script location, assuming parent script is main
  16.   local t = { [0] = debug.getinfo(3, "S").source:sub(2) }
  17.   local i = 1
  18.   while i <= #a do
  19.     -- local v = a[i]
  20.     if (a[i]:sub(1, 1) == "-") and (a[i] ~= "--") then
  21.       if a[i]:sub(2, 2) == "-" then
  22.         local eq, _ = a[i]:find("=", 1, true)
  23.         if eq ~= nil then
  24.           local n, v = a[i]:sub(3, eq-1), a[i]:sub(eq+1, #(a[i]))
  25.           if parg.reg[n] ~= nil then -- REG
  26.             if parg.reg[n].type == "value" then
  27.               t[n] = v
  28.             else
  29.               if t[n] == nil then t[n] = 0 end
  30.               t[n] = t[n] + 1
  31.             end
  32.             if parg.reg[n].same ~= nil then -- SAME
  33.               for ii, nn in ipairs(parg.reg[n].same) do
  34.                 t[nn] = t[n]
  35.               end
  36.             end -- SAME
  37.           else -- parg.reg[n] == nil
  38.             t[n] = v
  39.           end -- parg.reg[n] ~= nil
  40.         else -- eq == nil
  41.           local n, v = a[i]:sub(3, #(a[i])), a[i+1]
  42.           if parg.reg[n] ~= nil then -- REG
  43.             if parg.reg[n].type == "value" then
  44.               if v ~= nil then
  45.                 if v:sub(1, 1) ~= "-" then
  46.                   t[n] = v
  47.                   i = i + 1
  48.                 -- else -- TODO: Should I just leave it nil?
  49.                 --   t[n] = ""
  50.                 end
  51.               -- else -- TODO: Should I just leave it nil?
  52.               --   t[n] = ""
  53.               end -- v ~= nil
  54.               -- parg.reg[n].cb(t[n])
  55.             else -- parg.reg[n].type ~= "value"
  56.               if t[n] == nil then t[n] = 0 end
  57.               t[n] = t[n] + 1
  58.             end -- parg.reg[n].type == "value"
  59.             if parg.reg[n].same ~= nil then -- SAME
  60.               for ii, nn in ipairs(parg.reg[n].same) do
  61.                 t[nn] = t[n]
  62.               end
  63.             end -- SAME
  64.           else -- parg.reg[n] == nil
  65.             if t[n] == nil then t[n] = 0 end
  66.             t[n] = t[n] + 1
  67.           end -- parg.reg[n] ~= nil
  68.         end -- eq ~= nil
  69.       else -- if a[i]:sub(2, 2) ~= "-"
  70.         for j=2, #(a[i]) do
  71.           local b = a[i]:sub(j, j)
  72.           if (b == "=") and (j ~= #(a[i])) then
  73.             local n, v = a[i]:sub(j-1, j-1), a[i]:sub(j+1, #(a[i]))
  74.             if parg.reg[n] ~= nil then -- REG
  75.               if parg.reg[n].type == "value" then
  76.                 t[n] = v
  77.               end
  78.               if parg.reg[n].same ~= nil then -- SAME
  79.                 for ii, nn in ipairs(parg.reg[n].same) do
  80.                   t[nn] = t[n]
  81.                 end
  82.               end -- SAME
  83.               break -- for j=2, #(a[i])
  84.             else -- parg.reg[n] == nil
  85.               t[n] = v
  86.               break -- for j=2, #(a[i])
  87.             end -- parg.reg[n] ~= nil
  88.           else -- (b ~= "=") or (j == #(a[i]))
  89.             if parg.reg[b] ~= nil then
  90.               if (t[b] == nil) and parg.reg[b].type == "flag" then t[b] = 0 end
  91.             else
  92.               if t[b] == nil then t[b] = 0 end
  93.             end
  94.             if type(t[b]) == "number" then
  95.               t[b] = t[b] + 1
  96.             end
  97.           end -- (b == "=") and (j ~= #(a[i]))
  98.         end -- for j=2, #(a[i])
  99.         local n, v = a[i]:sub(#(a[i]), #(a[i])), a[i+1]
  100.         if parg.reg[n] ~= nil then -- REG
  101.           if (v ~= nil) and (parg.reg[n].type == "value") then
  102.             if v:sub(1, 1) ~= "-" then
  103.               t[n] = v
  104.                 i = i + 1
  105.             -- else -- TODO: Should I just leave it nil?
  106.             --   t[n] = ""
  107.             end -- v:sub(1, 1) ~= "-"
  108.           end -- (v ~= nil) and (parg.reg[n].type == "value")
  109.           if parg.reg[n].same ~= nil then -- SAME
  110.             for ii, nn in ipairs(parg.reg[n].same) do
  111.               t[nn] = t[n]
  112.             end
  113.           end -- SAME
  114.         end -- parg.reg[n] ~= nil
  115.       end -- if a[i]:sub(2, 2) == "-"
  116.     else -- a[i]:sub(1, 1) ~= "-" or (a[i] == "--")
  117.       table.insert(t, a[i])
  118.     end -- a[i]:sub(1, 1) == "-"
  119.     i = i + 1
  120.   end -- while i <= #a
  121.  
  122.   for n, r in pairs(parg.reg) do
  123.     if parg.reg[n] ~= nil then
  124.       if (r.type == "flag") and (t[n] == nil) then
  125.         if r.same ~= nil then
  126.           for i, v in ipairs(r.same) do
  127.             t[v] = 0
  128.           end
  129.         else -- r.same == nil
  130.           t[n] = 0
  131.         end -- r.same ~= nil
  132.       end -- (r.type == "flag") and (t[n] == nil)
  133.       if r.cb ~= nil then r.cb(t[n]) end
  134.       if r.same ~= nil then -- Clearing same, cb already done
  135.         for i, v in ipairs(r.same) do
  136.           parg.reg[v] = nil
  137.         end
  138.       end
  139.     end -- parg.reg ~= nil
  140.   end -- for n, r in pairs(parg.reg)
  141.   parg.reg = {} -- "Clearing" memory
  142.   return t
  143. end
  144.  
  145. -- Register an argument, or a list of arguments with same values (aliases)
  146. function parg.register(argument, argType, callback)
  147.   if type(argument) == "table" then
  148.     for i, v in ipairs(argument) do
  149.       parg.register(v, argType, callback)
  150.       parg.reg[v].same = argument
  151.     end
  152.   elseif type(argument) == "string" then
  153.     parg.reg[argument] = { type = argType, cb = callback, same = nil }
  154.   else
  155.     error("Expected string or table on 1, got "..type(argument))
  156.   end
  157. end
  158.  
  159. function parg.unregister(argument, clearSame)
  160.   if clearSame == nil then clearSame = false end
  161.   if type(clearSame) ~= "boolean" then error("Expected boolean on 2, got "..type(clearSame)) end
  162.   if type(argument) == "table" then
  163.     for i, v in ipairs(argument) do
  164.       parg.unregister(v, clearSame)
  165.     end
  166.   elseif type(argument) == "string" then
  167.     if parg.reg[v] ~= nil then
  168.       if parg.reg[argument].same ~= nil then
  169.         if clearSame then
  170.           for i, v in ipairs(parg.reg[argument].same) do
  171.             parg.reg[v] = nil
  172.           end
  173.         else -- not clearSame
  174.           for i, v in pairs(parg.reg) do
  175.             if v.same ~= nil then
  176.               for ii, vv in ipairs(v.same) do
  177.                 if vv == argument then table.remove(v.same, ii) end
  178.               end
  179.             end -- v.same ~= nil
  180.           end -- for i, v in pairs(parg.reg)
  181.           parg.reg[argument] = nil
  182.         end
  183.       else -- parg.reg[argument].same == nil
  184.         parg.reg[argument] = nil
  185.       end -- parg.reg[argument].same ~= nil
  186.     end -- parg.reg[v] ~= nil
  187.   else
  188.     error("Expected string or table on 1, got "..type(argument))
  189.   end
  190. end
  191.  
  192. setmetatable(parg, { __call = function (this, a) return parg.parse(a) end } )
  193.  
  194. return parg
RAW Paste Data