* luci/libs/uvl:

- fix handling of missing package/section/variable fields in scheme specs
	- fix dereferencing of scheme tables in luci.uvl.uvlitem.scheme()
	- unify TYPE_VARIABLE and TYPE_OPTION
	- implement external "regexp:..." validators
	- extend reference scheme to implement "lazylist" type for lists
This commit is contained in:
Jo-Philipp Wich 2008-09-02 22:13:52 +00:00
parent 51bfdb1377
commit 6b6abc95d0
3 changed files with 75 additions and 32 deletions

View file

@ -33,9 +33,8 @@ require("luci.uvl.dependencies")
TYPE_SCHEME = 0x00
TYPE_CONFIG = 0x01
TYPE_SECTION = 0x02
TYPE_VARIABLE = 0x03
TYPE_OPTION = 0x04
TYPE_ENUM = 0x05
TYPE_OPTION = 0x03
TYPE_ENUM = 0x04
--- Boolean; default true;
-- treat sections found in config but not in scheme as error
@ -306,7 +305,9 @@ function UVL._validate_option( self, option, nodeps )
if type(val) ~= "table" and STRICT_LIST_TYPE then
return false, option:error(ERR.OPT_NOTLIST(option))
end
elseif option:scheme('datatype') then
end
if option:scheme('datatype') then
local dt = option:scheme('datatype')
if self.datatypes[dt] then
@ -378,10 +379,20 @@ end
function UVL._read_scheme_parts( self, scheme, schemes )
-- helper function to check for required fields
local function _req( c, t, r )
local function _req( t, n, c, r )
for i, v in ipairs(r) do
if not t[v] then
return false, ERR.SME_REQFLD({c,t}, v)
if not c[v] then
local p, o = scheme:sid(), nil
if t == TYPE_SECTION then
o = section( scheme, nil, p, n )
elseif t == TYPE_OPTION then
o = option( scheme, nil, p, '(nil)', n )
elseif t == TYPE_ENUM then
o = enum( scheme, nil, p, '(nil)', '(nil)', n )
end
return false, ERR.SME_REQFLD(o,v)
end
end
return true
@ -393,7 +404,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
if c == TYPE_SECTION then
k = "package"
n = 1
elseif c == TYPE_VARIABLE then
elseif c == TYPE_OPTION then
k = "section"
n = 2
elseif c == TYPE_ENUM then
@ -444,7 +455,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
for k, v in pairs( conf ) do
if v['.type'] == 'section' then
ok, err = _req( TYPE_SECTION, v, { "name", "package" } )
ok, err = _req( TYPE_SECTION, k, v, { "name", "package" } )
if err then return false, scheme:error(err) end
local r, err = _ref( TYPE_SECTION, v )
@ -496,10 +507,10 @@ function UVL._read_scheme_parts( self, scheme, schemes )
for k, v in pairs( conf ) do
if v['.type'] == "variable" then
ok, err = _req( TYPE_VARIABLE, v, { "name", "section" } )
ok, err = _req( TYPE_OPTION, k, v, { "name", "section" } )
if err then return false, scheme:error(err) end
local r, err = _ref( TYPE_VARIABLE, v )
local r, err = _ref( TYPE_OPTION, v )
if err then return false, scheme:error(err) end
local p = self.packages[r[1]]
@ -567,7 +578,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
for k, v in pairs( conf ) do
if v['.type'] == "enum" then
ok, err = _req( TYPE_ENUM, v, { "value", "variable" } )
ok, err = _req( TYPE_ENUM, k, v, { "value", "variable" } )
if err then return false, scheme:error(err) end
local r, err = _ref( TYPE_ENUM, v )
@ -682,6 +693,25 @@ function UVL._read_validator( self, values, validators )
validator = value:gsub("^exec:","")
elseif value:match("^lua:") then
validator = self:_resolve_function( (value:gsub("^lua:","") ) )
elseif value:match("^regexp:") then
local pattern = value:gsub("^regexp:","")
validator = function( type, dtype, pack, sect, optn, ... )
local values = { ... }
for _, v in ipairs(values) do
local ok, match =
luci.util.copcall( string.match, v, pattern )
if not ok then
return false, match
elseif not match then
return false,
'Value "%s" does not match pattern "%s"' % {
v, pattern
}
end
end
return true
end
end
if validator then
@ -774,16 +804,19 @@ function uvlitem.scheme(self, opt)
local s
if #self.sref == 4 or #self.sref == 3 then
s = self.s
.packages[self.sref[1]]
.variables[self.sref[2]][self.sref[3]]
s = self.s and self.s.packages
s = s and s[self.sref[1]]
s = s and s.variables
s = s and s[self.sref[2]]
s = s and s[self.sref[3]]
elseif #self.sref == 2 then
s = self.s
.packages[self.sref[1]]
.sections[self.sref[2]]
s = self.s and self.s.packages
s = s and s[self.sref[1]]
s = s and s.sections
s = s and s[self.sref[2]]
else
s = self.s
.packages[self.sref[1]]
s = self.s and self.s.packages
s = s and s[self.sref[1]]
end
if s and opt then

