Backported UVL optimizations

This commit is contained in:
Steven Barth 2008-09-13 09:09:38 +00:00
parent 8f8da32d7e
commit 1fe083b59a
5 changed files with 418 additions and 411 deletions

File diff suppressed because it is too large Load diff

View file

@ -14,11 +14,14 @@ $Id$
]]-- ]]--
module( "luci.uvl.datatypes", package.seeall ) local fs = require "luci.fs"
local ip = require "luci.ip"
local math = require "math"
local util = require "luci.util"
require("luci.fs") local tonumber = tonumber
require("luci.ip")
require("luci.util") module "luci.uvl.datatypes"
function boolean( val ) function boolean( val )
@ -26,6 +29,8 @@ function boolean( val )
return true return true
elseif val == "0" or val == "no" or val == "off" or val == "false" then elseif val == "0" or val == "no" or val == "off" or val == "false" then
return true return true
elseif val == "" or val == nil then
return true
end end
return false return false
@ -59,7 +64,7 @@ end
function ip4addr( val ) function ip4addr( val )
if val then if val then
return luci.ip.IPv4(val) and true or false return ip.IPv4(val) and true or false
end end
return false return false
@ -72,7 +77,7 @@ end
function ip6addr( val ) function ip6addr( val )
if val then if val then
return luci.ip.IPv6(val) and true or false return ip.IPv6(val) and true or false
end end
return false return false
@ -102,7 +107,7 @@ function macaddr( val )
"^[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+:" .. "^[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+:" ..
"[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+$" "[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+$"
) then ) then
local parts = luci.util.split( val, ":" ) local parts = util.split( val, ":" )
for i = 1,6 do for i = 1,6 do
parts[i] = tonumber( parts[i], 16 ) parts[i] = tonumber( parts[i], 16 )
@ -134,7 +139,7 @@ function string( val )
end end
function directory( val, seen ) function directory( val, seen )
local s = luci.fs.stat( val ) local s = fs.stat( val )
seen = seen or { } seen = seen or { }
if s and not seen[s.ino] then if s and not seen[s.ino] then
@ -142,7 +147,7 @@ function directory( val, seen )
if s.type == "directory" then if s.type == "directory" then
return true return true
elseif s.type == "link" then elseif s.type == "link" then
return directory( luci.fs.readlink(val), seen ) return directory( fs.readlink(val), seen )
end end
end end
@ -150,7 +155,7 @@ function directory( val, seen )
end end
function file( val, seen ) function file( val, seen )
local s = luci.fs.stat( val ) local s = fs.stat( val )
seen = seen or { } seen = seen or { }
if s and not seen[s.ino] then if s and not seen[s.ino] then
@ -158,7 +163,7 @@ function file( val, seen )
if s.type == "regular" then if s.type == "regular" then
return true return true
elseif s.type == "link" then elseif s.type == "link" then
return file( luci.fs.readlink(val), seen ) return file( fs.readlink(val), seen )
end end
end end

View file

