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 function _parse_reference( r, c, s, o )
22 config = ( c or '$config' ),
23 section = ( s or '$section' ),
24 option = ( o or '$option' )
27 for i, v in ipairs(luci.util.split(r,".")) do
28 table.insert(ref, (v:gsub( "%$(.+)", function(n) return vars[n] end )))
32 if #ref == 1 and c and s then
33 ref = { c, s, ref[1] }
34 elseif #ref == 2 and c then
35 ref = { c, unpack(ref) }
41 ref = { '$config', '$section', ref[1] }
43 ref = { '$config', unpack(ref) }
52 function check( self, object, nodeps )
54 if not self.beenthere[object:cid()] then
55 self.beenthere[object:cid()] = true
57 return false, "Recursive dependency for '" .. object:sid() .. "' found"
60 local item = object.type == luci.uvl.TYPE_SECTION
61 and object:section() or object:option()
65 local valid, err = false,
66 string.format( 'In dependency check for %s "%s":',
67 ( object.type == luci.uvl.TYPE_SECTION and "section" or "option" ),
70 for _, dep in ipairs(item.depends) do
71 local subcondition = true
72 for k, v in pairs(dep) do
74 local ref = _parse_reference( k, unpack(object.cref) )
77 return false, "Ambiguous dependency reference '" .. k ..
78 "' for object '" .. object:sid() .. "' given"
81 local option = luci.uvl.option(
84 and object.config[ref[2]]['.type']
86 ref[1], ref[2], ref[3]
89 valid, err2 = self:_validate_option( option, true )
92 ( type(v) == "boolean" and object.config[ref[2]][ref[3]] ) or
93 ( ref[3] and object.config[ref[2]][ref[3]] ) == v
97 self.log.dump_dependency( dep, ref, v )
103 self.log.dump_dependency( dep, ref, nil, err2 )
116 if item.type == "enum" and item.enum_depends[object:value()] then
118 local valid, err = false,
119 string.format( 'In dependency check for enum value "%s.%s":',
120 object:cid(), object:value() )
122 for _, dep in ipairs(item.enum_depends[object:value()]) do
123 local subcondition = true
124 for k, v in pairs(dep) do
126 local ref = _parse_reference( k, unpack(object.cref) )
129 return false, "Ambiguous dependency reference '" .. k ..
130 "' for enum '" .. object:sid() .. "." ..
131 object:value() .. "' given"
134 local option = luci.uvl.option(
136 object.config[ref[2]]
137 and object.config[ref[2]]['.type']
139 ref[1], ref[2], ref[3]
142 valid, err2 = self:_validate_option( option, true )
145 ( type(v) == "boolean" and object.config[ref[2]][ref[3]] ) or
146 ( ref[3] and object.config[ref[2]][ref[3]] ) == v
150 self.log.dump_dependency( dep, ref, v )
156 self.log.dump_dependency( dep, ref, nil, err2 )