* luci/libs: uvl: implement dependencies for enum values
authorJo-Philipp Wich <jow@openwrt.org>
Mon, 25 Aug 2008 18:30:25 +0000 (18:30 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Mon, 25 Aug 2008 18:30:25 +0000 (18:30 +0000)
libs/uvl/luasrc/uvl.lua
libs/uvl/luasrc/uvl/dependencies.lua

index ed0bd13e1b5fe177053dbd7f3350663de4a6a85e..aaeb875f524e572e1e6837d460ef862942891c26 100644 (file)
@@ -352,7 +352,7 @@ function UVL._validate_option( self, option, nodeps )
                                return false,
                                        'Value "%s" of given option "%s" is not defined in %s { %s }'
                                                %{ val or '<nil>', option:cid(), item.type,
-                                                  table.concat( luci.util.keys(item.values), ", " ) }
+                                                  table.concat( luci.util.keys(item.values or {}), ", " ) }
                        end
                elseif item.type == "list" and val then
                        if type(val) ~= "table" and STRICT_LIST_TYPE then
@@ -609,6 +609,10 @@ function UVL._read_scheme_parts( self, scheme, schemes )
                                        t.values[v.value] = v.title or v.value
                                end
 
+                               if not t.enum_depends then
+                                       t.enum_depends = { }
+                               end
+
                                if v.default then
                                        _assert( not t.default,
                                                'Enum "%s" in scheme "%s", section "%s" redeclares ' ..
@@ -617,6 +621,16 @@ function UVL._read_scheme_parts( self, scheme, schemes )
 
                                        t.default = v.value
                                end
+
+                               if v.depends then
+                                       t.enum_depends[v.value] = _assert(
+                                               self:_read_dependency(
+                                                       v.depends, t.enum_depends[v.value]
+                                               ),
+                                               'Invalid reference "%s" in "%s.%s.%s.%s"',
+                                               v.depends, scheme, r[2], r[3], v.value
+                                       )
+                               end
                        end
                end
        end
index fc407a985912a1302db967bb0d414e7497681e74..a84f73c7b4dd24da5e9c468ae3806693f52e6634 100644 (file)
@@ -113,5 +113,58 @@ function check( self, object, nodeps )
                return false, err
        end
 
+       if item.type == "enum" and item.enum_depends[object:value()] then
+               local ok = false
+               local valid, err = false,
+                       string.format( 'In dependency check for enum value "%s.%s":',
+                               object:cid(), object:value() )
+
+               for _, dep in ipairs(item.enum_depends[object:value()]) do
+                       local subcondition = true
+                       for k, v in pairs(dep) do
+                               -- XXX: better error
+                               local ref = _parse_reference( k, unpack(object.cref) )
+
+                               if not ref then
+                                       return false, "Ambiguous dependency reference '" .. k ..
+                                               "' for enum '" .. object:sid() .. "." ..
+                                               object:value() .. "' given"
+                               end
+
+                               local option = luci.uvl.option(
+                                       self, object.config,
+                                       object.config[ref[2]]
+                                               and object.config[ref[2]]['.type']
+                                               or  object.sref[2],
+                                       ref[1], ref[2], ref[3]
+                               )
+
+                               valid, err2 = self:_validate_option( option, true )
+                               if valid then
+                                       if not (
+                                               ( type(v) == "boolean" and object.config[ref[2]][ref[3]] ) or
+                                               ( ref[3] and object.config[ref[2]][ref[3]] ) == v
+                                       ) then
+                                               subcondition = false
+                                               err = err .. "\n" ..
+                                                       self.log.dump_dependency( dep, ref, v )
+                                               break
+                                       end
+                               else
+                                       subcondition = false
+                                       err = err .. "\n" ..
+                                               self.log.dump_dependency( dep, ref, nil, err2 )
+                                       break
+                               end
+                       end
+
+                       if subcondition then
+                               return true
+                       end
+               end
+
+               return false, err
+       end
+
        return true
 end