View file

@ -43,10 +43,14 @@ function check( self, object )
if object:scheme('validators') then
for _, val in ipairs(object:scheme('validators')) do
local ok, err = false, nil
local values = object:value()
values = type(values) == "table" and values or { values }
local args = {
object:scheme('type'),
object.cref[1], object.cref[2], object.cref[3],
object:scheme('datatype'), object:value()
object:scheme('type'), object:scheme('datatype'),
object.cref[1], object.cref[2], object.cref[3] or '',
unpack(values)
}
if type(val) == "function" then

View file

@ -38,7 +38,7 @@ config variable
option name 'description'
option title 'Description of the defined package'
option section 'schema.package'
option type 'variable'
option type 'lazylist'
option datatype 'string'
option required false
@ -92,7 +92,7 @@ config variable
option name 'description'
option title 'Description of the defined section'
option section 'schema.section'
option type 'variable'
option type 'lazylist'
option datatype 'string'
option required false
@ -101,7 +101,7 @@ config variable
option name 'depends'
option title 'List of dependencies within and between defined sections'
option section 'schema.section'
option type 'list'
option type 'lazylist'
option datatype 'string'
option required false
@ -191,7 +191,7 @@ config variable
option name 'description'
option title 'Description of the defined variable'
option section 'schema.variable'
option type 'variable'
option type 'lazylist'
option datatype 'string'
option required false
@ -200,7 +200,7 @@ config variable
option name 'depends'
option title 'List of dependencies between defined variables'
option section 'schema.variable'
option type 'list'
option type 'lazylist'
option datatype 'string'
option required false
@ -240,6 +240,12 @@ config enum
option title 'This is a list variable'
option variable 'schema.variable.type'
# List-or-Option variable type (schema.@variable.type=lazylist)
config enum
option value 'lazylist'
option title 'This is a list or option variable'
option variable 'schema.variable.type'
# Reference variable type (schema.@variable.type=reference)
config enum
option value 'reference'
@ -260,7 +266,7 @@ config variable
option name 'validator'
option title 'Datatype of this variable'
option section 'schema.variable'
option type 'list'
option type 'lazylist'
option datatype 'string'
option required false
@ -269,7 +275,7 @@ config variable
option name 'valueof'
option title 'Reference to section or option to read values from'
option section 'schema.variable'
option type 'list'
option type 'lazylist'
option datatype 'string'
option required false
@ -323,7 +329,7 @@ config variable
option name 'description'
option title 'Description of the defined enum value'
option section 'schema.enum'
option type 'variable'
option type 'lazylist'
option datatype 'string'
option required false
@ -332,7 +338,7 @@ config variable
option name 'depends'
option title 'List of dependencies on defined variables'
option section 'schema.enum'
option type 'list'
option type 'lazylist'
option datatype 'string'
option required false