diff options
-rw-r--r-- | aconf/model/init.lua | 1 | ||||
-rw-r--r-- | aconf/model/net.lua | 4 | ||||
-rw-r--r-- | aconf/model/node.lua | 19 | ||||
-rw-r--r-- | aconf/model/root.lua | 5 | ||||
-rw-r--r-- | aconf/model/service.lua | 10 | ||||
-rw-r--r-- | aconf/modules/dnsmasq.lua | 4 | ||||
-rw-r--r-- | aconf/modules/network.lua | 6 | ||||
-rw-r--r-- | aconf/path.lua | 121 | ||||
-rw-r--r-- | aconf/path/address/init.lua | 33 | ||||
-rw-r--r-- | aconf/path/address/special.lua | 35 | ||||
-rw-r--r-- | aconf/path/base.lua | 159 | ||||
-rw-r--r-- | aconf/path/init.lua | 6 | ||||
-rw-r--r-- | aconf/persistence/backends/augeas.lua | 12 | ||||
-rw-r--r-- | aconf/persistence/backends/files.lua | 5 | ||||
-rw-r--r-- | aconf/persistence/backends/json.lua | 6 | ||||
-rw-r--r-- | aconf/persistence/defer.lua | 4 | ||||
-rw-r--r-- | aconf/persistence/init.lua | 6 | ||||
-rw-r--r-- | aconf/transaction/base.lua | 22 |
18 files changed, 170 insertions, 288 deletions
diff --git a/aconf/model/init.lua b/aconf/model/init.lua index 69d26bc..437cb93 100644 --- a/aconf/model/init.lua +++ b/aconf/model/init.lua @@ -58,7 +58,6 @@ local isinstance = M.object.isinstance local super = M.object.super M.path = require('aconf.path') -M.addr = require('aconf.path.address') local store = require('aconf.persistence') local def_store = require('aconf.persistence.defer') diff --git a/aconf/model/net.lua b/aconf/model/net.lua index 268e60e..6de00f0 100644 --- a/aconf/model/net.lua +++ b/aconf/model/net.lua @@ -15,7 +15,7 @@ local object = require('aconf.object') local class = object.class local super = object.super -local address = require('aconf.path.address') +local pth = require('aconf.path') local update = require('aconf.util').update @@ -26,7 +26,7 @@ local BaseIPAddress = class(String) function BaseIPAddress:abs_mask_addr(context) if self.mask_addr then - return address.join(address.parent(context.addr), self.mask_addr) + return pth.join(pth.parent(context.addr), self.mask_addr) end end diff --git a/aconf/model/node.lua b/aconf/model/node.lua index f15b97e..4f09c99 100644 --- a/aconf/model/node.lua +++ b/aconf/model/node.lua @@ -13,7 +13,6 @@ local isinstance = object.isinstance local super = object.super local pth = require('aconf.path') -local address = require('aconf.path.address') local util = require('aconf.util') local copy = util.copy @@ -24,7 +23,7 @@ local update = util.update function M.null_addr(path, name) local comps = pth.split(path) table.insert(comps, pth.escape(name)) - return address.join('/null', table.unpack(comps)) + return pth.join('/null', table.unpack(comps)) end @@ -33,13 +32,13 @@ M.BoundMember = class() function M.BoundMember:init(parent, name, field) local pmt = getmetatable(parent) - if pmt.maddr and name ~= address.wildcard then self.addr = pmt.maddr(name) + if pmt.maddr and name ~= pth.wildcard then self.addr = pmt.maddr(name) else - self.addr = field.addr or address.escape(name) + self.addr = field.addr or pth.escape(name) if type(self.addr) == 'function' then self.addr = self.addr(pmt.path, name) end - self.addr = address.to_absolute(self.addr, pmt.addr) + self.addr = pth.to_absolute(self.addr, pmt.addr) end local context = { @@ -374,12 +373,12 @@ function M.List:init(context, params) local addrs = expand() if not addrs[1] then - addrs[1] = address.join( + addrs[1] = pth.join( '/', table.unpack( util.map( - function(c) return c == address.wildcard and 1 or c end, - address.split(mt.field.addr) + function(c) return c == pth.wildcard and 1 or c end, + pth.split(mt.field.addr) ) ) ) @@ -387,9 +386,9 @@ function M.List:init(context, params) if addrs[i] then return addrs[i] end - local comps = address.split(addrs[#addrs]) + local comps = pth.split(addrs[#addrs]) comps[#comps] = comps[#comps] + i - #addrs - return address.join('/', table.unpack(comps)) + return pth.join('/', table.unpack(comps)) end function mt.members() return util.keys(expand()) end diff --git a/aconf/model/root.lua b/aconf/model/root.lua index 949005e..3f95b0e 100644 --- a/aconf/model/root.lua +++ b/aconf/model/root.lua @@ -9,7 +9,6 @@ local model = require('aconf.model.model') local node = require('aconf.model.node') local object = require('aconf.object') local pth = require('aconf.path') -local address = require('aconf.path.address') local util = require('aconf.util') local setdefault = util.setdefault @@ -42,10 +41,10 @@ M.topology = setmetatable( util.setdefaults(self, {members={}, paths={}, referrers={}}) if type(addr) == 'table' then addr = util.copy(addr) - else addr = address.split(addr) end + else addr = pth.split(addr) end if not addr[1] then return self end - local comp = address.escape(addr[1]) + local comp = pth.escape(addr[1]) local top if create then top = setdefault(self.members, comp, {order=order}) diff --git a/aconf/model/service.lua b/aconf/model/service.lua index a7c02b0..2d129fa 100644 --- a/aconf/model/service.lua +++ b/aconf/model/service.lua @@ -6,18 +6,16 @@ See LICENSE file for license details local fld = require('aconf.model.field') local new = require('aconf.model.model').new local super = require('aconf.object').super -local address = require('aconf.path.address') +local pth = require('aconf.path') local store = require('aconf.persistence') return function(name) local res = new() - local addr = address.join('/service', name) - local eaddr = address.join(addr, 'enabled') + local addr = pth.join('/service', name) + local eaddr = pth.join(addr, 'enabled') res.enabled = fld.Boolean{addr=eaddr, required=true} - res.status = fld.String{ - addr=address.join(addr, 'status'), editable=false - } + res.status = fld.String{addr=pth.join(addr, 'status'), editable=false} local function is_enabled() return store:get(eaddr) end local enabled diff --git a/aconf/modules/dnsmasq.lua b/aconf/modules/dnsmasq.lua index 770a1d1..413a270 100644 --- a/aconf/modules/dnsmasq.lua +++ b/aconf/modules/dnsmasq.lua @@ -34,7 +34,7 @@ Filter.redirect_address = M.net.IPAddress{ Filter.address = M.Model{model=Address, visible=false} Filter.whitelist = M.Set{ type=M.net.DomainName, - addr='server/\\#/domain', + addr='server/#/domain', ui_name='Domain whitelist', widget='inline' } @@ -43,7 +43,7 @@ local Dnsmasq = M.new() Dnsmasq.filter = M.Model{ model=Filter, addr='/augeas'..filter_conf, - be_mode={server='value', ['server/\\#/domain']='enumerate'} + be_mode={server='value', ['server/#/domain']='enumerate'} } Dnsmasq.conf_file = M.Set{ type=M.String, diff --git a/aconf/modules/network.lua b/aconf/modules/network.lua index 51d7589..e29f0b4 100644 --- a/aconf/modules/network.lua +++ b/aconf/modules/network.lua @@ -121,7 +121,7 @@ Interface.class = M.String{ local name = M.node.name(iface) if name == 'lo' then return 'loopback' end - local saddr = M.addr.rawjoin('/files', iface_sys_dir, name, '.') + local saddr = M.path.rawjoin('/files', iface_sys_dir, name, '.') if not txn:get(saddr) then return 'logical' end for _, addr in ipairs{ @@ -129,7 +129,7 @@ Interface.class = M.String{ {saddr, 'bridge'}, {'/files/proc/net/vlan', name} } do - if txn:get(M.addr.join(table.unpack(addr))) then + if txn:get(M.path.join(table.unpack(addr))) then return 'logical' end end @@ -235,7 +235,7 @@ Interface.stats = M.Collection{ type=M.Number{editable=false}, editable=false, addr=function(path) - return M.addr.join( + return M.path.join( '/files/sys/class/net', M.path.name(path), 'statistics' ) end, diff --git a/aconf/path.lua b/aconf/path.lua new file mode 100644 index 0000000..4e289f5 --- /dev/null +++ b/aconf/path.lua @@ -0,0 +1,121 @@ +--[[ +Copyright (c) 2012-2015 Kaarle Ritvanen +See LICENSE file for license details +--]] + +local M = {} + +local map = require('aconf.util').map + +M.up = {symbol='..'} +M.wildcard = {symbol='*'} +local special = {['..']=M.up, ['*']=M.wildcard} + + +function M.is_absolute(path) return path:sub(1, 1) == '/' end + + +function M.escape(comp) + if type(comp) == 'table' then + assert(comp.symbol) + return comp.symbol + end + if type(comp) == 'number' then return tostring(comp) end + local res = comp:gsub('([\\/])', '\\%1') + return (special[res] or tonumber(res)) and '\\'..res or res +end + + +function M.rawjoin(p1, p2, ...) + if not p2 then return p1 end + if not M.is_absolute(p2) then p2 = '/'..p2 end + return M.rawjoin((p1 == '/' and '' or p1)..p2, ...) +end + +function M.join(parent, ...) + local args = map(function(c) return M.escape(c) end, {...}) + if parent > '' then table.insert(args, 1, parent) end + return M.rawjoin(table.unpack(args)) +end + + +function M.split(path) + local res = {} + local comp = '' + local escaped + + local function merge(s) + if s > '' then + table.insert(res, not escaped and (special[s] or tonumber(s)) or s) + end + end + + while true do + local prefix, sep, suffix = path:match('([^\\/]*)([\\/])(.*)') + if not prefix then + merge(comp..path) + return res + end + + comp = comp..prefix + if sep == '\\' then + comp = comp..suffix:sub(1, 1) + escaped = true + path = suffix:sub(2, -1) + else + merge(comp) + comp = '' + escaped = false + path = suffix + end + end +end + + +function M.is_unique(path) + for _, comp in ipairs(M.split(path)) do + if comp == M.wildcard then return false end + end + return true +end + +function M.is_subordinate(p1, p2) + p1 = M.split(p1) + for i, comp in ipairs(M.split(p2)) do + if p1[i] ~= comp then return false end + end + return true +end + + +function M.to_absolute(path, base) + if not M.is_absolute(path) then + path = base..(base ~= '/' and '/' or '')..path + end + local comps = M.split(path) + local i = 1 + while i <= #comps do + if comps[i] == M.up then + if i == 1 then error('Invalid path: '..path) end + table.remove(comps, i - 1) + table.remove(comps, i - 1) + i = i - 1 + else i = i + 1 end + end + return M.join('/', table.unpack(comps)) +end + + +function M.parent(path) + local comps = M.split(path) + table.remove(comps) + return M.join('/', table.unpack(comps)) +end + +function M.name(path) + local comps = M.split(path) + return comps[#comps] +end + + +return M diff --git a/aconf/path/address/init.lua b/aconf/path/address/init.lua deleted file mode 100644 index c62487f..0000000 --- a/aconf/path/address/init.lua +++ /dev/null @@ -1,33 +0,0 @@ ---[[ -Copyright (c) 2012-2015 Kaarle Ritvanen -See LICENSE file for license details ---]] - -local object = require('aconf.object') -local class = object.class - -local special = require('aconf.path.address.special') -local base = require('aconf.path.base') - - -local M = { - special={ - enum_keys=special.EnumKeys(), - value=special.Value(), - value_equals=special.ValueEquals - } -} - -local _special = {['#']=M.special.enum_keys, ['&']=M.special.value} - - -local AddressSyntax = class(base.Syntax) - -function AddressSyntax:get_special(comp) - if comp:sub(1, 1) == '@' then - return special.ValueEquals(#comp > 1 and comp:sub(2, -1) or nil) - end - return _special[comp] or object.super(self, AddressSyntax):get_special(comp) -end - -return AddressSyntax():export(M) diff --git a/aconf/path/address/special.lua b/aconf/path/address/special.lua deleted file mode 100644 index ab94fce..0000000 --- a/aconf/path/address/special.lua +++ /dev/null @@ -1,35 +0,0 @@ ---[[ -Copyright (c) 2012-2015 Kaarle Ritvanen -See LICENSE file for license details ---]] - -local M = {} - - -local object = require('aconf.object') -local class = object.class - - -M.SpecialMode = class(require('aconf.path.base').Special) - -M.Value = class(M.SpecialMode) -M.Value.symbol = '&' - -M.Selector = class(M.SpecialMode) - -M.EnumKeys = class(M.Selector) -M.EnumKeys.symbol = '#' - - -M.ValueEquals = class(M.Selector) - -M.ValueEquals.symbol = '@' - -function M.ValueEquals:init(key) self.key = key end - -function M.ValueEquals:tostring() - return object.super(self, M.ValueEquals):tostring()..(self.key or '') -end - - -return M diff --git a/aconf/path/base.lua b/aconf/path/base.lua deleted file mode 100644 index 4e2bf8f..0000000 --- a/aconf/path/base.lua +++ /dev/null @@ -1,159 +0,0 @@ ---[[ -Copyright (c) 2012-2015 Kaarle Ritvanen -See LICENSE file for license details ---]] - -local M = {} - - -local object = require('aconf.object') -local class = object.class - -local map = require('aconf.util').map - - -M.Special = class() -function M.Special:tostring() return self.symbol end - -local Up = class(M.Special) -Up.symbol = '..' - -local Wildcard = class(M.Special) -Wildcard.symbol = '*' - - - -M.Syntax = class() - -M.Syntax.up = Up() -M.Syntax.wildcard = Wildcard() - - -function M.Syntax:get_special(comp) - return ({['..']=M.Syntax.up, ['*']=M.Syntax.wildcard})[comp] -end - - -function M.Syntax:is_absolute(path) return path:sub(1, 1) == '/' end - - -function M.Syntax:escape(comp) - if type(comp) == 'table' then - if object.isinstance(object.toinstance(comp), M.Special) then - return comp:tostring() - end - end - if type(comp) == 'number' then return tostring(comp) end - local res = comp:gsub('([\\/])', '\\%1') - return (self:get_special(res) or tonumber(res)) and '\\'..res or res -end - - -function M.Syntax:rawjoin(p1, p2, ...) - if not p2 then return p1 end - if not self:is_absolute(p2) then p2 = '/'..p2 end - return self:rawjoin((p1 == '/' and '' or p1)..p2, ...) -end - -function M.Syntax:join(parent, ...) - local args = map(function(c) return self:escape(c) end, {...}) - if parent > '' then table.insert(args, 1, parent) end - return self:rawjoin(table.unpack(args)) -end - - -function M.Syntax:split(path) - local res = {} - local comp = '' - local escaped - - local function merge(s) - if s > '' then - table.insert( - res, not escaped and (self:get_special(s) or tonumber(s)) or s - ) - end - end - - while true do - local prefix, sep, suffix = path:match('([^\\/]*)([\\/])(.*)') - if not prefix then - merge(comp..path) - return res - end - - comp = comp..prefix - if sep == '\\' then - comp = comp..suffix:sub(1, 1) - escaped = true - path = suffix:sub(2, -1) - else - merge(comp) - comp = '' - escaped = false - path = suffix - end - end -end - - -function M.Syntax:is_unique(path) - for _, comp in ipairs(self:split(path)) do - if comp == self.wildcard then return false end - end - return true -end - -function M.Syntax:is_subordinate(p1, p2) - p1 = self:split(p1) - for i, comp in ipairs(self:split(p2)) do - if p1[i] ~= comp then return false end - end - return true -end - - -function M.Syntax:to_absolute(path, base) - if not self:is_absolute(path) then - path = base..(base ~= '/' and '/' or '')..path - end - local comps = self:split(path) - local i = 1 - while i <= #comps do - if comps[i] == self.up then - if i == 1 then error('Invalid path: '..path) end - table.remove(comps, i - 1) - table.remove(comps, i - 1) - i = i - 1 - else i = i + 1 end - end - return self:join('/', table.unpack(comps)) -end - - -function M.Syntax:parent(path) - local comps = self:split(path) - table.remove(comps) - return self:join('/', table.unpack(comps)) -end - -function M.Syntax:name(path) - local comps = self:split(path) - return comps[#comps] -end - - -function M.Syntax:export(mod) - if not mod then mod = {} end - for k, v in pairs(M.Syntax) do - if k ~= 'export' then - mod[k] = type(v) == 'function' and function(...) - return v(self, ...) - end or v - end - end - return mod -end - - -return M diff --git a/aconf/path/init.lua b/aconf/path/init.lua deleted file mode 100644 index 5ac9642..0000000 --- a/aconf/path/init.lua +++ /dev/null @@ -1,6 +0,0 @@ ---[[ -Copyright (c) 2012-2015 Kaarle Ritvanen -See LICENSE file for license details ---]] - -return require('aconf.path.base').Syntax():export() diff --git a/aconf/persistence/backends/augeas.lua b/aconf/persistence/backends/augeas.lua index 46d3ea9..7ce68f0 100644 --- a/aconf/persistence/backends/augeas.lua +++ b/aconf/persistence/backends/augeas.lua @@ -5,7 +5,7 @@ See LICENSE file for license details local topology = require('aconf.model.root').topology local class = require('aconf.object').class -local address = require('aconf.path.address') +local pth = require('aconf.path') local tostr = require('aconf.persistence.util').tostring local util = require('aconf.util') @@ -92,7 +92,7 @@ local function conv_path(path) keys = {} end - top = top and top(address.escape(comp)) + top = top and top(pth.escape(comp)) mode = top and top.mode table.remove(path, 1) @@ -194,7 +194,7 @@ function backend:set(mods) local ppath, pmode = conv_path(parent) if is_selector(pmode) then - gc[address.join('/', table.unpack(parent))] = false + gc[pth.join('/', table.unpack(parent))] = false if pmode == 'enumerate' then local count = #self.aug:match(ppath) @@ -259,11 +259,11 @@ function backend:set(mods) self.aug:set(apath, value ~= nil and tostr(value) or nil) end - util.setdefault(gc, address.join('/', table.unpack(path)), true) + util.setdefault(gc, pth.join('/', table.unpack(path)), true) end for path, _ in pairs(gc) do - local p = address.split(path) + local p = pth.split(path) while #p > 0 do local value = self:get(p) @@ -275,7 +275,7 @@ function backend:set(mods) break end - if gc[address.join('/', table.unpack(p))] ~= false then + if gc[pth.join('/', table.unpack(p))] ~= false then self.aug:rm(conv_path(p)) end p[#p] = nil diff --git a/aconf/persistence/backends/files.lua b/aconf/persistence/backends/files.lua index c619754..bfb3d49 100644 --- a/aconf/persistence/backends/files.lua +++ b/aconf/persistence/backends/files.lua @@ -5,7 +5,6 @@ See LICENSE file for license details local topology = require('aconf.model.root').topology local pth = require('aconf.path') -local address = require('aconf.path.address') local util = require('aconf.persistence.util') local posix = require('posix') @@ -29,7 +28,7 @@ local backend = require('aconf.object').class() function backend:init() self.cache = {} end function backend:get(path, top) - local name = address.join('/', table.unpack(path)) + local name = pth.join('/', table.unpack(path)) if not self.cache[name] then local t = posix.stat(name, 'type') @@ -69,7 +68,7 @@ end function backend:set(mods) for _, mod in pairs(mods) do local path, value = table.unpack(mod) - local name = address.join('/', table.unpack(path)) + local name = pth.join('/', table.unpack(path)) if value == nil then print('DEL', name) diff --git a/aconf/persistence/backends/json.lua b/aconf/persistence/backends/json.lua index 5a13955..66cb667 100644 --- a/aconf/persistence/backends/json.lua +++ b/aconf/persistence/backends/json.lua @@ -3,7 +3,7 @@ Copyright (c) 2012-2015 Kaarle Ritvanen See LICENSE file for license details --]] -local address = require('aconf.path.address') +local pth = require('aconf.path') local Cache = require('aconf.persistence.backends.volatile') local util = require('aconf.persistence.util') local copy = require('aconf.util').copy @@ -26,7 +26,7 @@ function backend:split_path(path) local res while #fpath > 0 do - local fp = address.join('/', table.unpack(fpath)) + local fp = pth.join('/', table.unpack(fpath)) if self.cache[fp] then return fp, jpath end table.insert(jpath, 1, fpath[#fpath]) table.remove(fpath) @@ -35,7 +35,7 @@ function backend:split_path(path) fpath = '/' while true do - fpath = address.join(fpath, jpath[1]) + fpath = pth.join(fpath, jpath[1]) table.remove(jpath, 1) local t = posix.stat(fpath, 'type') diff --git a/aconf/persistence/defer.lua b/aconf/persistence/defer.lua index d7f33d8..fa10805 100644 --- a/aconf/persistence/defer.lua +++ b/aconf/persistence/defer.lua @@ -6,7 +6,7 @@ See LICENSE file for license details local object = require('aconf.object') local super = object.super -local address = require('aconf.path.address') +local pth = require('aconf.path') local DeferringCommitter = object.class( @@ -31,7 +31,7 @@ function DeferringCommitter:_set_multiple(mods) local path, value = table.unpack(mod) while path > '/' do if self.defer_paths[path] then return end - path = address.parent(path) + path = pth.parent(path) end end diff --git a/aconf/persistence/init.lua b/aconf/persistence/init.lua index 632c191..481e859 100644 --- a/aconf/persistence/init.lua +++ b/aconf/persistence/init.lua @@ -6,7 +6,7 @@ See LICENSE file for license details local loadmods = require('aconf.loader') local topology = require('aconf.model.root').topology local object = require('aconf.object') -local address = require('aconf.path.address') +local pth = require('aconf.path') local util = require('aconf.util') local contains = util.contains @@ -38,7 +38,7 @@ function DataStore:trigger(phase, path, func) end function DataStore:split_path(path) - local comps = address.split(path) + local comps = pth.split(path) local backend = self.backends[comps[1]] assert(backend) table.remove(comps, 1) @@ -105,7 +105,7 @@ function DataStore:_set_multiple(mods) local tp = path while not trigger[tp] do trigger[tp] = true - tp = address.parent(tp) + tp = pth.parent(tp) end local backend, comps = self:split_path(path) diff --git a/aconf/transaction/base.lua b/aconf/transaction/base.lua index cda7ed6..6522d81 100644 --- a/aconf/transaction/base.lua +++ b/aconf/transaction/base.lua @@ -10,7 +10,7 @@ local err = require('aconf.error') local object = require('aconf.object') local class = object.class -local address = require('aconf.path.address') +local pth = require('aconf.path') local util = require('aconf.util') -- TODO each transaction backend (i.e. persistence manager or @@ -116,21 +116,21 @@ end function M.Transaction:expand(path) local prefix = {} - path = address.split(path) + path = pth.split(path) while path[1] do local comp = path[1] table.remove(path, 1) - if comp == address.wildcard then - local p = address.join('/', table.unpack(prefix)) + if comp == pth.wildcard then + local p = pth.join('/', table.unpack(prefix)) local res = {} local children = self:get(p) or {} table.sort(children) for _, child in ipairs(children) do util.extend( - res, self:expand(address.join(p, child, table.unpack(path))) + res, self:expand(pth.join(p, child, table.unpack(path))) ) end @@ -140,7 +140,7 @@ function M.Transaction:expand(path) table.insert(prefix, comp) end - return {address.join('/', table.unpack(prefix))} + return {pth.join('/', table.unpack(prefix))} end function M.Transaction:_set_multiple(mods) @@ -157,14 +157,14 @@ function M.Transaction:_set_multiple(mods) for _, mod in ipairs(mods) do local path, value = table.unpack(mod) - local ppath = address.parent(path) + local ppath = pth.parent(path) local parent = self:get(ppath) if parent == nil then parent = {} self:set(ppath, parent) end - local name = address.name(path) + local name = pth.name(path) local old = self:get(path) local is_table = type(value) == 'table' @@ -175,7 +175,7 @@ function M.Transaction:_set_multiple(mods) if type(old) == 'table' then if delete then for _, child in ipairs(old) do - self:set(address.join(path, child)) + self:set(pth.join(path, child)) end elseif is_table then return elseif #old > 0 then @@ -215,7 +215,7 @@ function M.Transaction:commit() local function insert_add(path) if not handled[path] then - local pp = address.parent(path) + local pp = pth.parent(path) if self.added[pp] then insert_add(pp) end insert(path, self.added[path]) end @@ -226,7 +226,7 @@ function M.Transaction:commit() local value = self.backend:get(path) if type(value) == 'table' then for _, child in ipairs(value) do - local cp = address.join(path, child) + local cp = pth.join(path, child) assert(self.deleted[cp]) insert_del(cp) end |