* 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_SCHEME = 0x00
TYPE_CONFIG = 0x01 TYPE_CONFIG = 0x01
TYPE_SECTION = 0x02 TYPE_SECTION = 0x02
TYPE_VARIABLE = 0x03 TYPE_OPTION = 0x03
TYPE_OPTION = 0x04 TYPE_ENUM = 0x04
TYPE_ENUM = 0x05
--- Boolean; default true; --- Boolean; default true;
-- treat sections found in config but not in scheme as error -- 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 if type(val) ~= "table" and STRICT_LIST_TYPE then
return false, option:error(ERR.OPT_NOTLIST(option)) return false, option:error(ERR.OPT_NOTLIST(option))
end end
elseif option:scheme('datatype') then end
if option:scheme('datatype') then
local dt = option:scheme('datatype') local dt = option:scheme('datatype')
if self.datatypes[dt] then if self.datatypes[dt] then
@ -378,10 +379,20 @@ end
function UVL._read_scheme_parts( self, scheme, schemes ) function UVL._read_scheme_parts( self, scheme, schemes )
-- helper function to check for required fields -- 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 for i, v in ipairs(r) do
if not t[v] then if not c[v] then
return false, ERR.SME_REQFLD({c,t}, v) 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
end end
return true return true
@ -393,7 +404,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
if c == TYPE_SECTION then if c == TYPE_SECTION then
k = "package" k = "package"
n = 1 n = 1
elseif c == TYPE_VARIABLE then elseif c == TYPE_OPTION then
k = "section" k = "section"
n = 2 n = 2
elseif c == TYPE_ENUM then elseif c == TYPE_ENUM then
@ -444,7 +455,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
for k, v in pairs( conf ) do for k, v in pairs( conf ) do
if v['.type'] == 'section' then 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 if err then return false, scheme:error(err) end
local r, err = _ref( TYPE_SECTION, v ) 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 for k, v in pairs( conf ) do
if v['.type'] == "variable" then 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 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 if err then return false, scheme:error(err) end
local p = self.packages[r[1]] 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 for k, v in pairs( conf ) do
if v['.type'] == "enum" then 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 if err then return false, scheme:error(err) end
local r, err = _ref( TYPE_ENUM, v ) local r, err = _ref( TYPE_ENUM, v )
@ -682,6 +693,25 @@ function UVL._read_validator( self, values, validators )
validator = value:gsub("^exec:","") validator = value:gsub("^exec:","")
elseif value:match("^lua:") then elseif value:match("^lua:") then
validator = self:_resolve_function( (value:gsub("^lua:","") ) ) 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 end
if validator then if validator then
@ -774,16 +804,19 @@ function uvlitem.scheme(self, opt)
local s local s
if #self.sref == 4 or #self.sref == 3 then if #self.sref == 4 or #self.sref == 3 then
s = self.s s = self.s and self.s.packages
.packages[self.sref[1]] s = s and s[self.sref[1]]
.variables[self.sref[2]][self.sref[3]] s = s and s.variables
s = s and s[self.sref[2]]
s = s and s[self.sref[3]]
elseif #self.sref == 2 then elseif #self.sref == 2 then
s = self.s s = self.s and self.s.packages
.packages[self.sref[1]] s = s and s[self.sref[1]]
.sections[self.sref[2]] s = s and s.sections
s = s and s[self.sref[2]]
else else
s = self.s s = self.s and self.s.packages
.packages[self.sref[1]] s = s and s[self.sref[1]]
end end
if s and opt then if s and opt then

View file

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

View file

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