aboutsummaryrefslogtreecommitdiffstats
path: root/util/multitable.lua
diff options
context:
space:
mode:
Diffstat (limited to 'util/multitable.lua')
-rw-r--r--util/multitable.lua43
1 files changed, 38 insertions, 5 deletions
diff --git a/util/multitable.lua b/util/multitable.lua
index 66b9bd8a..caf25118 100644
--- a/util/multitable.lua
+++ b/util/multitable.lua
@@ -1,17 +1,14 @@
-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
---
+--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
-
-
local select = select;
local t_insert = table.insert;
-local pairs = pairs;
-local next = next;
+local unpack, pairs, next, type = unpack, pairs, next, type;
module "multitable"
@@ -129,6 +126,41 @@ local function search_add(self, results, ...)
return results;
end
+function iter(self, ...)
+ local query = { ... };
+ local maxdepth = select("#", ...);
+ local stack = { self.data };
+ local keys = { };
+ local function it(self)
+ local depth = #stack;
+ local key = next(stack[depth], keys[depth]);
+ if key == nil then -- Go up the stack
+ stack[depth], keys[depth] = nil, nil;
+ if depth > 1 then
+ return it(self);
+ end
+ return; -- The end
+ else
+ keys[depth] = key;
+ end
+ local value = stack[depth][key];
+ if query[depth] == nil or key == query[depth] then
+ if depth == maxdepth then -- Result
+ local result = {}; -- Collect keys forming path to result
+ for i = 1, depth do
+ result[i] = keys[i];
+ end
+ result[depth+1] = value;
+ return unpack(result, 1, depth+1);
+ elseif type(value) == "table" then
+ t_insert(stack, value); -- Descend
+ end
+ end
+ return it(self);
+ end;
+ return it, self;
+end
+
function new()
return {
data = {};
@@ -138,6 +170,7 @@ function new()
remove = remove;
search = search;
search_add = search_add;
+ iter = iter;
};
end