module("luci.util", package.seeall)
--
+-- Pythonic string formatting extension
+--
+getmetatable("").__mod = function(a, b)
+ if not b then
+ return a
+ elseif type(b) == "table" then
+ return a:format(unpack(b))
+ else
+ return a:format(b)
+ end
+end
+
+
+--
-- Class helper routines
--
-- @param t Table value to dump
-- @param i Number of tabs to prepend to each line
-- @return Always nil
-function dumptable(t, i)
+function dumptable(t, i, seen)
i = i or 0
+ seen = seen or setmetatable({}, {__mode="k"})
+
for k,v in pairs(t) do
- print(string.rep("\t", i) .. tostring(k), tostring(v))
+ perror(string.rep("\t", i) .. tostring(k) .. "\t" .. tostring(v))
if type(v) == "table" then
- dumptable(v, i+1)
+ if not seen[v] then
+ seen[v] = true
+ dumptable(v, i+1, seen)
+ else
+ perror(string.rep("\t", i) .. "*** RECURSION ***")
+ end
end
end
end
-- @param value String containing the HTML text
-- @return String with HTML tags stripped of
function striptags(s)
- return (s:gsub("</?[A-Za-z][A-Za-z0-9:_%-]*[^>]*>", " "):gsub("%s+", " "))
+ return pcdata(s:gsub("</?[A-Za-z][A-Za-z0-9:_%-]*[^>]*>", " "):gsub("%s+", " "))
end
--- Splits given string on a defined separator sequence and return a table
-- Serialize the contents of a table value.
-function _serialize_table(t)
- local data = ""
+function _serialize_table(t, seen)
+ assert(not seen[t], "Recursion detected.")
+ seen[t] = true
+
+ local data = ""
+ local idata = ""
+ local ilen = 0
+
for k, v in pairs(t) do
- k = serialize_data(k)
- v = serialize_data(v)
- data = data .. ( #data > 0 and ", " or "" ) ..
- '[' .. k .. '] = ' .. v
+ if type(k) ~= "number" or k < 1 or math.floor(k) ~= k or ( k - #t ) > 3 then
+ k = serialize_data(k, seen)
+ v = serialize_data(v, seen)
+ data = data .. ( #data > 0 and ", " or "" ) ..
+ '[' .. k .. '] = ' .. v
+ elseif k > ilen then
+ ilen = k
+ end
end
- return data
+
+ for i = 1, ilen do
+ local v = serialize_data(t[i], seen)
+ idata = idata .. ( #idata > 0 and ", " or "" ) .. v
+ end
+
+ return idata .. ( #data > 0 and ", " or "" ) .. data
end
--- Recursively serialize given data to lua code, suitable for restoring
-- @return String value containing the serialized code
-- @see restore_data
-- @see get_bytecode
-function serialize_data(val)
+function serialize_data(val, seen)
+ seen = seen or setmetatable({}, {__mode="k"})
+
if val == nil then
return "nil"
elseif type(val) == "number" then
elseif type(val) == "function" then
return string.format("loadstring(%q)", get_bytecode(val))
elseif type(val) == "table" then
- return "{ " .. _serialize_table(val) .. " }"
+ return "{ " .. _serialize_table(val, seen) .. " }"
else
return '"[unhandled data type:' .. type(val) .. ']"'
end