3 UCI Validation Layer - Main Library
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 function _assert( condition, fmt, ... )
21 return assert( nil, string.format( fmt, ... ) )
28 function _parse_reference( r, c, s, o )
36 for i, v in ipairs(luci.util.split(r,".")) do
37 table.insert( ref, (v:gsub( "%$(.+)", function(n) return vars[n] end )) )
40 if #ref == 1 and c and s then
41 ref = { c, s, ref[1] }
42 elseif #ref == 2 and c then
43 ref = { c, unpack(ref) }
45 print("INVALID REFERENCE: "..#ref, c, s, o)
52 function check_dependency( self, uci, conf, sect, optn, nodeps, section2 )
54 -- print( "Depency check: ", conf .. '.' .. sect .. ( optn and '.' .. optn or '' ) )
56 local key = conf .. '.' .. sect .. ( optn and '.' .. optn or '' )
57 if not self.beenthere[key] then
58 self.beenthere[key] = true
60 print("CIRCULAR DEPENDENCY!")
61 return false, "Recursive depency detected"
65 if not self.packages[conf] then self:read_scheme(conf) end
66 local item = self.packages[conf]
70 item = _assert( self:_scheme_section( uci, conf, sect ) or self:_scheme_section( uci, conf, section2 ),
71 "Unknown section '%s' in scheme '%s' requested",
72 sect or '<nil>', conf or '<nil>' )
76 item = _assert( self:_scheme_option( uci, conf, sect, optn ) or
77 self:_scheme_option( uci, conf, section2, optn ),
78 "Unknown variable '%s' in scheme '%s', section '%s' requested",
79 optn or '<nil>', conf or '<nil>', sect or '<nil>' )
87 for _, dep in ipairs(item.depends) do
88 --print("DEP:",luci.util.serialize_data(dep))
90 local subcondition = true
92 for k, v in pairs(dep) do
94 local ref = _assert( _parse_reference(k,conf,sect,optn),
95 "Ambiguous dependency reference '" .. k .. "' given" )
97 -- XXX: true -> nodeps
98 valid, err = self:validate_option(ref[1], ref[2], ref[3], uci, true, section2)
100 --print("CHK:",uci[ref[2]][ref[3]],v,unpack(ref))
102 ( type(v) == "boolean" and uci[ref[2]][ref[3]] ) or
103 ( ref[3] and uci[ref[2]][ref[3]] ) == v
106 err = type(v) ~= "boolean"
107 and "Option '" .. table.concat( ref, "." ) .. "' doesn't match requested type '" .. v .. '"'
108 or "Option '" .. table.concat( ref, "." ) .. "' has no value"
119 -- print( " -> Success (condition matched)\n" )
124 -- print( " -> Failed\n" )
128 -- print( " -> Success (no depends)\n" )