summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2015-07-14 15:27:53 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2015-07-14 15:27:53 +0100
commitecf1af2d8a42ca698040594327d379b7ffe04560 (patch)
tree915c1c4cfdfa690187da720e2eec3174d4c905b2
parent1f3c05d453a39ee6b8962d59f804af27ff2fa571 (diff)
downloadclod-ecf1af2d8a42ca698040594327d379b7ffe04560.tar.gz
Add support for retrieving the location of a clod key/value pair
-rw-r--r--lib/clod.lua32
-rw-r--r--test/test-clod.lua25
2 files changed, 56 insertions, 1 deletions
diff --git a/lib/clod.lua b/lib/clod.lua
index 2416a80..ee6cd75 100644
--- a/lib/clod.lua
+++ b/lib/clod.lua
@@ -398,6 +398,36 @@ function methods:set_list(prefix, list)
end
---
+-- Get the location of a given setting
+--
+-- Find where a given key is defined in the clod source. Note that if
+-- you have added a new key, or removed an old key, since loading then
+-- you may not be able to retrieve data for those entries.
+--
+-- Also, note that this function will always return the original line number
+-- of an entry, which is not necessarily where the entry would be in a new
+-- serialisation if changes have been made.
+--
+-- @function locate
+-- @tparam string key The name of the key to locate
+-- @treturn number-or-false The line number that key is defined on, or nil.
+-- @treturn[opt] string The reason for the nil return
+function methods:locate(key)
+ local meta = metadata[self].settings
+ if meta[key] then
+ if meta[key].original_lineno then
+ return meta[key].original_lineno
+ end
+ return nil, "Key is new, rather than from the input"
+ end
+ for k in pairs(meta) do
+ if k:sub(1,#key) == key then
+ return nil, "Ambiguous key prefix"
+ end
+ end
+ return nil, "Not found"
+end
+---
-- The settings in this `clodfile` instance.
--
-- @field settings
@@ -462,7 +492,7 @@ local function parse_config(conf, confname, migrate_lists)
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 }
+ local entry = { key = key, value = value, lineno = curline, original_lineno = curline }
while last_entry.lineno < (curline - 1) do
local empty = {
lineno = last_entry.lineno + 1,
diff --git a/test/test-clod.lua b/test/test-clod.lua
index b720ff6..fe18bf6 100644
--- a/test/test-clod.lua
+++ b/test/test-clod.lua
@@ -347,6 +347,31 @@ tab["*"] "world"
assert(conf:serialise() == output_str)
end
+function suite.locate_inputs()
+ local input_str = [[
+foo "bar"
+baz "meta"
+qux "fish"
+]]
+ local conf = assert(clod.parse(input_str, "@str", true))
+ assert(conf:locate("foo") == 1)
+ assert(conf:locate("baz") == 2)
+ assert(conf:locate("qux") == 3)
+end
+
+function suite.locate_inputs_even_after_delete()
+ local input_str = [[
+foo "bar"
+baz "meta"
+qux "fish"
+]]
+ local conf = assert(clod.parse(input_str, "@str", true))
+ assert(conf:locate("foo") == 1)
+ conf.settings["baz"] = nil
+ assert(conf:locate("qux") == 3)
+end
+
+
local count_ok = 0
for _, testname in ipairs(testnames) do
-- print("Run: " .. testname)