summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2012-08-25 10:58:53 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2012-08-25 10:58:53 +0100
commit05f5c01ba6b609f8b15574412fd874adda322590 (patch)
treed662fd13157a613e21111fae72e74c93c11e18a1
parenta278292101608a2fc1c2ebb3a46f883b2ffc7076 (diff)
downloadclod-05f5c01ba6b609f8b15574412fd874adda322590.tar.gz
CLOD: Simple list methods with simple algorithm for replacement strategy
-rw-r--r--lib/clod.lua42
-rw-r--r--test/test-clod.lua59
2 files changed, 101 insertions, 0 deletions
diff --git a/lib/clod.lua b/lib/clod.lua
index 7696d5e..4114fd6 100644
--- a/lib/clod.lua
+++ b/lib/clod.lua
@@ -177,6 +177,16 @@ function settings_mt:__newindex(subkey, value)
if last.key then
insert_blank = true
end
+ else
+ -- Starting at longest_prefix_found_at, iterate
+ -- until it no longer matches the prefix
+ local entry = longest_prefix_found_at
+ while entry.next and (entry.next.key and
+ (entry.next.key:sub(1, longest_prefix) ==
+ longest_prefix_found_at.key:sub(1, longest_prefix))) do
+ entry = entry.next
+ end
+ longest_prefix_found_at = entry
end
local before = longest_prefix_found_at
if insert_blank then
@@ -242,6 +252,38 @@ function methods:each(prefix)
return iterator, metadata[self], nil
end
+function methods:get_list(prefix)
+ local ret = {}
+ local map = {}
+ for k, v in self:each(prefix) do
+ ret[#ret+1] = k
+ map[k] = v
+ end
+ table.sort(ret)
+ for i = 1, #ret do
+ ret[i] = map[ret[i]]
+ end
+ return ret
+end
+
+function methods:set_list(prefix, list)
+ -- This algorithm isn't perfect, but it'll do in the face of
+ -- lazy apps devs who don't look after keys/value pairs themselves
+ local old_list = self:get_list(prefix)
+ -- Step one is to update all extant entries
+ for i = 1, #list do
+ local key = ("%s.i_%d"):format(prefix, i)
+ self.settings[key] = list[i]
+ end
+ -- If the new list is shorter, delete trailing entries
+ if #list < #old_list then
+ for i = #list + 1, #old_list do
+ local key = ("%s.i_%d"):format(prefix, i)
+ self.settings[key] = nil
+ end
+ end
+end
+
-- Metamethods for clod instances
function clod_mt:__index(key)
if key == "settings" then
diff --git a/test/test-clod.lua b/test/test-clod.lua
index f8baa77..7fc05cd 100644
--- a/test/test-clod.lua
+++ b/test/test-clod.lua
@@ -256,6 +256,65 @@ owner.name "Daniel"
assert(not had_owner)
end
+function suite.get_list()
+ local input_str = [[
+foo["*"] "Hello"
+foo["*"] "World"
+]]
+ local conf = clod.parse(input_str)
+ local list = conf:get_list('foo')
+ assert(#list == 2)
+ assert(list[1] == "Hello")
+ assert(list[2] == "World")
+end
+
+function suite.set_list_same_length()
+ local input_str = [[
+foo["*"] "Hello"
+foo["*"] "World"
+]]
+ local conf = clod.parse(input_str)
+ local list = { "Yeesh", "Gawd" }
+ conf:set_list("foo", list)
+ local output_str = [[
+foo["*"] "Yeesh"
+foo["*"] "Gawd"
+]]
+ assert(conf:serialise() == output_str)
+end
+
+function suite.set_list_longer_length()
+ local input_str = [[
+foo["*"] "Hello"
+foo["*"] "World"
+]]
+ local conf = clod.parse(input_str)
+ local list = { "Yeesh", "Gawd", "Cripes" }
+ conf:set_list("foo", list)
+ local output_str = [[
+foo["*"] "Yeesh"
+foo["*"] "Gawd"
+foo["*"] "Cripes"
+]]
+ assert(conf:serialise() == output_str)
+end
+
+function suite.set_list_shorter_length()
+ local input_str = [[
+foo["*"] "Hello"
+foo["*"] "World"
+foo["*"] "Badger"
+]]
+ local conf = clod.parse(input_str)
+ local list = { "Yeesh", "Gawd" }
+ conf:set_list("foo", list)
+ local output_str = [[
+foo["*"] "Yeesh"
+foo["*"] "Gawd"
+]]
+ assert(conf:serialise() == output_str)
+end
+
local count_ok = 0
for _, testname in ipairs(testnames) do
-- print("Run: " .. testname)