summaryrefslogtreecommitdiff
path: root/lib/clod.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/clod.lua')
-rw-r--r--lib/clod.lua52
1 files changed, 49 insertions, 3 deletions
diff --git a/lib/clod.lua b/lib/clod.lua
index b1e5ccd..7696d5e 100644
--- a/lib/clod.lua
+++ b/lib/clod.lua
@@ -84,6 +84,20 @@ local function delete_entry(entry)
end
end
+local function has_key(confmeta, key)
+ return confmeta.settings[key] ~= nil
+end
+
+local function calculate_wild_key(confmeta, prefix)
+ local keyno = 1
+ local keystr = ("%si_%s"):format(prefix, keyno)
+ while has_key(confmeta, keystr) do
+ keyno = keyno + 1
+ keystr = ("%si_%s"):format(prefix, keyno)
+ end
+ return keystr
+end
+
function settings_mt:__newindex(subkey, value)
local meta = metadata[self]
local confmeta = metadata[meta.conf]
@@ -94,6 +108,11 @@ function settings_mt:__newindex(subkey, value)
if meta.prefix then
key = meta.prefix .. "." .. subkey
end
+ local wild_prefix, last_key_element = key:match("^(.-)([^.]+)$")
+ if last_key_element == "*" then
+ -- Wild insert, so calculate a unique key to use
+ key = calculate_wild_key(confmeta, wild_prefix)
+ end
if value == nil then
-- removing an entry...
if confmeta.settings[key] then
@@ -178,6 +197,10 @@ function methods:serialise()
local function serialise_entry(entry)
local key, value, line = entry.key, entry.value, ""
if key then
+ local wild_prefix = key:match("^(.-)%.i_[0-9]+$")
+ if wild_prefix then
+ key = wild_prefix .. '["*"]'
+ end
local vtype = type(value)
assert((vtype == "string" or vtype == "number" or vtype == "boolean"),
"Unexpected " .. vtype .. " in key: " .. key)
@@ -201,6 +224,24 @@ function methods:serialise()
return tconcat(retstr, "\n")
end
+function methods:each(prefix)
+ if prefix then
+ prefix = "^" .. prefix:gsub("%.", "%%.")
+ end
+ local function iterator(confmeta, prev_key)
+ local next_key, next_value = next(confmeta.settings, prev_key)
+ if prefix then
+ while next_key and not next_key:match(prefix) do
+ next_key, next_value = next(confmeta.settings, next_key)
+ end
+ end
+ if next_key and next_value then
+ return next_key, next_value.value
+ end
+ end
+ return iterator, metadata[self], nil
+end
+
-- Metamethods for clod instances
function clod_mt:__index(key)
if key == "settings" then
@@ -236,14 +277,19 @@ local function parse_config(conf, confname)
if type(value) == "table" or type(value) == "function" then
error("Clod does not support " .. type(value) .. "s as values")
end
- return self[key](value)
+ return self[key](value, 1)
end
- function parse_mt:__call(value)
+ function parse_mt:__call(value, offset)
if type(value) == "table" or type(value) == "function" then
error("Clod does not support " .. type(value) .. "s as values")
end
local key = assert(keys[self])
- local curline = getinfo(2, "Snlf").currentline
+ local wild_prefix, last_key_element = key:match("^(.-)([^.]+)$")
+ if last_key_element == "*" then
+ -- Wild insert, so calculate a unique key to use
+ key = calculate_wild_key({settings=settings}, wild_prefix)
+ end
+ local curline = getinfo(2 + (offset or 0), "Snlf").currentline
local entry = { key = key, value = value, lineno = curline }
while last_entry.lineno < (curline - 1) do
local empty = {