diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/clod.lua | 52 |
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 = { |