@ -14,38 +14,35 @@ $Id$
]]-- ]]--
module( "luci.uvl.dependencies", package.seeall ) local uvl = require "luci.uvl"
local ERR = require "luci.uvl.errors"
local util = require "luci.util"
local table = require "table"
local type, unpack = type, unpack
local ipairs, pairs = ipairs, pairs
module "luci.uvl.dependencies"
local ERR = luci.uvl.errors
function _parse_reference( r, c, s, o ) function _parse_reference( r, c, s, o )
local ref = { } local ref = { }
local vars = { local vars = {
config = ( c or '$config' ), config = c,
section = ( s or '$section' ), section = s,
option = ( o or '$option' ) option = o
} }
for i, v in ipairs(luci.util.split(r,".")) do for v in r:gmatch("[^.]+") do
table.insert(ref, (v:gsub( "%$(.+)", function(n) return vars[n] end ))) ref[#ref+1] = (v:gsub( "%$(.+)", vars ))
end end
if c or s then if #ref < 2 then
if #ref == 1 and c and s then table.insert(ref, 1, s or '$section')
ref = { c, s, ref[1] } end
elseif #ref == 2 and c then if #ref < 3 then
ref = { c, unpack(ref) } table.insert(ref, 1, c or '$config')
elseif #ref ~= 3 then
ref = nil
end
else
if #ref == 1 then
ref = { '$config', '$section', ref[1] }
elseif #ref == 2 then
ref = { '$config', unpack(ref) }
elseif #ref ~= 3 then
ref = nil
end
end end
return ref return ref
@ -54,7 +51,7 @@ end
function _serialize_dependency( dep, v ) function _serialize_dependency( dep, v )
local str local str
for k, v in luci.util.spairs( dep, for k, v in util.spairs( dep,
function(a,b) function(a,b)
a = ( type(dep[a]) ~= "boolean" and "_" or "" ) .. a a = ( type(dep[a]) ~= "boolean" and "_" or "" ) .. a
b = ( type(dep[b]) ~= "boolean" and "_" or "" ) .. b b = ( type(dep[b]) ~= "boolean" and "_" or "" ) .. b
@ -92,7 +89,7 @@ function check( self, object, nodeps )
return false, derr:child(ERR.SME_BADDEP(object,k)) return false, derr:child(ERR.SME_BADDEP(object,k))
end end
local option = luci.uvl.option( self, object.c, unpack(ref) ) local option = uvl.option( self, object.c, unpack(ref) )
valid, err = self:_validate_option( option, true ) valid, err = self:_validate_option( option, true )
if valid then if valid then

View file

@ -14,11 +14,19 @@ $Id$
]]-- ]]--
module( "luci.uvl.errors", package.seeall ) local uci = require "luci.model.uci"
local uvl = require "luci.uvl"
local util = require "luci.util"
local string = require "string"
require("luci.util") local ipairs, error, type = ipairs, error, type
local tonumber, unpack = tonumber, unpack
local luci = luci
module "luci.uvl.errors"
ERRCODES = { ERRCODES = {
{ 'UCILOAD', 'Unable to load config "%p": %1' }, { 'UCILOAD', 'Unable to load config "%p": %1' },
@ -68,11 +76,11 @@ ERRCODES = {
-- build error constants and instance constructors -- build error constants and instance constructors
for i, v in ipairs(ERRCODES) do for i, v in ipairs(ERRCODES) do
luci.uvl.errors[v[1]] = function(...) _M[v[1]] = function(...)
return error(i, ...) return error(i, ...)
end end
luci.uvl.errors['ERR_'..v[1]] = i _M['ERR_'..v[1]] = i
end end
@ -85,14 +93,14 @@ function i18n(key, def)
end end
error = luci.util.class() error = util.class()
function error.__init__(self, code, pso, args) function error.__init__(self, code, pso, args)
self.code = code self.code = code
self.args = ( type(args) == "table" and args or { args } ) self.args = ( type(args) == "table" and args or { args } )
if luci.util.instanceof( pso, luci.uvl.uvlitem ) then if util.instanceof( pso, uvl.uvlitem ) then
self.stype = pso.sref[2] self.stype = pso.sref[2]
self.package, self.section, self.option, self.value = unpack(pso.cref) self.package, self.section, self.option, self.value = unpack(pso.cref)
self.object = pso self.object = pso
@ -101,7 +109,7 @@ function error.__init__(self, code, pso, args)
pso = ( type(pso) == "table" and pso or { pso } ) pso = ( type(pso) == "table" and pso or { pso } )
if pso[2] then if pso[2] then
local uci = luci.model.uci.cursor() local uci = uci.cursor()
self.stype = uci:get(pso[1], pso[2]) or pso[2] self.stype = uci:get(pso[1], pso[2]) or pso[2]
end end
@ -113,7 +121,7 @@ function error.child(self, err)
if not self.childs then if not self.childs then
self.childs = { err } self.childs = { err }
else else
table.insert( self.childs, err ) self.childs[#self.childs+1] = err
end end
return self return self
end end

View file

@ -14,26 +14,28 @@ $Id$
]]-- ]]--
module( "luci.uvl.validation", package.seeall ) local os = require "os"
local fs = require "luci.fs"
local sys = require "luci.sys"
local ERR = require "luci.uvl.errors"
require("luci.fs") local ipairs, unpack, type, tostring = ipairs, unpack, type, tostring
require("luci.sys")
local ERR = luci.uvl.errors module "luci.uvl.validation"
function _exec( bin, args ) function _exec( bin, args )
local cmd, output = "", nil local cmd, output = "", nil
for _, v in ipairs({ bin, unpack(args) }) do for _, v in ipairs({ bin, unpack(args) }) do
cmd = cmd .. string.format("%q ",v):gsub("([%$`])","\\%1") cmd = cmd .. ("%q " % v):gsub("([%$`])","\\%1")
end end
local tmpfile = "/tmp/uvl" .. luci.sys.uniqueid(8) local tmpfile = "/tmp/uvl" .. sys.uniqueid(8)
local retval = os.execute( cmd .. " 1>" .. tmpfile .. " 2>" .. tmpfile ) local retval = os.execute( cmd .. " 1>" .. tmpfile .. " 2>" .. tmpfile )
if luci.fs.access(tmpfile) then if fs.access(tmpfile) then
output = luci.fs.readfile(tmpfile) output = fs.readfile(tmpfile)
luci.fs.unlink(tmpfile) fs.unlink(tmpfile)
end end
return retval, output return retval, output