summaryrefslogtreecommitdiffstats
path: root/acf
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-03-20 14:11:41 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-03-25 12:48:22 +0200
commit5d663a122ea39802c096a57ad3fb471dee347759 (patch)
treee065df62daadce671a7e83532426af28db2a39b1 /acf
parent84c91f33056d68216429e488ea1bc074b3f23d75 (diff)
downloadaconf-5d663a122ea39802c096a57ad3fb471dee347759.tar.bz2
aconf-5d663a122ea39802c096a57ad3fb471dee347759.tar.xz
allow escaped slashes in object path names
Diffstat (limited to 'acf')
-rw-r--r--acf/init.lua2
-rw-r--r--acf/loader.lua22
-rw-r--r--acf/model/init.lua4
-rw-r--r--acf/path.lua52
-rw-r--r--acf/persistence/backends/augeas.lua4
-rw-r--r--acf/persistence/backends/files.lua6
-rw-r--r--acf/persistence/backends/json.lua6
-rw-r--r--acf/persistence/init.lua7
-rw-r--r--acf/util.lua16
9 files changed, 75 insertions, 44 deletions
diff --git a/acf/init.lua b/acf/init.lua
index 8f89c08..b20d1a1 100644
--- a/acf/init.lua
+++ b/acf/init.lua
@@ -5,7 +5,7 @@ See LICENSE file for license details
module(..., package.seeall)
-require('acf.util').loadmods('modules')
+require('acf.loader').loadmods('modules')
require 'acf.model'
call = require('acf.error').call
diff --git a/acf/loader.lua b/acf/loader.lua
new file mode 100644
index 0000000..d66403a
--- /dev/null
+++ b/acf/loader.lua
@@ -0,0 +1,22 @@
+--[[
+Copyright (c) 2012-2013 Kaarle Ritvanen
+See LICENSE file for license details
+--]]
+
+module(..., package.seeall)
+
+local pth = require('acf.path')
+require 'lfs'
+require 'stringy'
+
+function loadmods(subdir)
+ local comps = pth.split('acf/'..subdir)
+ local res = {}
+ for modfile in lfs.dir(pth.mjoin(unpack(comps))) do
+ if stringy.endswith(modfile, '.lua') then
+ local name = string.sub(modfile, 1, -5)
+ res[name] = require(table.concat(comps, '.')..'.'..name)
+ end
+ end
+ return res
+end
diff --git a/acf/model/init.lua b/acf/model/init.lua
index 6b1fd64..bf4f7b4 100644
--- a/acf/model/init.lua
+++ b/acf/model/init.lua
@@ -136,7 +136,7 @@ function Reference:meta(context)
end
function Reference:follow(context, value)
- return context.txn:search(pth.join(self:abs_scope(context), value))
+ return context.txn:search(pth.mjoin(self:abs_scope(context), value))
end
function Reference:load(context)
@@ -163,7 +163,7 @@ function Reference:_validate(context, value)
end
-- assume one-level ref for now
- if string.find(value, '/') then
+ if #pth.split(value) > 1 then
raise(path, 'Subtree references not yet supported')
end
diff --git a/acf/path.lua b/acf/path.lua
index 15d3fca..f18d701 100644
--- a/acf/path.lua
+++ b/acf/path.lua
@@ -5,13 +5,7 @@ See LICENSE file for license details
module(..., package.seeall)
-require 'stringy'
-
-local function filter(func, tbl)
- local res = {}
- for _, v in ipairs(tbl) do if func(v) then table.insert(res, v) end end
- return res
-end
+local map = require('acf.util').map
function is_absolute(path)
@@ -35,24 +29,52 @@ function to_absolute(path, base)
return '/'..table.concat(comps, '/')
end
-function join(p1, p2, ...)
+
+local function escape(comp)
+ local res = string.gsub(comp, '([\\/])', '\\%1')
+ return res
+end
+
+
+function join(parent, name) return mjoin(parent, escape(name)) end
+
+function mjoin(p1, p2, ...)
if not p2 then return p1 end
if not is_absolute(p2) then p2 = '/'..p2 end
- return join((p1 == '/' and '' or p1)..p2, unpack(arg))
+ return mjoin((p1 == '/' and '' or p1)..p2, unpack(arg))
end
+
function split(path)
- -- assume absolute paths
- assert(is_absolute(path))
- if path == '/' then return {} end
- return filter(function(s) return s > '' end,
- stringy.split(string.sub(path, 2, -1), '/'))
+ local res = {}
+ local comp = ''
+
+ local function merge(s) if s > '' then table.insert(res, s) end end
+
+ while true do
+ local prefix, sep, suffix = string.match(path, '([^\\/]*)([\\/])(.*)')
+ if not prefix then
+ merge(comp..path)
+ return res
+ end
+
+ comp = comp..prefix
+ if sep == '\\' then
+ comp = comp..string.sub(suffix, 1, 1)
+ path = string.sub(suffix, 2, -1)
+ else
+ merge(comp)
+ comp = ''
+ path = suffix
+ end
+ end
end
+
function parent(path)
local comps = split(path)
table.remove(comps)
- return join('/', unpack(comps))
+ return mjoin('/', unpack(map(escape, comps)))
end
function name(path)
diff --git a/acf/persistence/backends/augeas.lua b/acf/persistence/backends/augeas.lua
index 34d7df8..cf4614f 100644
--- a/acf/persistence/backends/augeas.lua
+++ b/acf/persistence/backends/augeas.lua
@@ -1,5 +1,5 @@
--[[
-Copyright (c) 2012 Kaarle Ritvanen
+Copyright (c) 2012-2013 Kaarle Ritvanen
See LICENSE file for license details
--]]
@@ -13,7 +13,7 @@ backend = require('acf.object').class()
function backend:init() self.aug = require('augeas').init() end
function backend:get(path)
- path = '/'..pth.join(unpack(path))
+ path = '/'..pth.mjoin(unpack(path))
local _, count = self.aug:match(path)
if count == 0 then return end
diff --git a/acf/persistence/backends/files.lua b/acf/persistence/backends/files.lua
index 8e59ab9..bc9c111 100644
--- a/acf/persistence/backends/files.lua
+++ b/acf/persistence/backends/files.lua
@@ -1,5 +1,5 @@
--[[
-Copyright (c) 2012 Kaarle Ritvanen
+Copyright (c) 2012-2013 Kaarle Ritvanen
See LICENSE file for license details
--]]
@@ -17,7 +17,7 @@ backend = require('acf.object').class()
function backend:init() self.cache = {} end
function backend:get(path)
- local name = pth.join('/', unpack(path))
+ local name = pth.mjoin('/', unpack(path))
if not self.cache[name] then
local attrs = lfs.attributes(name)
@@ -46,7 +46,7 @@ end
function backend:set(mods)
for _, mod in pairs(mods) do
local path, t, value = unpack(mod)
- local name = pth.join('/', unpack(path))
+ local name = pth.mjoin('/', unpack(path))
-- TODO save references (t == 'reference') as symlinks
diff --git a/acf/persistence/backends/json.lua b/acf/persistence/backends/json.lua
index 7300ce9..6500d13 100644
--- a/acf/persistence/backends/json.lua
+++ b/acf/persistence/backends/json.lua
@@ -1,5 +1,5 @@
--[[
-Copyright (c) 2012 Kaarle Ritvanen
+Copyright (c) 2012-2013 Kaarle Ritvanen
See LICENSE file for license details
--]]
@@ -34,7 +34,7 @@ function backend:split_path(path)
local res
while #fpath > 0 do
- local fp = pth.join('/', unpack(fpath))
+ local fp = pth.mjoin('/', unpack(fpath))
if self.cache[fp] then return fp, jpath end
table.insert(jpath, 1, fpath[#fpath])
table.remove(fpath)
@@ -43,7 +43,7 @@ function backend:split_path(path)
fpath = '/'
while true do
- fpath = pth.join(fpath, jpath[1])
+ fpath = pth.mjoin(fpath, jpath[1])
table.remove(jpath, 1)
local attrs = lfs.attributes(fpath)
diff --git a/acf/persistence/init.lua b/acf/persistence/init.lua
index 2533560..479620b 100644
--- a/acf/persistence/init.lua
+++ b/acf/persistence/init.lua
@@ -5,6 +5,7 @@ See LICENSE file for license details
module(..., package.seeall)
+local loadmods = require('acf.loader').loadmods
local object = require('acf.object')
local super = object.super
local pth = require('acf.path')
@@ -15,8 +16,10 @@ DataStore = object.class(require('acf.transaction.backend').TransactionBackend)
function DataStore:init()
super(self, DataStore):init()
- self.backends = util.map(function(m) return m.backend() end,
- util.loadmods('persistence/backends'))
+ self.backends = util.map(
+ function(m) return m.backend() end,
+ loadmods('persistence/backends')
+ )
end
function DataStore:split_path(path)
diff --git a/acf/util.lua b/acf/util.lua
index 9ca287c..8dd54cc 100644
--- a/acf/util.lua
+++ b/acf/util.lua
@@ -28,19 +28,3 @@ function map(func, tbl)
for k, v in pairs(tbl) do res[k] = func(copy(v)) end
return res
end
-
-
-local pth = require('acf.path')
-require 'lfs'
-
-function loadmods(subdir)
- local comps = pth.split('/acf/'..subdir)
- local res = {}
- for modfile in lfs.dir(pth.join(unpack(comps))) do
- if stringy.endswith(modfile, '.lua') then
- local name = string.sub(modfile, 1, -5)
- res[name] = require(table.concat(comps, '.')..'.'..name)
- end
- end
- return res
-end