diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-02-24 14:29:29 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-02-24 14:29:29 +0000 |
commit | 0ed33d48078e69cff0c01dd99a84f77d9a123a5b (patch) | |
tree | f1e66774e6b46488eefb5c292f5f6a152ef191ae /lualib/lua_util.lua | |
parent | 67f8d8fccd3403450f6652fdd67a4db37112a592 (diff) | |
download | rspamd-0ed33d48078e69cff0c01dd99a84f77d9a123a5b.tar.gz rspamd-0ed33d48078e69cff0c01dd99a84f77d9a123a5b.zip |
[Minor] Add table compare utility
Diffstat (limited to 'lualib/lua_util.lua')
-rw-r--r-- | lualib/lua_util.lua | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lualib/lua_util.lua b/lualib/lua_util.lua index fb9fab0a4..a7509665a 100644 --- a/lualib/lua_util.lua +++ b/lualib/lua_util.lua @@ -321,4 +321,54 @@ end exports.parse_time_interval = parse_time_interval +--[[[ +-- @function lua_util.table_cmp(t1, t2) +-- Compare two tables deeply +--]] +local function table_cmp(table1, table2) + local avoid_loops = {} + local function recurse(t1, t2) + if type(t1) ~= type(t2) then return false end + if type(t1) ~= "table" then return t1 == t2 end + + if avoid_loops[t1] then return avoid_loops[t1] == t2 end + avoid_loops[t1] = t2 + -- Copy keys from t2 + local t2keys = {} + local t2tablekeys = {} + for k, _ in pairs(t2) do + if type(k) == "table" then table.insert(t2tablekeys, k) end + t2keys[k] = true + end + -- Let's iterate keys from t1 + for k1, v1 in pairs(t1) do + local v2 = t2[k1] + if type(k1) == "table" then + -- if key is a table, we need to find an equivalent one. + local ok = false + for i, tk in ipairs(t2tablekeys) do + if table_cmp(k1, tk) and recurse(v1, t2[tk]) then + table.remove(t2tablekeys, i) + t2keys[tk] = nil + ok = true + break + end + end + if not ok then return false end + else + -- t1 has a key which t2 doesn't have, fail. + if v2 == nil then return false end + t2keys[k1] = nil + if not recurse(v1, v2) then return false end + end + end + -- if t2 has a key which t1 doesn't have, fail. + if next(t2keys) then return false end + return true + end + return recurse(table1, table2) +end + +exports.table_cmp = table_cmp + return exports |