libs: drop uvl and uvldoc
This commit is contained in:
parent
800a263049
commit
052f65950c
18 changed files with 0 additions and 3060 deletions
|
@ -1,2 +0,0 @@
|
||||||
include ../../build/config.mk
|
|
||||||
include ../../build/module.mk
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,187 +0,0 @@
|
||||||
--[[
|
|
||||||
|
|
||||||
UCI Validation Layer - Datatype Tests
|
|
||||||
(c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
|
||||||
(c) 2008 Steven Barth <steven@midlink.org>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
|
|
||||||
]]--
|
|
||||||
|
|
||||||
local fs = require "nixio.fs"
|
|
||||||
local ip = require "luci.ip"
|
|
||||||
local math = require "math"
|
|
||||||
local util = require "luci.util"
|
|
||||||
|
|
||||||
local tonumber = tonumber
|
|
||||||
|
|
||||||
module "luci.uvl.datatypes"
|
|
||||||
|
|
||||||
|
|
||||||
function boolean( val )
|
|
||||||
if val == "1" or val == "yes" or val == "on" or val == "true" then
|
|
||||||
return true
|
|
||||||
elseif val == "0" or val == "no" or val == "off" or val == "false" then
|
|
||||||
return true
|
|
||||||
elseif val == "" or val == nil then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function uint( val )
|
|
||||||
local n = tonumber(val)
|
|
||||||
if n ~= nil and math.floor(n) == n and n >= 0 then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function integer( val )
|
|
||||||
local n = tonumber(val)
|
|
||||||
if n ~= nil and math.floor(n) == n then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function float( val )
|
|
||||||
return ( tonumber(val) ~= nil )
|
|
||||||
end
|
|
||||||
|
|
||||||
function ipaddr( val )
|
|
||||||
return ip4addr(val) or ip6addr(val)
|
|
||||||
end
|
|
||||||
|
|
||||||
function ip4addr( val )
|
|
||||||
if val then
|
|
||||||
return ip.IPv4(val) and true or false
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function ip4prefix( val )
|
|
||||||
val = tonumber(val)
|
|
||||||
return ( val and val >= 0 and val <= 32 )
|
|
||||||
end
|
|
||||||
|
|
||||||
function ip6addr( val )
|
|
||||||
if val then
|
|
||||||
return ip.IPv6(val) and true or false
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function ip6prefix( val )
|
|
||||||
val = tonumber(val)
|
|
||||||
return ( val and val >= 0 and val <= 128 )
|
|
||||||
end
|
|
||||||
|
|
||||||
function port( val )
|
|
||||||
val = tonumber(val)
|
|
||||||
return ( val and val >= 1 and val <= 65535 )
|
|
||||||
end
|
|
||||||
|
|
||||||
function portrange( val )
|
|
||||||
local p1, p2 = val:match("^(%d+)%-(%d+)$")
|
|
||||||
if p1 and p2 and port(p1) and port(p2) then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return port(val)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function macaddr( val )
|
|
||||||
if val and val:match(
|
|
||||||
"^[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+:" ..
|
|
||||||
"[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+$"
|
|
||||||
) then
|
|
||||||
local parts = util.split( val, ":" )
|
|
||||||
|
|
||||||
for i = 1,6 do
|
|
||||||
parts[i] = tonumber( parts[i], 16 )
|
|
||||||
if parts[i] < 0 or parts[i] > 255 then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function hostname( val )
|
|
||||||
if val and val:match("[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*") then
|
|
||||||
return true -- XXX: ToDo: need better solution
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function host( val )
|
|
||||||
return hostname(val) or ipaddr(val)
|
|
||||||
end
|
|
||||||
|
|
||||||
function string( val )
|
|
||||||
return true -- Everything qualifies as valid string
|
|
||||||
end
|
|
||||||
|
|
||||||
function directory( val, seen )
|
|
||||||
local s = fs.stat( val )
|
|
||||||
seen = seen or { }
|
|
||||||
|
|
||||||
if s and not seen[s.ino] then
|
|
||||||
seen[s.ino] = true
|
|
||||||
if s.type == "dir" then
|
|
||||||
return true
|
|
||||||
elseif s.type == "lnk" then
|
|
||||||
return directory( fs.readlink(val), seen )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function file( val, seen )
|
|
||||||
local s = fs.stat( val )
|
|
||||||
seen = seen or { }
|
|
||||||
|
|
||||||
if s and not seen[s.ino] then
|
|
||||||
seen[s.ino] = true
|
|
||||||
if s.type == "reg" then
|
|
||||||
return true
|
|
||||||
elseif s.type == "lnk" then
|
|
||||||
return file( fs.readlink(val), seen )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function device( val, seen )
|
|
||||||
local s = fs.stat( val )
|
|
||||||
seen = seen or { }
|
|
||||||
|
|
||||||
if s and not seen[s.ino] then
|
|
||||||
seen[s.ino] = true
|
|
||||||
if s.type == "chr" or s.type == "blk" then
|
|
||||||
return true
|
|
||||||
elseif s.type == "lnk" then
|
|
||||||
return device( fs.readlink(val), seen )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
|
@ -1,196 +0,0 @@
|
||||||
--[[
|
|
||||||
|
|
||||||
UCI Validation Layer - Dependency helper
|
|
||||||
(c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
|
||||||
(c) 2008 Steven Barth <steven@midlink.org>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
|
|
||||||
]]--
|
|
||||||
|
|
||||||
local uvl = require "luci.uvl"
|
|
||||||
local ERR = require "luci.uvl.errors".error
|
|
||||||
local util = require "luci.util"
|
|
||||||
local table = require "table"
|
|
||||||
|
|
||||||
local type, unpack = type, unpack
|
|
||||||
local ipairs, pairs = ipairs, pairs
|
|
||||||
|
|
||||||
module "luci.uvl.dependencies"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function _parse_reference( r, c, s, o )
|
|
||||||
local ref = { }
|
|
||||||
local vars = {
|
|
||||||
config = c,
|
|
||||||
section = s,
|
|
||||||
option = o
|
|
||||||
}
|
|
||||||
|
|
||||||
for v in r:gmatch("[^.]+") do
|
|
||||||
ref[#ref+1] = (v:gsub( "%$(.+)", vars ))
|
|
||||||
end
|
|
||||||
|
|
||||||
if #ref < 2 then
|
|
||||||
table.insert(ref, 1, s or '$section')
|
|
||||||
end
|
|
||||||
if #ref < 3 then
|
|
||||||
table.insert(ref, 1, c or '$config')
|
|
||||||
end
|
|
||||||
|
|
||||||
return ref
|
|
||||||
end
|
|
||||||
|
|
||||||
function _serialize_dependency( dep, v )
|
|
||||||
local str
|
|
||||||
|
|
||||||
for k, v in util.spairs( dep,
|
|
||||||
function(a,b)
|
|
||||||
a = ( type(dep[a]) ~= "boolean" and "_" or "" ) .. a
|
|
||||||
b = ( type(dep[b]) ~= "boolean" and "_" or "" ) .. b
|
|
||||||
return a < b
|
|
||||||
end
|
|
||||||
) do
|
|
||||||
str = ( str and str .. " and " or "" ) .. k ..
|
|
||||||
( type(v) ~= "boolean" and "=" .. v or "" )
|
|
||||||
end
|
|
||||||
|
|
||||||
return str
|
|
||||||
end
|
|
||||||
|
|
||||||
function check( self, object, nodeps )
|
|
||||||
|
|
||||||
local derr = ERR('DEPENDENCY', object)
|
|
||||||
|
|
||||||
if not self.depseen[object:cid()] then
|
|
||||||
self.depseen[object:cid()] = true
|
|
||||||
else
|
|
||||||
return false, derr:child(ERR('DEP_RECURSIVE', object))
|
|
||||||
end
|
|
||||||
|
|
||||||
if object:scheme('depends') then
|
|
||||||
local ok = true
|
|
||||||
local valid = false
|
|
||||||
|
|
||||||
for _, dep in ipairs(object:scheme('depends')) 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, derr:child(ERR('SME_BADDEP',object,k))
|
|
||||||
end
|
|
||||||
|
|
||||||
local option = uvl.option( self, object.c, unpack(ref) )
|
|
||||||
|
|
||||||
valid, err = self:_validate_option( option, true )
|
|
||||||
if valid then
|
|
||||||
if not (
|
|
||||||
( type(v) == "boolean" and option:value() ) or
|
|
||||||
( ref[3] and option:value() ) == v
|
|
||||||
) then
|
|
||||||
subcondition = false
|
|
||||||
|
|
||||||
local depstr = _serialize_dependency( dep, v )
|
|
||||||
derr:child(
|
|
||||||
type(v) == "boolean"
|
|
||||||
and ERR('DEP_NOVALUE', option, depstr)
|
|
||||||
or ERR('DEP_NOTEQUAL', option, {depstr, v})
|
|
||||||
)
|
|
||||||
|
|
||||||
break
|
|
||||||
end
|
|
||||||
else
|
|
||||||
subcondition = false
|
|
||||||
|
|
||||||
local depstr = _serialize_dependency( dep, v )
|
|
||||||
derr:child(ERR('DEP_NOTVALID', option, depstr):child(err))
|
|
||||||
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if subcondition then
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
else
|
|
||||||
ok = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not ok then
|
|
||||||
return false, derr
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
if object:scheme("type") == "enum" and
|
|
||||||
object:scheme("enum_depends")[object:value()]
|
|
||||||
then
|
|
||||||
local ok = true
|
|
||||||
local valid = false
|
|
||||||
local enum = object:enum()
|
|
||||||
local eerr = ERR('DEP_BADENUM', enum)
|
|
||||||
|
|
||||||
for _, dep in ipairs(enum:scheme('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, derr:child(eerr:child(ERR('SME_BADDEP',enum,k)))
|
|
||||||
end
|
|
||||||
|
|
||||||
local option = luci.uvl.option( self, object.c, unpack(ref) )
|
|
||||||
|
|
||||||
valid, err = 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() ) == v
|
|
||||||
) then
|
|
||||||
subcondition = false
|
|
||||||
|
|
||||||
local depstr = _serialize_dependency( dep, v )
|
|
||||||
eerr:child(
|
|
||||||
type(v) == "boolean"
|
|
||||||
and ERR('DEP_NOVALUE', option, depstr)
|
|
||||||
or ERR('DEP_NOTEQUAL', option, {depstr, v})
|
|
||||||
)
|
|
||||||
|
|
||||||
break
|
|
||||||
end
|
|
||||||
else
|
|
||||||
subcondition = false
|
|
||||||
|
|
||||||
local depstr = _serialize_dependency( dep, v )
|
|
||||||
eerr:child(ERR('DEP_NOTVALID', option, depstr):child(err))
|
|
||||||
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if subcondition then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
ok = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not ok then
|
|
||||||
return false, derr:child(eerr)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
|
@ -1,188 +0,0 @@
|
||||||
--[[
|
|
||||||
|
|
||||||
UCI Validation Layer - Error handling
|
|
||||||
(c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
|
||||||
(c) 2008 Steven Barth <steven@midlink.org>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
|
|
||||||
]]--
|
|
||||||
|
|
||||||
local uci = require "luci.model.uci"
|
|
||||||
local uvl = require "luci.uvl"
|
|
||||||
local util = require "luci.util"
|
|
||||||
local string = require "string"
|
|
||||||
|
|
||||||
local luci, tonumber, unpack, ipairs, type =
|
|
||||||
luci, tonumber, unpack, ipairs, type
|
|
||||||
|
|
||||||
module "luci.uvl.errors"
|
|
||||||
|
|
||||||
ERRCODES = {
|
|
||||||
UCILOAD = 'Unable to load config "%p": %1',
|
|
||||||
|
|
||||||
SCHEME = 'Error in scheme "%p":\n%c',
|
|
||||||
CONFIG = 'Error in config "%p":\n%c',
|
|
||||||
SECTION = 'Error in section "%i" (%I):\n%c',
|
|
||||||
OPTION = 'Error in option "%i" (%I):\n%c',
|
|
||||||
REFERENCE = 'Option "%i" has invalid reference specification %1:\n%c',
|
|
||||||
DEPENDENCY = 'In dependency check for %t "%i":\n%c',
|
|
||||||
|
|
||||||
SME_FIND = 'Can not find scheme "%p" in "%1"',
|
|
||||||
SME_READ = 'Can not access file "%1"',
|
|
||||||
SME_REQFLD = 'Missing required scheme field "%1" in "%i"',
|
|
||||||
SME_INVREF = 'Illegal reference "%1" to an anonymous section',
|
|
||||||
SME_BADREF = 'Malformed reference in "%1"',
|
|
||||||
SME_BADDEP = 'Malformed dependency specification "%1" in "%i"',
|
|
||||||
SME_BADVAL = 'Malformed validator specification "%1" in "%i"',
|
|
||||||
SME_ERRVAL = 'External validator "%1" failed: %2',
|
|
||||||
SME_VBADPACK = 'Variable "%o" in scheme "%p" references unknown package "%1"',
|
|
||||||
SME_VBADSECT = 'Variable "%o" in scheme "%p" references unknown section "%1"',
|
|
||||||
SME_EBADPACK = 'Enum "%v" in scheme "%p" references unknown package "%1"',
|
|
||||||
SME_EBADSECT = 'Enum "%v" in scheme "%p" references unknown section "%1"',
|
|
||||||
SME_EBADOPT = 'Enum "%v" in scheme "%p" references unknown option "%1"',
|
|
||||||
SME_EBADTYPE = 'Enum "%v" in scheme "%p" references non-enum option "%I"',
|
|
||||||
SME_EBADDEF = 'Enum "%v" in scheme "%p" redeclares the default value of "%I"',
|
|
||||||
|
|
||||||
SECT_UNKNOWN = 'Section "%i" (%I) not found in scheme',
|
|
||||||
SECT_REQUIRED = 'Required section "%p.%S" not found in config',
|
|
||||||
SECT_UNIQUE = 'Unique section "%p.%S" occurs multiple times in config',
|
|
||||||
SECT_NAMED = 'The section of type "%p.%S" is stored anonymously in config but must be named',
|
|
||||||
SECT_NOTFOUND = 'Section "%p.%s" not found in config',
|
|
||||||
|
|
||||||
OPT_UNKNOWN = 'Option "%i" (%I) not found in scheme',
|
|
||||||
OPT_REQUIRED = 'Required option "%i" has no value',
|
|
||||||
OPT_BADVALUE = 'Value "%1" of option "%i" is not defined in enum %2',
|
|
||||||
OPT_INVVALUE = 'Value "%1" of option "%i" does not validate as datatype "%2"',
|
|
||||||
OPT_NOTLIST = 'Option "%i" is defined as list but stored as plain value',
|
|
||||||
OPT_DATATYPE = 'Option "%i" has unknown datatype "%1"',
|
|
||||||
OPT_NOTFOUND = 'Option "%p.%s.%o" not found in config',
|
|
||||||
OPT_RANGE = 'Option "%p.%s.%o" is not within the specified range',
|
|
||||||
|
|
||||||
DEP_NOTEQUAL = 'Dependency (%1) failed:\nOption "%i" is not eqal "%2"',
|
|
||||||
DEP_NOVALUE = 'Dependency (%1) failed:\nOption "%i" has no value',
|
|
||||||
DEP_NOTVALID = 'Dependency (%1) failed:\n%c',
|
|
||||||
DEP_RECURSIVE = 'Recursive dependency for option "%i" detected',
|
|
||||||
DEP_BADENUM = 'In dependency check for enum value "%i":\n%c'
|
|
||||||
}
|
|
||||||
|
|
||||||
function i18n(key)
|
|
||||||
if luci.i18n then
|
|
||||||
return luci.i18n.translate(key)
|
|
||||||
else
|
|
||||||
return key
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
error = util.class()
|
|
||||||
|
|
||||||
function error.__init__(self, code, pso, args)
|
|
||||||
|
|
||||||
self.code = code
|
|
||||||
self.args = ( type(args) == "table" and args or { args } )
|
|
||||||
|
|
||||||
if util.instanceof( pso, uvl.uvlitem ) then
|
|
||||||
self.stype = pso.sref[2]
|
|
||||||
self.package, self.section, self.option, self.value = unpack(pso.cref)
|
|
||||||
self.object = pso
|
|
||||||
self.value = self.value or ( pso.value and pso:value() )
|
|
||||||
else
|
|
||||||
pso = ( type(pso) == "table" and pso or { pso } )
|
|
||||||
|
|
||||||
if pso[2] then
|
|
||||||
local uci = uci.cursor()
|
|
||||||
self.stype = uci:get(pso[1], pso[2]) or pso[2]
|
|
||||||
end
|
|
||||||
|
|
||||||
self.package, self.section, self.option, self.value = unpack(pso)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function error.child(self, err)
|
|
||||||
if not self.childs then
|
|
||||||
self.childs = { err }
|
|
||||||
else
|
|
||||||
self.childs[#self.childs+1] = err
|
|
||||||
end
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
function error.string(self,pad)
|
|
||||||
pad = pad or " "
|
|
||||||
|
|
||||||
local str = i18n(ERRCODES[self.code] or self.code)
|
|
||||||
:gsub("\n", "\n"..pad)
|
|
||||||
:gsub("%%i", self:cid())
|
|
||||||
:gsub("%%I", self:sid())
|
|
||||||
:gsub("%%p", self.package or '(nil)')
|
|
||||||
:gsub("%%s", self.section or '(nil)')
|
|
||||||
:gsub("%%S", self.stype or '(nil)')
|
|
||||||
:gsub("%%o", self.option or '(nil)')
|
|
||||||
:gsub("%%v", self.value or '(nil)')
|
|
||||||
:gsub("%%t", self.object and self.object:type() or '(nil)' )
|
|
||||||
:gsub("%%T", self.object and self.object:title() or '(nil)' )
|
|
||||||
:gsub("%%([1-9])", function(n) return self.args[tonumber(n)] or '(nil)' end)
|
|
||||||
:gsub("%%c",
|
|
||||||
function()
|
|
||||||
local s = ""
|
|
||||||
for _, err in ipairs(self.childs or {}) do
|
|
||||||
s = s .. err:string(pad.." ") .. "\n" .. pad
|
|
||||||
end
|
|
||||||
return s
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
return (str:gsub("%s+$",""))
|
|
||||||
end
|
|
||||||
|
|
||||||
function error.cid(self)
|
|
||||||
return self.object and self.object:cid() or self.package ..
|
|
||||||
( self.section and '.' .. self.section or '' ) ..
|
|
||||||
( self.option and '.' .. self.option or '' ) ..
|
|
||||||
( self.value and '.' .. self.value or '' )
|
|
||||||
end
|
|
||||||
|
|
||||||
function error.sid(self)
|
|
||||||
return self.object and self.object:sid() or self.package ..
|
|
||||||
( self.stype and '.' .. self.stype or '' ) ..
|
|
||||||
( self.option and '.' .. self.option or '' ) ..
|
|
||||||
( self.value and '.' .. self.value or '' )
|
|
||||||
end
|
|
||||||
|
|
||||||
function error.is(self, code)
|
|
||||||
if self.code == code then
|
|
||||||
return true
|
|
||||||
elseif self.childs then
|
|
||||||
for _, c in ipairs(self.childs) do
|
|
||||||
if c:is(code) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function error.is_all(self, ...)
|
|
||||||
local codes = { ... }
|
|
||||||
|
|
||||||
if util.contains(codes, self.code) then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
local equal = false
|
|
||||||
for _, c in ipairs(self.childs) do
|
|
||||||
if c.childs then
|
|
||||||
equal = c:is_all(...)
|
|
||||||
else
|
|
||||||
equal = util.contains(codes, c.code)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return equal
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,72 +0,0 @@
|
||||||
--[[
|
|
||||||
|
|
||||||
UCI Validation Layer - Validation helper
|
|
||||||
(c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
|
||||||
(c) 2008 Steven Barth <steven@midlink.org>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
|
|
||||||
]]--
|
|
||||||
|
|
||||||
local os = require "os"
|
|
||||||
local fs = require "nixio.fs"
|
|
||||||
local sys = require "luci.sys"
|
|
||||||
local ERR = require "luci.uvl.errors".error
|
|
||||||
|
|
||||||
local ipairs, unpack, type, tostring = ipairs, unpack, type, tostring
|
|
||||||
|
|
||||||
module "luci.uvl.validation"
|
|
||||||
|
|
||||||
function _exec( bin, args )
|
|
||||||
local cmd, output = "", nil
|
|
||||||
|
|
||||||
for _, v in ipairs({ bin, unpack(args) }) do
|
|
||||||
cmd = cmd .. ("%q " % v):gsub("([%$`])","\\%1")
|
|
||||||
end
|
|
||||||
|
|
||||||
local tmpfile = "/tmp/uvl" .. sys.uniqueid(8)
|
|
||||||
local retval = os.execute( cmd .. " 1>" .. tmpfile .. " 2>" .. tmpfile )
|
|
||||||
|
|
||||||
if fs.access(tmpfile) then
|
|
||||||
output = fs.readfile(tmpfile)
|
|
||||||
fs.unlink(tmpfile)
|
|
||||||
end
|
|
||||||
|
|
||||||
return retval, output
|
|
||||||
end
|
|
||||||
|
|
||||||
function check( self, object )
|
|
||||||
if object:scheme('validators') then
|
|
||||||
for _, val in ipairs(object:scheme('validators')) do
|
|
||||||
local ok, err = false, nil
|
|
||||||
|
|
||||||
local values = object:value()
|
|
||||||
values = type(values) == "table" and values or { values }
|
|
||||||
|
|
||||||
local args = {
|
|
||||||
object:scheme('type'), object:scheme('datatype'),
|
|
||||||
object.cref[1], object.cref[2], object.cref[3] or '',
|
|
||||||
unpack(values)
|
|
||||||
}
|
|
||||||
|
|
||||||
if type(val) == "function" then
|
|
||||||
ok, err = val(unpack(args))
|
|
||||||
else
|
|
||||||
ok, err = _exec( val, args )
|
|
||||||
ok = ( ok == 0 )
|
|
||||||
end
|
|
||||||
|
|
||||||
if not ok then
|
|
||||||
return false, ERR('SME_ERRVAL', object, {tostring(val), err})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
end
|
|
|
@ -1,403 +0,0 @@
|
||||||
# UVL - Reference-Spec
|
|
||||||
# This is a meta scheme defining the format of uci schemes.
|
|
||||||
# $Id$
|
|
||||||
|
|
||||||
package schema
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Central package definition
|
|
||||||
#
|
|
||||||
# config package
|
|
||||||
# option ...
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Section definition (schema.@package)
|
|
||||||
config section
|
|
||||||
option name 'package'
|
|
||||||
option title 'Definition of uci package'
|
|
||||||
option package 'schema'
|
|
||||||
option required false
|
|
||||||
option named false
|
|
||||||
option unique true
|
|
||||||
option dynamic false
|
|
||||||
|
|
||||||
# Section title (schema.@package.title)
|
|
||||||
config variable
|
|
||||||
option name 'title'
|
|
||||||
option title 'Title of the defined package'
|
|
||||||
option section 'schema.package'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Section description (schema.@package.description)
|
|
||||||
config variable
|
|
||||||
option name 'description'
|
|
||||||
option title 'Description of the defined package'
|
|
||||||
option section 'schema.package'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Central section definition
|
|
||||||
#
|
|
||||||
# config section
|
|
||||||
# option ...
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Section definition (schema.@section)
|
|
||||||
config section
|
|
||||||
option name 'section'
|
|
||||||
option title 'Definition of uci section'
|
|
||||||
option package 'schema'
|
|
||||||
option required false
|
|
||||||
option named false
|
|
||||||
option unique false
|
|
||||||
option dynamic false
|
|
||||||
|
|
||||||
# Section name (schema.@section.name)
|
|
||||||
config variable
|
|
||||||
option name 'name'
|
|
||||||
option title 'Name of the defined section'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required true
|
|
||||||
|
|
||||||
# Section package (schema.@section.package)
|
|
||||||
config variable
|
|
||||||
option name 'package'
|
|
||||||
option title 'Parent package of the defined section'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required true
|
|
||||||
|
|
||||||
# Section title (schema.@section.title)
|
|
||||||
config variable
|
|
||||||
option name 'title'
|
|
||||||
option title 'Title of the defined section'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Section description (schema.@section.description)
|
|
||||||
config variable
|
|
||||||
option name 'description'
|
|
||||||
option title 'Description of the defined section'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Section dependencies (schema.@section.depends)
|
|
||||||
config variable
|
|
||||||
option name 'depends'
|
|
||||||
option title 'List of dependencies within and between defined sections'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Section required flag (schema.@section.required)
|
|
||||||
config variable
|
|
||||||
option name 'required'
|
|
||||||
option title 'Specify whether at least one instance of this section type must be defined in config'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'boolean'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Section unique flag (schema.@section.unique)
|
|
||||||
config variable
|
|
||||||
option name 'unique'
|
|
||||||
option title 'Specify whether only one instance of this section type is allowed in config'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'boolean'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Section named flag (schema.@section.named)
|
|
||||||
config variable
|
|
||||||
option name 'named'
|
|
||||||
option title 'Specify whether sections of this type must have a name set (are not anonymous)'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'boolean'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Section dynamic flag (schema.@section.dynamic)
|
|
||||||
config variable
|
|
||||||
option name 'dynamic'
|
|
||||||
option title 'Specify whether sections of this type may contain arbitary, not specified options'
|
|
||||||
option section 'schema.section'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'boolean'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Central variable definition
|
|
||||||
#
|
|
||||||
# config variable
|
|
||||||
# option ...
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Variable definition (schema.@variable)
|
|
||||||
config section
|
|
||||||
option name 'variable'
|
|
||||||
option title 'Definition of uci variable'
|
|
||||||
option package 'schema'
|
|
||||||
option required false
|
|
||||||
option named false
|
|
||||||
option unique false
|
|
||||||
option dynamic false
|
|
||||||
|
|
||||||
# Variable name (schema.@variable.name)
|
|
||||||
config variable
|
|
||||||
option name 'name'
|
|
||||||
option title 'Name of the defined variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required true
|
|
||||||
|
|
||||||
# Variable section (schema.@variable.section)
|
|
||||||
config variable
|
|
||||||
option name 'section'
|
|
||||||
option title 'Parent section of the defined variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required true
|
|
||||||
|
|
||||||
# Variable title (schema.@variable.title)
|
|
||||||
config variable
|
|
||||||
option name 'title'
|
|
||||||
option title 'Title of the defined variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable description (schema.@variable.description)
|
|
||||||
config variable
|
|
||||||
option name 'description'
|
|
||||||
option title 'Description of the defined variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable dependencies (schema.@variable.depends)
|
|
||||||
config variable
|
|
||||||
option name 'depends'
|
|
||||||
option title 'List of dependencies between defined variables'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable required flag (schema.@variable.required)
|
|
||||||
config variable
|
|
||||||
option name 'required'
|
|
||||||
option title 'Specify whether this variable must be set in config'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'boolean'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable multiple values flag (schema.@variable.multival)
|
|
||||||
config variable
|
|
||||||
option name 'multival'
|
|
||||||
option title 'Specify whether this variable may contain multiple values separated by space'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'boolean'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable type (schema.@variable.type)
|
|
||||||
config variable
|
|
||||||
option name 'type'
|
|
||||||
option title 'Type of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'enum'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Plain variable type (schema.@variable.type=variable)
|
|
||||||
config enum
|
|
||||||
option value 'variable'
|
|
||||||
option title 'This is a plain variable'
|
|
||||||
option variable 'schema.variable.type'
|
|
||||||
|
|
||||||
# Enum variable type (schema.@variable.type=enum)
|
|
||||||
config enum
|
|
||||||
option value 'enum'
|
|
||||||
option title 'This is a enum variable'
|
|
||||||
option variable 'schema.variable.type'
|
|
||||||
|
|
||||||
# List variable type (schema.@variable.type=list)
|
|
||||||
config enum
|
|
||||||
option value 'list'
|
|
||||||
option title 'This is a list variable'
|
|
||||||
option variable 'schema.variable.type'
|
|
||||||
|
|
||||||
# List-or-Option variable type (schema.@variable.type=lazylist)
|
|
||||||
config enum
|
|
||||||
option value 'lazylist'
|
|
||||||
option title 'This is a list or option variable'
|
|
||||||
option variable 'schema.variable.type'
|
|
||||||
|
|
||||||
# Reference variable type (schema.@variable.type=reference)
|
|
||||||
config enum
|
|
||||||
option value 'reference'
|
|
||||||
option title 'This is a reference (valueof) variable'
|
|
||||||
option variable 'schema.variable.type'
|
|
||||||
|
|
||||||
# Variable datatype (schema.@variable.datatype)
|
|
||||||
config variable
|
|
||||||
option name 'datatype'
|
|
||||||
option title 'Datatype of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable default value (schema.@variable.default)
|
|
||||||
config variable
|
|
||||||
option name 'default'
|
|
||||||
option title 'Default value of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable minimum length (schema.@variable.minlength)
|
|
||||||
config variable
|
|
||||||
option name 'minlength'
|
|
||||||
option title 'Minimum length of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'uint'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable maximum length (schema.@variable.minlength)
|
|
||||||
config variable
|
|
||||||
option name 'maxlength'
|
|
||||||
option title 'Maximum length of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'uint'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable minimum value (schema.@variable.minlength)
|
|
||||||
config variable
|
|
||||||
option name 'minimum'
|
|
||||||
option title 'Minimum value of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'integer'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable maximum value (schema.@variable.minlength)
|
|
||||||
config variable
|
|
||||||
option name 'maximum'
|
|
||||||
option title 'Maximum value of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'integer'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable validators (schema.@variable.validator)
|
|
||||||
config variable
|
|
||||||
option name 'validator'
|
|
||||||
option title 'Datatype of this variable'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Variable value references (schema.@variable.valueof)
|
|
||||||
config variable
|
|
||||||
option name 'valueof'
|
|
||||||
option title 'Reference to section or option to read values from'
|
|
||||||
option section 'schema.variable'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Central enum definition
|
|
||||||
#
|
|
||||||
# config enum
|
|
||||||
# option ...
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Enum definition (schema.@enum)
|
|
||||||
config section
|
|
||||||
option name 'enum'
|
|
||||||
option title 'Definition of uci enum value'
|
|
||||||
option package 'schema'
|
|
||||||
option required false
|
|
||||||
option named false
|
|
||||||
option unique false
|
|
||||||
option dynamic false
|
|
||||||
|
|
||||||
# Enum value (schema.@enum.value)
|
|
||||||
config variable
|
|
||||||
option name 'value'
|
|
||||||
option title 'Value of the defined enum value'
|
|
||||||
option section 'schema.enum'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required true
|
|
||||||
|
|
||||||
# Enum variable (schema.@enum.variable)
|
|
||||||
config variable
|
|
||||||
option name 'variable'
|
|
||||||
option title 'Parent variable of the defined enum value'
|
|
||||||
option section 'schema.enum'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required true
|
|
||||||
|
|
||||||
# Enum value title (schema.@enum.title)
|
|
||||||
config variable
|
|
||||||
option name 'title'
|
|
||||||
option title 'Title of the defined enum value'
|
|
||||||
option section 'schema.enum'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Enum value description (schema.@enum.description)
|
|
||||||
config variable
|
|
||||||
option name 'description'
|
|
||||||
option title 'Description of the defined enum value'
|
|
||||||
option section 'schema.enum'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Enum value dependencies (schema.@enum.depends)
|
|
||||||
config variable
|
|
||||||
option name 'depends'
|
|
||||||
option title 'List of dependencies on defined variables'
|
|
||||||
option section 'schema.enum'
|
|
||||||
option type 'lazylist'
|
|
||||||
option datatype 'string'
|
|
||||||
option required false
|
|
||||||
|
|
||||||
# Enum value default flag (schema.@enum.default)
|
|
||||||
config variable
|
|
||||||
option name 'default'
|
|
||||||
option title 'Specify whether this value is the default value of the parent enum'
|
|
||||||
option section 'schema.enum'
|
|
||||||
option type 'variable'
|
|
||||||
option datatype 'boolean'
|
|
||||||
option required false
|
|
|
@ -1,241 +0,0 @@
|
||||||
#!/usr/bin/lua
|
|
||||||
--[[
|
|
||||||
|
|
||||||
UCI Validation Layer - Command Line Utility
|
|
||||||
(c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
|
||||||
(c) 2008 Steven Barth <steven@midlink.org>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
|
|
||||||
]]--
|
|
||||||
|
|
||||||
require("luci.uvl")
|
|
||||||
require("luci.util")
|
|
||||||
|
|
||||||
|
|
||||||
function getopt( arg, options )
|
|
||||||
options = options or ""
|
|
||||||
local tab = {}
|
|
||||||
local args = {}
|
|
||||||
for k, v in ipairs(arg) do
|
|
||||||
if v:sub(1, 2) == "--" then
|
|
||||||
local x = v:find( "=", 1, true )
|
|
||||||
if x then
|
|
||||||
tab[ v:sub( 3, x-1 ) ] = v:sub( x+1 )
|
|
||||||
else
|
|
||||||
tab[ v:sub( 3 ) ] = true
|
|
||||||
end
|
|
||||||
elseif v:sub( 1, 1 ) == "-" then
|
|
||||||
local y = 2
|
|
||||||
local l = #v
|
|
||||||
local jopt
|
|
||||||
while ( y <= l ) do
|
|
||||||
jopt = v:sub( y, y )
|
|
||||||
if options:find( jopt, 1, true ) then
|
|
||||||
if y < l then
|
|
||||||
tab[ jopt ] = v:sub( y+1 )
|
|
||||||
y = l
|
|
||||||
else
|
|
||||||
tab[ jopt ] = arg[ k + 1 ]
|
|
||||||
arg[ k + 1 ] = ""
|
|
||||||
end
|
|
||||||
else
|
|
||||||
tab[ jopt ] = true
|
|
||||||
end
|
|
||||||
y = y + 1
|
|
||||||
end
|
|
||||||
elseif #v > 0 then
|
|
||||||
table.insert(args, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return tab, args
|
|
||||||
end
|
|
||||||
|
|
||||||
function genspec(conf)
|
|
||||||
require("luci.model.uci")
|
|
||||||
require("luci.uvl.datatypes")
|
|
||||||
|
|
||||||
local uci = luci.model.uci.cursor()
|
|
||||||
local ok, err = uci:load(conf)
|
|
||||||
|
|
||||||
if not ok then
|
|
||||||
print("Can not load config:", err)
|
|
||||||
os.exit(1)
|
|
||||||
else
|
|
||||||
local function _guess_datatype(v)
|
|
||||||
if type(v) == "table" then v = v[1] end
|
|
||||||
|
|
||||||
for _, type in ipairs({
|
|
||||||
"boolean", "integer", "float", "ip4addr", "ip6addr",
|
|
||||||
"macaddr", "directory", "file"
|
|
||||||
}) do
|
|
||||||
if luci.uvl.datatypes[type](v) then
|
|
||||||
return type
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return "string"
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local co = uci:get_all(conf)
|
|
||||||
local ct = { }
|
|
||||||
local ca = { }
|
|
||||||
local so = { }
|
|
||||||
local to = { }
|
|
||||||
|
|
||||||
-- count section types
|
|
||||||
for _, section in pairs(co) do
|
|
||||||
ct[section['.type']] = ( ct[section['.type']] or 0 ) + 1
|
|
||||||
ca[section['.type']] = section['.anonymous']
|
|
||||||
so[section['.type']] = so[section['.type']] or { }
|
|
||||||
to[section['.type']] = to[section['.type']] or { }
|
|
||||||
|
|
||||||
for option, value in pairs(section) do
|
|
||||||
if option:sub(1,1) ~= "." then
|
|
||||||
so[section['.type']][option] = _guess_datatype(value)
|
|
||||||
to[section['.type']][option] = ( type(value) == "table" and "list" or "variable" )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- package name
|
|
||||||
print( "package %s" % conf )
|
|
||||||
|
|
||||||
-- write section schemes
|
|
||||||
for type, count in luci.util.kspairs(ct) do
|
|
||||||
print( "\nconfig section" )
|
|
||||||
print( "\toption name '%s'" % type )
|
|
||||||
print( "\toption title 'Section %s'" % type )
|
|
||||||
print( "\toption package '%s'"% conf )
|
|
||||||
print( "\toption named %s" % ( ca[type] and 'false' or 'true' ) )
|
|
||||||
print( "\toption unique %s" % ( ct[type] > 1 and 'false' or ( ca[type] and 'false' or 'true' ) ) )
|
|
||||||
print( "\toption dynamic false" )
|
|
||||||
print( "\toption required false" )
|
|
||||||
|
|
||||||
-- write option schemes
|
|
||||||
for opt, val in luci.util.kspairs(so[type]) do
|
|
||||||
print( "\nconfig variable" )
|
|
||||||
print( "\toption name '%s'" % opt )
|
|
||||||
print( "\toption title 'Option %s'" % opt )
|
|
||||||
print( "\toption section '%s.%s'" %{ conf, type } )
|
|
||||||
print( "\toption datatype '%s'" % so[type][opt] )
|
|
||||||
|
|
||||||
if to[type][opt] ~= "variable" then
|
|
||||||
print( "\toption type '%s'" % to[type][opt] )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
print("")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local options, arguments = getopt( arg )
|
|
||||||
|
|
||||||
if #arguments ~= 2 or options.help then
|
|
||||||
print([=[
|
|
||||||
|
|
||||||
uvl - UCI Validation Layer
|
|
||||||
$Id$
|
|
||||||
(c) 2008 Jo-Philipp Wich, Steven Barth
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
uvl --help
|
|
||||||
uvl [--silent] [--schemedir=DIR] [--configdir=DIR] [--no-strict-sections] \
|
|
||||||
[--no-strict-options] [--no-strict-validators] [--no-strict-lists] \
|
|
||||||
{verify|verify-scheme|genspec} config[.section[.option]]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--help
|
|
||||||
Display this help message.
|
|
||||||
|
|
||||||
--silent
|
|
||||||
Don't produce any output.
|
|
||||||
|
|
||||||
--schemedir=DIR
|
|
||||||
Use DIR as scheme directory.
|
|
||||||
|
|
||||||
--configdir=DIR
|
|
||||||
Use DIR as config directory.
|
|
||||||
|
|
||||||
--no-strict-sections
|
|
||||||
Don't treat sections found in config but not in scheme as error.
|
|
||||||
|
|
||||||
--no-strict-options
|
|
||||||
Don't treat options found in config but not in scheme as error.
|
|
||||||
|
|
||||||
--no-strict-validators
|
|
||||||
Don't invalidate config if an external validator fails.
|
|
||||||
|
|
||||||
--no-strict-lists
|
|
||||||
Don't invalidate lists that are stored options.
|
|
||||||
|
|
||||||
Actions:
|
|
||||||
verify
|
|
||||||
Validate given configuration, section or option.
|
|
||||||
|
|
||||||
verify-scheme
|
|
||||||
Validate given scheme against the reference meta scheme.
|
|
||||||
|
|
||||||
genspec
|
|
||||||
Generate a scheme skeleton from given configuration.
|
|
||||||
]=])
|
|
||||||
os.exit(255)
|
|
||||||
elseif arguments[1] == "verify" or arguments[1] == "verify-scheme" then
|
|
||||||
luci.uvl.STRICT_UNKNOWN_SECTIONS =
|
|
||||||
( not options['no-strict-sections'] and true or false )
|
|
||||||
luci.uvl.STRICT_UNKNOWN_OPTIONS =
|
|
||||||
( not options['no-strict-options'] and true or false )
|
|
||||||
luci.uvl.STRICT_EXTERNAL_VALIDATORS =
|
|
||||||
( not options['no-strict-validators'] and true or false )
|
|
||||||
luci.uvl.STRICT_LIST_TYPE =
|
|
||||||
( not options['no-strict-lists'] and true or false )
|
|
||||||
|
|
||||||
local uvl = luci.uvl.UVL(
|
|
||||||
type(options.schemedir) == "string" and options.schemedir,
|
|
||||||
type(options.configdir) == "string" and options.configdir
|
|
||||||
)
|
|
||||||
|
|
||||||
local cso = luci.util.split( arguments[2], "." )
|
|
||||||
local ok, err
|
|
||||||
|
|
||||||
if arguments[1] == "verify-scheme" then
|
|
||||||
uvl:read_scheme( 'schema', cso[1] )
|
|
||||||
|
|
||||||
local uci = uvl.uci.cursor(
|
|
||||||
type(options.configdir) == "string"
|
|
||||||
and options.configdir or uvl.schemedir .. '/default'
|
|
||||||
)
|
|
||||||
|
|
||||||
ok, err = uvl:validate_config( cso[1], uci:get_all(cso[1]) )
|
|
||||||
if err then err.code = luci.uvl.errors.ERR_SCHEME end
|
|
||||||
else
|
|
||||||
ok, err = uvl:validate( unpack(cso) )
|
|
||||||
end
|
|
||||||
|
|
||||||
if ok then
|
|
||||||
if not options.silent then
|
|
||||||
print( string.format(
|
|
||||||
'%s "%s" validates fine!',
|
|
||||||
( arguments[1] == "verify-scheme" and "Scheme" or
|
|
||||||
( #cso == 1 and "Config" or
|
|
||||||
( #cso == 2 and "Section" or "Option" ) ) ),
|
|
||||||
table.concat(cso, ".")
|
|
||||||
) )
|
|
||||||
end
|
|
||||||
os.exit( 0 )
|
|
||||||
else
|
|
||||||
if not options.silent then print( err and err:string() or "Unknown error" ) end
|
|
||||||
os.exit( 1 )
|
|
||||||
end
|
|
||||||
else
|
|
||||||
genspec( arguments[2] )
|
|
||||||
end
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/usr/bin/lua
|
|
||||||
|
|
||||||
if arg[1] then
|
|
||||||
require("luci.util")
|
|
||||||
require("luci.uvl")
|
|
||||||
require("nixio.fs")
|
|
||||||
|
|
||||||
local uvl = luci.uvl.UVL()
|
|
||||||
local scheme, err = uvl:get_scheme( arg[1] )
|
|
||||||
|
|
||||||
if scheme then
|
|
||||||
nixio.fs.writefile(
|
|
||||||
"%s/bytecode/%s.lua" %{ uvl.schemedir, arg[1] },
|
|
||||||
luci.util.get_bytecode(scheme)
|
|
||||||
)
|
|
||||||
elseif err then
|
|
||||||
print("Error:", err:string())
|
|
||||||
else
|
|
||||||
print("Error: Can not find scheme:", arg[1])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
print( "Usage: uvlc <scheme>" )
|
|
||||||
end
|
|
|
@ -1,2 +0,0 @@
|
||||||
include ../../build/config.mk
|
|
||||||
include ../../build/module.mk
|
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
<div id="copy">
|
|
||||||
<hr />
|
|
||||||
generated on <%=require "os".date("%c")%> with <a href="http://luci.freifunk-halle.net"><abbr title="Lua Configuration Interface">LuCI</abbr> UVLDoc</a> - written by Steven Barth and Jo-Philipp Wich
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="clear"> </div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" type="text/css" href="uvldoc.css" />
|
|
||||||
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
|
|
||||||
<title><% if title then %><%=title%> - <% end %>LuCI UVLDoc</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div id="menu">
|
|
||||||
<%+menu.xml%>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="content">
|
|
|
@ -1,12 +0,0 @@
|
||||||
<%+header.xml%>
|
|
||||||
<h1 class="index-title">UCI Documentation</h1>
|
|
||||||
<h3 class="index-subtitle">Schemes</h3>
|
|
||||||
<table class="index">
|
|
||||||
<% for k, v in luci.util.kspairs(self.schemes) do %>
|
|
||||||
<tr>
|
|
||||||
<th><a href="<%=self:_scheme_filename(k)%>"><%=k%></a></th>
|
|
||||||
<td><%=self.schemes[k].title%></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</table>
|
|
||||||
<%+footer.xml%>
|
|
|
@ -1,22 +0,0 @@
|
||||||
<div class="menu-title">LuCI UVLDoc</div>
|
|
||||||
<ul class="menu-index">
|
|
||||||
<li<%-if not scheme then%> class="menu-active"<%-end-%>>
|
|
||||||
<a href="<%=self:_index_filename()%>">Index</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="menu-title">Schemes</div>
|
|
||||||
<ul class="menu-index">
|
|
||||||
<% for k, v in luci.util.kspairs(self.schemes) do %>
|
|
||||||
<li<%-if scheme == k then%> class="menu-active"<%-end-%>>
|
|
||||||
<a href="<%=self:_scheme_filename(k)%>"><%=k%></a>
|
|
||||||
<%-if scheme == k then-%>
|
|
||||||
<ul>
|
|
||||||
<%-for k2, v2 in luci.util.kspairs(v.sections) do%>
|
|
||||||
<li<%-if k2 == section then%> class="menu-active"<%-end-%>><a href="<%=self:_section_filename(k, k2)%>"><%=k2%></a></li>
|
|
||||||
<%end-%>
|
|
||||||
</ul>
|
|
||||||
<%-end%>
|
|
||||||
</li>
|
|
||||||
<%-end%>
|
|
||||||
</ul>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<%- title = scheme -%>
|
|
||||||
<%+header.xml%>
|
|
||||||
<h1 class="section-title"><%=scheme-%>
|
|
||||||
<%-if package.title then%><dfn> - <%=package.title%></dfn><%end%></h1>
|
|
||||||
<div class="scheme-description"><%=package.description%></div>
|
|
||||||
|
|
||||||
<h3 class="scheme-title">Sections:</h3>
|
|
||||||
<table class="scheme-index">
|
|
||||||
<% for k, v in luci.util.kspairs(package.sections) do %>
|
|
||||||
<tr>
|
|
||||||
<th><a href="<%=self:_section_filename(scheme, k)%>"><%=k%></a></th>
|
|
||||||
<td><%=v.title%></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</table>
|
|
||||||
<%+footer.xml%>
|
|
|
@ -1,198 +0,0 @@
|
||||||
<%- title = scheme .. "." .. type -%>
|
|
||||||
<%+header.xml%>
|
|
||||||
<%
|
|
||||||
local table = require "table"
|
|
||||||
|
|
||||||
types = {
|
|
||||||
list = "List",
|
|
||||||
variable = "Variable",
|
|
||||||
lazylist = "Mixed",
|
|
||||||
enum = "Enumerator",
|
|
||||||
reference = "Reference"
|
|
||||||
}
|
|
||||||
|
|
||||||
datatypes = {
|
|
||||||
boolean = "Boolean",
|
|
||||||
string = "String",
|
|
||||||
uint = "Unsigned Integer",
|
|
||||||
integer = "Integer",
|
|
||||||
float = "Real Number",
|
|
||||||
ipaddr = "IP-Address",
|
|
||||||
ip4addr = "IPv4-Address",
|
|
||||||
ip6addr = "IPv6-Address",
|
|
||||||
ip4prefix = "IPv4-Prefix",
|
|
||||||
ip6prefix = "IPv6-Prefix",
|
|
||||||
hostname = "Hostname",
|
|
||||||
host = "Host (Hostname or IP-Address)",
|
|
||||||
directory = "Filesystem path (to directory)",
|
|
||||||
file = "Filesystem path (to file)",
|
|
||||||
macaddr = "MAC-Address",
|
|
||||||
port = "Port",
|
|
||||||
portrange = "Single Port or Portrange (First-Last)"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _parse_ref( r )
|
|
||||||
local k, v, h = r:match("([^.]+)%.([^.]+)%.([^.]+)")
|
|
||||||
if not k then
|
|
||||||
k, v = r:match("([^.]+)%.([^.]+)")
|
|
||||||
end
|
|
||||||
if k then
|
|
||||||
if h then
|
|
||||||
return self:_variable_target(k, v, h), true
|
|
||||||
else
|
|
||||||
return self:_section_filename(k, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function _parse_dep( r, c, s, o )
|
|
||||||
local ref = { }
|
|
||||||
local vars = {
|
|
||||||
config = c,
|
|
||||||
section = s,
|
|
||||||
option = o
|
|
||||||
}
|
|
||||||
|
|
||||||
for v in r:gmatch("[^.]+") do
|
|
||||||
ref[#ref+1] = (v:gsub( "%$(.+)", vars ))
|
|
||||||
end
|
|
||||||
|
|
||||||
if #ref < 2 then
|
|
||||||
table.insert(ref, 1, s or '$section')
|
|
||||||
end
|
|
||||||
if #ref < 3 then
|
|
||||||
table.insert(ref, 1, c or '$config')
|
|
||||||
end
|
|
||||||
|
|
||||||
return self:_variable_target(unpack(ref))
|
|
||||||
end
|
|
||||||
|
|
||||||
%>
|
|
||||||
<a name="top"></a>
|
|
||||||
<h1 class="section-title"><%=scheme-%>
|
|
||||||
<%-if package.title then%><dfn> - <%=package.title%></dfn><%end%></h1>
|
|
||||||
<h2 class="section-subtitle"><%=type-%>
|
|
||||||
<%-if section.title then%><dfn> - <%=section.title%></dfn><%end%></h2>
|
|
||||||
<div class="section-description"><%=section.description%></div>
|
|
||||||
|
|
||||||
<h3 class="section-attributes">Attributes:</h3>
|
|
||||||
<ul class="section-attributes-index">
|
|
||||||
<%-
|
|
||||||
if section.required then %>
|
|
||||||
<li class="section-attributes-required">required: <dfn>A section of this type is required.</dfn></li>
|
|
||||||
<% end
|
|
||||||
if section.unique then %>
|
|
||||||
<li class="section-attributes-unique">unique: <dfn>There can be only one section of this type.</dfn></li>
|
|
||||||
<%- else -%>
|
|
||||||
<li class="section-attributes-multiple">multiple: <dfn>There can be more than one section of this type.</dfn></li>
|
|
||||||
<% end
|
|
||||||
if section.dynamic then %>
|
|
||||||
<li class="section-attributes-dynamic">dynamic: <dfn>Sections of this type may contain user-defined options.</dfn></li>
|
|
||||||
<% end
|
|
||||||
if section.named then %>
|
|
||||||
<li class="section-attributes-named">named: <dfn>Sections of this type require a name.</dfn></li>
|
|
||||||
<% end -%>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<% if section.depends then %>
|
|
||||||
<h3 class="section-depends">Requirements (one of):</h3>
|
|
||||||
<ul class="section-depends-index">
|
|
||||||
<% for i, d in ipairs(section.depends) do
|
|
||||||
local nf = false%>
|
|
||||||
<li>
|
|
||||||
<% for k2, v in luci.util.kspairs(d) do
|
|
||||||
local t = _parse_dep(k2, scheme, type)
|
|
||||||
%>
|
|
||||||
<% if nf then %>and<% end %>
|
|
||||||
<%if t then%><a href="<%=t%>"><%end%><%=k2%><%if t then%></a><%end%><%if v~=true then%>=<%=v%><%end%>
|
|
||||||
<% nf = true
|
|
||||||
end %>
|
|
||||||
</li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<h3 class="section-variables">Variable Overview:</h3>
|
|
||||||
<table class="section-variables-index">
|
|
||||||
<% for k, v in luci.util.kspairs(package.variables[type]) do
|
|
||||||
if v.required then%>
|
|
||||||
<tr class="section-variable-required">
|
|
||||||
<th><a href="#variable.<%=k%>"><%=k%></a></th>
|
|
||||||
<td><%=v.title%></td>
|
|
||||||
</tr>
|
|
||||||
<% end end
|
|
||||||
for k, v in luci.util.kspairs(package.variables[type]) do
|
|
||||||
if not v.required then%>
|
|
||||||
<tr class="section-variable-mixed">
|
|
||||||
<th><a href="#variable.<%=k%>"><%=k%></a></th>
|
|
||||||
<td><%=v.title%></td>
|
|
||||||
</tr>
|
|
||||||
<% end end %>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3 class="section-variables">Options:</h3>
|
|
||||||
<%-
|
|
||||||
for i=0, 1 do
|
|
||||||
for k, v in luci.util.kspairs(package.variables[type]) do
|
|
||||||
if (i==0) == v.required then
|
|
||||||
%>
|
|
||||||
<hr />
|
|
||||||
<div class="variable-documentation">
|
|
||||||
<a name="variable.<%=k%>"></a>
|
|
||||||
<h4 class="variable-title"><%=k-%>
|
|
||||||
<%-if v.title then%><dfn> - <%=v.title%></dfn><%end%></h4>
|
|
||||||
<div class="variable-declaration">
|
|
||||||
<div class="variable-description"><%=v.description%></div>
|
|
||||||
<h5 class="variable-attributes">Attributes:</h5>
|
|
||||||
<ul class="varaible-attributes-index">
|
|
||||||
<% if v.required then %>
|
|
||||||
<li class="variable-attribute-required"><strong>required</strong></li>
|
|
||||||
<% end %>
|
|
||||||
<li class="variable-attribute-type"><strong>Type:</strong> <%=types[v.type] or v.type%></li>
|
|
||||||
<li class="variable-attribute-datatype"><strong>Datatype:</strong> <%=datatypes[v.datatype] or v.datatype%></li>
|
|
||||||
<% if v.multival then %>
|
|
||||||
<li class="variable-attribute-multiple"><strong>multiple values:</strong> space-separated</li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% if v.depends then %>
|
|
||||||
<h5 class="variable-depends">Dependencies (one of):</h5>
|
|
||||||
<ul class="variable-depends-index">
|
|
||||||
<% for i, d in ipairs(v.depends) do
|
|
||||||
local nf = false %>
|
|
||||||
<li>
|
|
||||||
<% for k2, v in luci.util.kspairs(d) do
|
|
||||||
local t = _parse_dep(k2, scheme, type, k)
|
|
||||||
%>
|
|
||||||
<% if nf then %>and<% end %>
|
|
||||||
<%if t then%><a href="<%=t%>"><%end%><%=k2%><%if t then%></a><%end%><%if v~=true then%>=<%=v%><%end%>
|
|
||||||
<% nf = true
|
|
||||||
end %>
|
|
||||||
</li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% end %>
|
|
||||||
<% if v.type == "enum" then %>
|
|
||||||
<h5 class="variable-values">Possible Values:</h5>
|
|
||||||
<ul class="variable-values-index">
|
|
||||||
<% for k, d in pairs(v.values) do %>
|
|
||||||
<li><strong><%=k%></strong><%if d then%> (<%=d%>)<%end%></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% elseif v.type == "reference" then %>
|
|
||||||
<h5 class="variable-reference">Value references:</h5>
|
|
||||||
<ul class="variable-reference-index">
|
|
||||||
<% for k, d in ipairs(v.valueof) do %>
|
|
||||||
<li>
|
|
||||||
<% local t, x = _parse_ref(d)
|
|
||||||
if t then %><%=x and "Value of" or "Section of type"%> <a href="<%=t%>"><% end %>
|
|
||||||
<%=d%>
|
|
||||||
<% if t then%></a><% end %>
|
|
||||||
</li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<a href="#top">⇑</a>
|
|
||||||
</div>
|
|
||||||
<% end end end -%>
|
|
||||||
<%+footer.xml%>
|
|
|
@ -1,135 +0,0 @@
|
||||||
body {
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 0.85em;
|
|
||||||
color: #101010;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 1.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
font-size: 1.0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
dfn {
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr, td, th {
|
|
||||||
border: 1px solid #e0e0ff;
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background-color: #f0f0ff;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hr {
|
|
||||||
border: none;
|
|
||||||
background-color: #cccccc;
|
|
||||||
height: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul, li {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.clear {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.variable-declaration {
|
|
||||||
padding-left: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.variable-description {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3.section-variables {
|
|
||||||
margin-top: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4.variable-title {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#menu {
|
|
||||||
float: left;
|
|
||||||
background-color: #f0f0ff;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 1px solid #e0e0ff;
|
|
||||||
width: 11.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#menu ul {
|
|
||||||
list-style-type: none;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
#menu ul li {
|
|
||||||
margin-left: 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
div.menu-title {
|
|
||||||
background-color: #e0e0ff;
|
|
||||||
color: #000000;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#content {
|
|
||||||
margin-top: 0;
|
|
||||||
padding-top: 0;
|
|
||||||
margin-left: 12.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#copy {
|
|
||||||
margin-top: 2.5em;
|
|
||||||
font-size: 0.7em;
|
|
||||||
text-align: center;
|
|
||||||
font-size: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:link {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #004080;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:visited {
|
|
||||||
font-weight:bold;
|
|
||||||
color: #006699;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
text-decoration:underline;
|
|
||||||
}
|
|
|
@ -1,124 +0,0 @@
|
||||||
--[[
|
|
||||||
LuCI - Lua Configuration Interface
|
|
||||||
|
|
||||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
|
||||||
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
]]--
|
|
||||||
|
|
||||||
local io = require "io"
|
|
||||||
local fs = require "nixio.fs"
|
|
||||||
local uvl = require "luci.uvl"
|
|
||||||
local util = require "luci.util"
|
|
||||||
local ltn12 = require "luci.ltn12"
|
|
||||||
local template = require "luci.template"
|
|
||||||
|
|
||||||
local ipairs, getfenv, pairs, require, unpack = ipairs, getfenv, pairs, require, unpack
|
|
||||||
local luci = luci
|
|
||||||
|
|
||||||
module "luci.uvldoc.renderer"
|
|
||||||
|
|
||||||
|
|
||||||
Generator = util.class()
|
|
||||||
|
|
||||||
function Generator.__init__(self, schemes, output, uvlpath)
|
|
||||||
self.names = schemes
|
|
||||||
self.output = output or "doc"
|
|
||||||
self.schemes = {}
|
|
||||||
self.uvl = uvl.UVL(uvlpath)
|
|
||||||
|
|
||||||
self.extension = ".xml"
|
|
||||||
self.additionals = {"uvldoc.css"}
|
|
||||||
self.sourcedir = util.libpath() .. "/uvldoc/proto/xhtml/"
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function Generator.make(self)
|
|
||||||
for i, scheme in ipairs(self.names) do
|
|
||||||
self.schemes[scheme] = self.uvl:get_scheme(scheme)
|
|
||||||
end
|
|
||||||
|
|
||||||
fs.mkdir(self.output)
|
|
||||||
|
|
||||||
for i, file in ipairs(self.additionals) do
|
|
||||||
fs.datacopy(self.sourcedir .. file, self.output .. "/" .. file)
|
|
||||||
end
|
|
||||||
|
|
||||||
template.compiler_mode = "memory"
|
|
||||||
template.viewdir = self.sourcedir
|
|
||||||
template.context.viewns = {
|
|
||||||
include = function(name) template.Template(name):render(getfenv(2)) end,
|
|
||||||
pairs = pairs,
|
|
||||||
ipairs = ipairs,
|
|
||||||
unpack = unpack,
|
|
||||||
luci = luci,
|
|
||||||
require = require
|
|
||||||
}
|
|
||||||
|
|
||||||
self:_make_index()
|
|
||||||
|
|
||||||
for scheme, package in pairs(self.schemes) do
|
|
||||||
self:_make_package(scheme)
|
|
||||||
for type, section in pairs(package.sections) do
|
|
||||||
self:_make_section(scheme, type)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Generator._make_index(self)
|
|
||||||
local t = template.Template("index.xml")
|
|
||||||
local sink = ltn12.sink.file(
|
|
||||||
io.open(self.output .. "/" .. self:_index_filename(), "w")
|
|
||||||
)
|
|
||||||
t:render({self = self, write = sink})
|
|
||||||
sink()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Generator._make_package(self, scheme)
|
|
||||||
local t = template.Template("scheme.xml")
|
|
||||||
local sink = ltn12.sink.file(
|
|
||||||
io.open(self.output .. "/" .. self:_scheme_filename(scheme), "w")
|
|
||||||
)
|
|
||||||
t:render({self = self, package = self.schemes[scheme], scheme = scheme, write = sink})
|
|
||||||
sink()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Generator._make_section(self, scheme, section)
|
|
||||||
local t = template.Template("section.xml")
|
|
||||||
local sink = ltn12.sink.file(
|
|
||||||
io.open(self.output .. "/" .. self:_section_filename(scheme, section), "w")
|
|
||||||
)
|
|
||||||
local pkg = self.schemes[scheme]
|
|
||||||
t:render({self = self, package = pkg,
|
|
||||||
scheme = scheme, type=section, section=pkg.sections[section],
|
|
||||||
write = sink})
|
|
||||||
sink()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Generator._index_filename(self)
|
|
||||||
return "index%s" % self.extension
|
|
||||||
end
|
|
||||||
|
|
||||||
function Generator._scheme_filename(self, scheme)
|
|
||||||
return "scheme.%s%s" % {scheme, self.extension}
|
|
||||||
end
|
|
||||||
|
|
||||||
function Generator._section_filename(self, scheme, section)
|
|
||||||
if self.schemes[scheme] and self.schemes[scheme].sections[section] then
|
|
||||||
return "section.%s.%s%s" % {scheme, section, self.extension}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Generator._variable_target(self, scheme, section, variable)
|
|
||||||
if self.schemes[scheme] and self.schemes[scheme].variables[section] and
|
|
||||||
self.schemes[scheme].variables[section][variable] then
|
|
||||||
return "section.%s.%s%s#variable.%s" % {scheme, section, self.extension, variable}
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in a new issue