|
@@ -1,160 +1,168 @@
|
|
|
function in_site(var)
|
|
|
- return var
|
|
|
+ return var
|
|
|
end
|
|
|
|
|
|
function in_domain(var)
|
|
|
- return var
|
|
|
+ return var
|
|
|
end
|
|
|
|
|
|
|
|
|
-local function loadvar(varname)
|
|
|
- local ok, val = pcall(assert(loadstring('return site.' .. varname)))
|
|
|
- if ok then
|
|
|
- return val
|
|
|
- else
|
|
|
- return nil
|
|
|
- end
|
|
|
+local function path_to_string(path)
|
|
|
+ return table.concat(path, '/')
|
|
|
end
|
|
|
|
|
|
local function array_to_string(array)
|
|
|
- local string = ''
|
|
|
- for _, v in ipairs(array) do
|
|
|
- if #string >= 1 then
|
|
|
- string = string .. ', '
|
|
|
- end
|
|
|
- string = string .. v
|
|
|
- end
|
|
|
- return '[' .. string .. ']'
|
|
|
+ return '[' .. table.concat(array, ', ') .. ']'
|
|
|
end
|
|
|
|
|
|
-local function assert_one_of(var, array, msg)
|
|
|
- for _, v in ipairs(array) do
|
|
|
- if v == var then
|
|
|
- return true
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- error(msg)
|
|
|
+local function var_error(path, val, msg)
|
|
|
+ print(string.format('*** site.conf error: expected %s to %s, but it is %s', path_to_string(path), msg, tostring(val)))
|
|
|
+ os.exit(1)
|
|
|
end
|
|
|
|
|
|
-local function assert_type(var, t, msg)
|
|
|
- assert(type(var) == t, msg)
|
|
|
-end
|
|
|
|
|
|
+function extend(path, c)
|
|
|
+ local p = {unpack(path)}
|
|
|
|
|
|
-function assert_uci_name(var)
|
|
|
- -- We don't use character classes like %w here to be independent of the locale
|
|
|
- assert(var:match('^[0-9a-zA-Z_]+$'), "site.conf error: `" .. var .. "' is not a valid config section name (only alphanumeric characters and the underscore are allowed)")
|
|
|
+ for _, e in ipairs(c) do
|
|
|
+ p[#p+1] = e
|
|
|
+ end
|
|
|
+ return p
|
|
|
end
|
|
|
|
|
|
+local function loadpath(path, base, c, ...)
|
|
|
+ if not c or base == nil then
|
|
|
+ return base
|
|
|
+ end
|
|
|
|
|
|
-function need_string(varname, required)
|
|
|
- local var = loadvar(varname)
|
|
|
+ if type(base) ~= 'table' then
|
|
|
+ var_error(path, base, 'be a table')
|
|
|
+ end
|
|
|
|
|
|
- if required == false and var == nil then
|
|
|
- return nil
|
|
|
- end
|
|
|
-
|
|
|
- assert_type(var, 'string', "site.conf error: expected `" .. varname .. "' to be a string")
|
|
|
- return var
|
|
|
+ return loadpath(extend(path, {c}), base[c], ...)
|
|
|
end
|
|
|
|
|
|
-function need_string_match(varname, pat, required)
|
|
|
- local var = need_string(varname, required)
|
|
|
-
|
|
|
- if not var then
|
|
|
- return nil
|
|
|
- end
|
|
|
-
|
|
|
- assert(var:match(pat), "site.conf error: expected `" .. varname .. "' to match pattern `" .. pat .. "'")
|
|
|
+local function loadvar(path)
|
|
|
+ return loadpath({}, site, unpack(path))
|
|
|
+end
|
|
|
|
|
|
- return var
|
|
|
+local function check_type(t)
|
|
|
+ return function(val)
|
|
|
+ return type(val) == t
|
|
|
+ end
|
|
|
end
|
|
|
|
|
|
-function need_number(varname, required)
|
|
|
- local var = loadvar(varname)
|
|
|
+local function check_one_of(array)
|
|
|
+ return function(val)
|
|
|
+ for _, v in ipairs(array) do
|
|
|
+ if v == val then
|
|
|
+ return true
|
|
|
+ end
|
|
|
+ end
|
|
|
+ return false
|
|
|
+ end
|
|
|
+end
|
|
|
|
|
|
- if required == false and var == nil then
|
|
|
- return nil
|
|
|
- end
|
|
|
+function need(path, check, required, msg)
|
|
|
+ local val = loadvar(path)
|
|
|
+ if required == false and val == nil then
|
|
|
+ return nil
|
|
|
+ end
|
|
|
|
|
|
- assert_type(var, 'number', "site.conf error: expected `" .. varname .. "' to be a number")
|
|
|
+ if not check(val) then
|
|
|
+ var_error(path, val, msg)
|
|
|
+ end
|
|
|
|
|
|
- return var
|
|
|
+ return val
|
|
|
end
|
|
|
|
|
|
-function need_boolean(varname, required)
|
|
|
- local var = loadvar(varname)
|
|
|
-
|
|
|
- if required == false and var == nil then
|
|
|
- return nil
|
|
|
- end
|
|
|
+local function need_type(path, type, required, msg)
|
|
|
+ return need(path, check_type(type), required, msg)
|
|
|
+end
|
|
|
|
|
|
- assert_type(var, 'boolean', "site.conf error: expected `" .. varname .. "' to be a boolean")
|
|
|
|
|
|
- return var
|
|
|
+function need_alphanumeric_key(path)
|
|
|
+ local val = path[#path]
|
|
|
+ -- We don't use character classes like %w here to be independent of the locale
|
|
|
+ if not val:match('^[0-9a-zA-Z_]+$') then
|
|
|
+ var_error(path, val, 'have a key using only alphanumeric characters and underscores')
|
|
|
+ end
|
|
|
end
|
|
|
|
|
|
-function need_array(varname, subcheck, required)
|
|
|
- local var = loadvar(varname)
|
|
|
|
|
|
- if required == false and var == nil then
|
|
|
- return nil
|
|
|
- end
|
|
|
+function need_string(path, required)
|
|
|
+ return need_type(path, 'string', required, 'be a string')
|
|
|
+end
|
|
|
|
|
|
- assert_type(var, 'table', "site.conf error: expected `" .. varname .. "' to be an array")
|
|
|
+function need_string_match(path, pat, required)
|
|
|
+ local val = need_string(path, required)
|
|
|
+ if not val then
|
|
|
+ return nil
|
|
|
+ end
|
|
|
|
|
|
- for _, e in ipairs(var) do
|
|
|
- subcheck(e)
|
|
|
- end
|
|
|
+ if not val:match(pat) then
|
|
|
+ var_error(path, val, "match pattern '" .. pat .. "'")
|
|
|
+ end
|
|
|
|
|
|
- return var
|
|
|
+ return val
|
|
|
end
|
|
|
|
|
|
-function need_table(varname, subcheck, required)
|
|
|
- local var = loadvar(varname)
|
|
|
+function need_number(path, required)
|
|
|
+ return need_type(path, 'number', required, 'be a number')
|
|
|
+end
|
|
|
|
|
|
- if required == false and var == nil then
|
|
|
- return nil
|
|
|
- end
|
|
|
+function need_boolean(path, required)
|
|
|
+ return need_type(path, 'boolean', required, 'be a boolean')
|
|
|
+end
|
|
|
|
|
|
- assert_type(var, 'table', "site.conf error: expected `" .. varname .. "' to be a table")
|
|
|
+function need_array(path, subcheck, required)
|
|
|
+ local val = need_type(path, 'table', required, 'be an array')
|
|
|
+ if not val then
|
|
|
+ return nil
|
|
|
+ end
|
|
|
|
|
|
- if subcheck then
|
|
|
- for k, v in pairs(var) do
|
|
|
- subcheck(k, v)
|
|
|
- end
|
|
|
- end
|
|
|
+ if subcheck then
|
|
|
+ for i = 1, #val do
|
|
|
+ subcheck(extend(path, {i}))
|
|
|
+ end
|
|
|
+ end
|
|
|
|
|
|
- return var
|
|
|
+ return val
|
|
|
end
|
|
|
|
|
|
-function need_one_of(varname, array, required)
|
|
|
- local var = loadvar(varname)
|
|
|
+function need_table(path, subcheck, required)
|
|
|
+ local val = need_type(path, 'table', required, 'be a table')
|
|
|
+ if not val then
|
|
|
+ return nil
|
|
|
+ end
|
|
|
|
|
|
- if required == false and var == nil then
|
|
|
- return nil
|
|
|
- end
|
|
|
+ if subcheck then
|
|
|
+ for k, _ in pairs(val) do
|
|
|
+ subcheck(extend(path, {k}))
|
|
|
+ end
|
|
|
+ end
|
|
|
|
|
|
- assert_one_of(var, array, "site.conf error: expected `" .. varname .. "' to be one of given array: " .. array_to_string(array))
|
|
|
+ return val
|
|
|
+end
|
|
|
+
|
|
|
+function need_value(path, value, required)
|
|
|
+ return need(path, function(v)
|
|
|
+ return v == value
|
|
|
+ end, required, 'be ' .. tostring(value))
|
|
|
+end
|
|
|
|
|
|
- return var
|
|
|
+function need_one_of(path, array, required)
|
|
|
+ return need(path, check_one_of(array), required, 'be one of the given array ' .. array_to_string(array))
|
|
|
end
|
|
|
|
|
|
-function need_string_array(varname, required)
|
|
|
- local ok, var = pcall(need_array, varname, function(e) assert_type(e, 'string') end, required)
|
|
|
- assert(ok, "site.conf error: expected `" .. varname .. "' to be a string array")
|
|
|
- return var
|
|
|
+function need_string_array(path, required)
|
|
|
+ return need_array(path, need_string, required)
|
|
|
end
|
|
|
|
|
|
-function need_string_array_match(varname, pat, required)
|
|
|
- local ok, var = pcall(need_array, varname, function(e) assert(e:match(pat)) end, required)
|
|
|
- assert(ok, "site.conf error: expected `" .. varname .. "' to be a string array matching pattern `" .. pat .. "'")
|
|
|
- return var
|
|
|
+function need_string_array_match(path, pat, required)
|
|
|
+ return need_array(path, function(e) need_string_match(e, pat) end, required)
|
|
|
end
|
|
|
|
|
|
-function need_array_of(varname, array, required)
|
|
|
- local ok, var = pcall(need_array, varname, function(e) assert_one_of(e, array) end,required)
|
|
|
- assert(ok, "site.conf error: expected `" .. varname .. "' to be a subset of given array: " .. array_to_string(array))
|
|
|
- return var
|
|
|
+function need_array_of(path, array, required)
|
|
|
+ return need_array(path, function(e) need_one_of(e, array) end, required)
|
|
|
end
|