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