build: remove some obsolete support scripts
[project/luci.git] / libs / uvl / luasrc / uvl / dependencies.lua
1 --[[
2
3 UCI Validation Layer - Dependency helper
4 (c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
5 (c) 2008 Steven Barth <steven@midlink.org>
6
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
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 $Id$
14
15 ]]--
16
17 local uvl = require "luci.uvl"
18 local ERR = require "luci.uvl.errors".error
19 local util = require "luci.util"
20 local table = require "table"
21
22 local type, unpack = type, unpack
23 local ipairs, pairs = ipairs, pairs
24
25 module "luci.uvl.dependencies"
26
27
28
29 function _parse_reference( r, c, s, o )
30 local ref = { }
31 local vars = {
32 config = c,
33 section = s,
34 option = o
35 }
36
37 for v in r:gmatch("[^.]+") do
38 ref[#ref+1] = (v:gsub( "%$(.+)", vars ))
39 end
40
41 if #ref < 2 then
42 table.insert(ref, 1, s or '$section')
43 end
44 if #ref < 3 then
45 table.insert(ref, 1, c or '$config')
46 end
47
48 return ref
49 end
50
51 function _serialize_dependency( dep, v )
52 local str
53
54 for k, v in util.spairs( dep,
55 function(a,b)
56 a = ( type(dep[a]) ~= "boolean" and "_" or "" ) .. a
57 b = ( type(dep[b]) ~= "boolean" and "_" or "" ) .. b
58 return a < b
59 end
60 ) do
61 str = ( str and str .. " and " or "" ) .. k ..
62 ( type(v) ~= "boolean" and "=" .. v or "" )
63 end
64
65 return str
66 end
67
68 function check( self, object, nodeps )
69
70 local derr = ERR('DEPENDENCY', object)
71
72 if not self.depseen[object:cid()] then
73 self.depseen[object:cid()] = true
74 else
75 return false, derr:child(ERR('DEP_RECURSIVE', object))
76 end
77
78 if object:scheme('depends') then
79 local ok = true
80 local valid = false
81
82 for _, dep in ipairs(object:scheme('depends')) do
83 local subcondition = true
84 for k, v in pairs(dep) do
85 -- XXX: better error
86 local ref = _parse_reference( k, unpack(object.cref) )
87
88 if not ref then
89 return false, derr:child(ERR('SME_BADDEP',object,k))
90 end
91
92 local option = uvl.option( self, object.c, unpack(ref) )
93
94 valid, err = self:_validate_option( option, true )
95 if valid then
96 if not (
97 ( type(v) == "boolean" and option:value() ) or
98 ( ref[3] and option:value() ) == v
99 ) then
100 subcondition = false
101
102 local depstr = _serialize_dependency( dep, v )
103 derr:child(
104 type(v) == "boolean"
105 and ERR('DEP_NOVALUE', option, depstr)
106 or ERR('DEP_NOTEQUAL', option, {depstr, v})
107 )
108
109 break
110 end
111 else
112 subcondition = false
113
114 local depstr = _serialize_dependency( dep, v )
115 derr:child(ERR('DEP_NOTVALID', option, depstr):child(err))
116
117 break
118 end
119 end
120
121 if subcondition then
122 ok = true
123 break
124 else
125 ok = false
126 end
127 end
128
129 if not ok then
130 return false, derr
131 end
132 else
133 return true
134 end
135
136 if object:scheme("type") == "enum" and
137 object:scheme("enum_depends")[object:value()]
138 then
139 local ok = true
140 local valid = false
141 local enum = object:enum()
142 local eerr = ERR('DEP_BADENUM', enum)
143
144 for _, dep in ipairs(enum:scheme('enum_depends')[object:value()]) do
145 local subcondition = true
146 for k, v in pairs(dep) do
147 -- XXX: better error
148 local ref = _parse_reference( k, unpack(object.cref) )
149
150 if not ref then
151 return false, derr:child(eerr:child(ERR('SME_BADDEP',enum,k)))
152 end
153
154 local option = luci.uvl.option( self, object.c, unpack(ref) )
155
156 valid, err = self:_validate_option( option, true )
157 if valid then
158 if not (
159 ( type(v) == "boolean" and object.config[ref[2]][ref[3]] ) or
160 ( ref[3] and object:config() ) == v
161 ) then
162 subcondition = false
163
164 local depstr = _serialize_dependency( dep, v )
165 eerr:child(
166 type(v) == "boolean"
167 and ERR('DEP_NOVALUE', option, depstr)
168 or ERR('DEP_NOTEQUAL', option, {depstr, v})
169 )
170
171 break
172 end
173 else
174 subcondition = false
175
176 local depstr = _serialize_dependency( dep, v )
177 eerr:child(ERR('DEP_NOTVALID', option, depstr):child(err))
178
179 break
180 end
181 end
182
183 if subcondition then
184 return true
185 else
186 ok = false
187 end
188 end
189
190 if not ok then
191 return false, derr:child(eerr)
192 end
193 end
194
195 return true
196 end