module "luci.uvl"
-local ERR = require "luci.uvl.errors"
+local ERR = require "luci.uvl.errors".error
local datatypes = require "luci.uvl.datatypes"
local validation = require "luci.uvl.validation"
local dependencies = require "luci.uvl.dependencies"
for k, v in pairs(co:config()) do
local so = co:section(k)
if not self.beenthere[so:cid()] then
- co:error(ERR.SECT_UNKNOWN(so))
+ co:error(ERR('SECT_UNKNOWN', so))
end
end
end
for _, k in ipairs(util.keys(sc)) do
local so = co:section(k)
if so:scheme('required') and sc[k] == 0 then
- co:error(ERR.SECT_REQUIRED(so))
+ co:error(ERR('SECT_REQUIRED', so))
elseif so:scheme('unique') and sc[k] > 1 then
- co:error(ERR.SECT_UNIQUE(so))
+ co:error(ERR('SECT_UNIQUE', so))
end
end
if so:config() then
return self:_validate_section( so )
else
- return false, ERR.SECT_NOTFOUND(so)
+ return false, ERR('SECT_NOTFOUND', so)
end
end
if so:config() and oo:config() then
return self:_validate_option( oo )
else
- return false, ERR.OPT_NOTFOUND(oo)
+ return false, ERR('OPT_NOTFOUND', oo)
end
end
if section:scheme('named') == true and
section:config('.anonymous') == true
then
- return false, ERR.SECT_NAMED(section)
+ return false, ERR('SECT_NAMED', section)
end
for _, v in ipairs(section:variables()) do
local ok, err = self:_validate_option( v )
if not ok and (
v:scheme('required') or v:scheme('type') == "enum" or (
- not err:is(ERR.ERR_DEP_NOTEQUAL) and
- not err:is(ERR.ERR_DEP_NOVALUE)
+ not err:is('DEP_NOTEQUAL') and
+ not err:is('DEP_NOVALUE')
)
) then
section:error(err)
section:error(err)
end
else
- return false, ERR.SECT_NOTFOUND(section)
+ return false, ERR('SECT_NOTFOUND', section)
end
if STRICT_UNKNOWN_OPTIONS and not section:scheme('dynamic') then
for k, v in pairs(section:config()) do
local oo = section:option(k)
if k:byte(1) == 46 and not self.beenthere[oo:cid()] then
- section:error(ERR.OPT_UNKNOWN(oo))
+ section:error(ERR('OPT_UNKNOWN', oo))
end
end
end
if not option:scheme() and not option:parent():scheme('dynamic') then
if STRICT_UNKNOWN_OPTIONS then
- return false, option:error(ERR.OPT_UNKNOWN(option))
+ return false, option:error(ERR('OPT_UNKNOWN', option))
else
return true
end
local ok, err = dependencies.check( self, option )
if not ok then
if not err:is_all(
- ERR.ERR_OPT_REQUIRED,
- ERR.ERR_DEP_NOTEQUAL,
- ERR.ERR_DEP_NOVALUE
+ 'OPT_REQUIRED',
+ 'DEP_NOTEQUAL',
+ 'DEP_NOVALUE'
) then
option:error(err)
return false, option:errors()
end
if option:scheme('required') and not option:value() then
- return false, option:error(ERR.OPT_REQUIRED(option))
+ return false, option:error(ERR('OPT_REQUIRED', option))
elseif option:value() then
local val = option:value()
local config_values = ( type(val) == "table" and val or { val } )
for _, v in ipairs(config_values) do
if not scheme_values[v] then
- return false, option:error( ERR.OPT_BADVALUE(
+ return false, option:error( ERR(
+ 'OPT_BADVALUE',
option, { v, util.serialize_data(
util.keys(scheme_values)
) }
end
elseif option:scheme('type') == "list" then
if type(val) ~= "table" and STRICT_LIST_TYPE then
- return false, option:error(ERR.OPT_NOTLIST(option))
+ return false, option:error(ERR('OPT_NOTLIST', option))
end
end
for i, v in ipairs(val) do
if not self.datatypes[dt]( v ) then
return false, option:error(
- ERR.OPT_INVVALUE(option, { v, dt })
+ ERR('OPT_INVVALUE', option, { v, dt })
)
end
end
else
- return false, option:error(ERR.OPT_DATATYPE(option, dt))
+ return false, option:error(ERR('OPT_DATATYPE', option, dt))
end
end
for _, v in ipairs(val) do
if option:scheme('minlength') then
if #v < option:scheme('minlength') then
- return false, option:error(ERR.OPT_RANGE(option))
+ return false, option:error(ERR('OPT_RANGE', option))
end
end
if option:scheme('maxlength') then
if #v > option:scheme('maxlength') then
- return false, option:error(ERR.OPT_RANGE(option))
+ return false, option:error(ERR('OPT_RANGE', option))
end
end
if option:scheme('minimum') then
if not w or w < option:scheme('minimum') then
- return false, option:error(ERR.OPT_RANGE(option))
+ return false, option:error(ERR('OPT_RANGE', option))
end
end
if option:scheme('maximum') then
if not w or w > option:scheme('maximum') then
- return false, option:error(ERR.OPT_RANGE(option))
+ return false, option:error(ERR('OPT_RANGE', option))
end
end
end
local ok, err
for _, file in ipairs(files) do
if not fs.access(file) then
- return false, so:error(ERR.SME_READ(so,file))
+ return false, so:error(ERR('SME_READ', so,file))
end
local uci = uci.cursor( fs.dirname(file), default_savedir )
local sd, err = uci:load( sname )
if not sd then
- return false, ERR.UCILOAD(so, err)
+ return false, ERR('UCILOAD', so, err)
end
ok, err = pcall(function()
if ok and alias then self.packages[alias] = self.packages[shm] end
return ok and self, err
else
- return false, so:error(ERR.SME_FIND(so, self.schemedir))
+ return false, so:error(ERR('SME_FIND', so, self.schemedir))
end
else
local sc = loadfile(bc)
self.packages[shm] = sc()
return true
else
- return false, so:error(ERR.SME_READ(so,bc))
+ return false, so:error(ERR('SME_READ',so,bc))
end
end
end
o = enum( scheme, nil, p, '(nil)', '(nil)', n )
end
- return false, ERR.SME_REQFLD(o,v)
+ return false, ERR('SME_REQFLD',o,v)
end
end
return true
r[1] = ( #r[1] > 0 and r[1] or scheme:sid() )
if #r ~= n then
- return false, ERR.SME_BADREF(scheme, k)
+ return false, ERR('SME_BADREF', scheme, k)
end
return r
s.depends = self:_read_dependency( v2, s.depends )
if not s.depends then
return false, scheme:error(
- ERR.SME_BADDEP(so, util.serialize_data(s.depends))
+ ERR('SME_BADDEP', so, util.serialize_data(s.depends))
)
end
elseif k == "dynamic" or k == "unique" or
local p = self.packages[r[1]]
if not p then
error(scheme:error(
- ERR.SME_VBADPACK({scheme:sid(), '', v.name}, r[1])
+ ERR('SME_VBADPACK', {scheme:sid(), '', v.name}, r[1])
))
end
local s = p.variables[r[2]]
if not s then
error(scheme:error(
- ERR.SME_VBADSECT({scheme:sid(), '', v.name}, r[2])
+ ERR('SME_VBADSECT', {scheme:sid(), '', v.name}, r[2])
))
end
t.depends = self:_read_dependency( v2, t.depends )
if not t.depends then
error(scheme:error(so:error(
- ERR.SME_BADDEP(to, util.serialize_data(v2))
+ ERR('SME_BADDEP', to, util.serialize_data(v2))
)))
end
elseif k == "validator" then
t.validators = self:_read_validator( v2, t.validators )
if not t.validators then
error(scheme:error(so:error(
- ERR.SME_BADVAL(to, util.serialize_data(v2))
+ ERR('SME_BADVAL', to, util.serialize_data(v2))
)))
end
elseif k == "valueof" then
local values, err = self:_read_reference( v2 )
if err then
error(scheme:error(so:error(
- ERR.REFERENCE(to, util.serialize_data(v2)):child(err)
+ ERR('REFERENCE', to, util.serialize_data(v2)):child(err)
)))
end
t.type = "reference"
local p = self.packages[r[1]]
if not p then
error(scheme:error(
- ERR.SME_EBADPACK({scheme:sid(), '', '', v.value}, r[1])
+ ERR('SME_EBADPACK', {scheme:sid(), '', '', v.value}, r[1])
))
end
local s = p.variables[r[2]]
if not s then
error(scheme:error(
- ERR.SME_EBADSECT({scheme:sid(), '', '', v.value}, r[2])
+ ERR('SME_EBADSECT', {scheme:sid(), '', '', v.value}, r[2])
))
end
local t = s[r[3]]
if not t then
error(scheme:error(
- ERR.SME_EBADOPT({scheme:sid(), '', '', v.value}, r[3])
+ ERR('SME_EBADOPT', {scheme:sid(), '', '', v.value}, r[3])
))
end
local eo = oo:enum(v.value)
if t.type ~= "enum" and t.type ~= "reference" then
- error(scheme:error(ERR.SME_EBADTYPE(eo)))
+ error(scheme:error(ERR('SME_EBADTYPE', eo)))
end
if not t.values then
if v.default then
if t.default then
- error(scheme:error(ERR.SME_EBADDEF(eo)))
+ error(scheme:error(ERR('SME_EBADDEF', eo)))
end
t.default = v.value
end
if not t.enum_depends[v.value] then
error(scheme:error(so:error(oo:error(
- ERR.SME_BADDEP(eo, util.serialize_data(v.depends))
+ ERR('SME_BADDEP', eo, util.serialize_data(v.depends))
))))
end
end
if v['.type'] == ref[2] then
if #ref == 2 then
if v['.anonymous'] == true then
- return false, ERR.SME_INVREF('', value)
+ return false, ERR('SME_INVREF', '', value)
end
val[k] = k -- XXX: title/description would be nice
elseif v[ref[3]] then
end
end
else
- return false, ERR.SME_BADREF('', value)
+ return false, ERR('SME_BADREF', '', value)
end
end
function uvlitem.error(self, arg1, arg2, arg3, arg4, arg5)
if not self.e then
- local errconst = { ERR.CONFIG, ERR.SECTION, ERR.OPTION, ERR.OPTION }
- self.e = errconst[#self.cref]( self )
+ local errconst = { 'CONFIG', 'SECTION', 'OPTION', 'OPTION' }
+ self.e = ERR( errconst[#self.cref], self )
end
return self.e:child( arg1, arg2, arg3, arg4, arg5 )
co, err = uci.cursor(configdir):get_all(c)
if err then
- self:error(ERR.UCILOAD(self, err))
+ self:error(ERR('UCILOAD', self, err))
end
self._configcache = co
--- Add an error to scheme.
-- @return Scheme error context
function scheme.error(self, arg1, arg2, arg3, arg4, arg5)
- if not self.e then self.e = ERR.SCHEME( self ) end
+ if not self.e then self.e = ERR( 'SCHEME', self ) end
return self.e:child( arg1, arg2, arg3, arg4, arg5 )
end
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' }
+ 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'
}
--- build error constants and instance constructors
-for i, v in ipairs(ERRCODES) do
- _M[v[1]] = function(...)
- return error(i, ...)
- end
-
- _M['ERR_'..v[1]] = i
-end
-
-
function i18n(key, def)
if luci.i18n then
return luci.i18n.translate(key,def)
pad = pad or " "
local str = i18n(
- 'uvl_err_%s' % string.lower(ERRCODES[self.code][1]),
- ERRCODES[self.code][2]
+ 'uvl_err_%s' % string.lower(self.code),
+ ERRCODES[self.code]
)
:gsub("\n", "\n"..pad)
:gsub("%%i", self:cid())