3 UCI Validation Layer - Dependency helper
4 (c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
5 (c) 2008 Steven Barth <steven@midlink.org>
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
17 module( "luci.uvl.dependencies", package.seeall )
19 local ERR = luci.uvl.errors
21 function _parse_reference( r, c, s, o )
24 config = ( c or '$config' ),
25 section = ( s or '$section' ),
26 option = ( o or '$option' )
29 for i, v in ipairs(luci.util.split(r,".")) do
30 table.insert(ref, (v:gsub( "%$(.+)", function(n) return vars[n] end )))
34 if #ref == 1 and c and s then
35 ref = { c, s, ref[1] }
36 elseif #ref == 2 and c then
37 ref = { c, unpack(ref) }
43 ref = { '$config', '$section', ref[1] }
45 ref = { '$config', unpack(ref) }
54 function _serialize_dependency( dep, v )
57 for k, v in luci.util.spairs( dep,
59 a = ( type(dep[a]) ~= "boolean" and "_" or "" ) .. a
60 b = ( type(dep[b]) ~= "boolean" and "_" or "" ) .. b
64 str = ( str and str .. " and " or "" ) .. k ..
65 ( type(v) ~= "boolean" and "=" .. v or "" )
71 function check( self, object, nodeps )
73 local derr = ERR.DEPENDENCY(object)
75 if not self.beenthere[object:cid()] then
76 self.beenthere[object:cid()] = true
78 return false, derr:child(ERR.DEP_RECURSIVE(object))
81 if object:scheme('depends') then
85 for _, dep in ipairs(object:scheme('depends')) do
86 local subcondition = true
87 for k, v in pairs(dep) do
89 local ref = _parse_reference( k, unpack(object.cref) )
92 return false, derr:child(ERR.SME_BADDEP(object,k))
95 local option = luci.uvl.option( self, object.c, unpack(ref) )
97 valid, err = self:_validate_option( option, true )
100 ( type(v) == "boolean" and option:value() ) or
101 ( ref[3] and option:value() ) == v
105 local depstr = _serialize_dependency( dep, v )
108 and ERR.DEP_NOVALUE(option, depstr)
109 or ERR.DEP_NOTEQUAL(option, {depstr, v})
117 local depstr = _serialize_dependency( dep, v )
118 derr:child(ERR.DEP_NOTVALID(option, depstr):child(err))
139 if object:scheme("type") == "enum" and
140 object:scheme("enum_depends")[object:value()]
144 local enum = object:enum()
145 local eerr = ERR.DEP_BADENUM(enum)
147 for _, dep in ipairs(enum:scheme('enum_depends')[object:value()]) do
148 local subcondition = true
149 for k, v in pairs(dep) do
151 local ref = _parse_reference( k, unpack(object.cref) )
154 return false, derr:child(eerr:child(ERR.SME_BADDEP(enum,k)))
157 local option = luci.uvl.option( self, object.c, unpack(ref) )
159 valid, err = self:_validate_option( option, true )
162 ( type(v) == "boolean" and object.config[ref[2]][ref[3]] ) or
163 ( ref[3] and object:config() ) == v
167 local depstr = _serialize_dependency( dep, v )
170 and ERR.DEP_NOVALUE(option, depstr)
171 or ERR.DEP_NOTEQUAL(option, {depstr, v})
179 local depstr = _serialize_dependency( dep, v )
180 eerr:child(ERR.DEP_NOTVALID(option, depstr):child(err))
194 return false, derr:child(eerr)