local function loadvar(varname) local ok, val = pcall(assert(loadstring('return site.' .. varname))) if ok then return val else return nil end 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 .. ']' 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) end local function assert_type(var, t, msg) assert(type(var) == t, msg) end 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)") end function need_string(varname, required) local var = loadvar(varname) 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 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 .. "'") return var end function need_number(varname, required) local var = loadvar(varname) if required == false and var == nil then return nil end assert_type(var, 'number', "site.conf error: expected `" .. varname .. "' to be a number") return var end function need_boolean(varname, required) local var = loadvar(varname) if required == false and var == nil then return nil end assert_type(var, 'boolean', "site.conf error: expected `" .. varname .. "' to be a boolean") return var end function need_array(varname, subcheck, required) local var = loadvar(varname) if required == false and var == nil then return nil end assert_type(var, 'table', "site.conf error: expected `" .. varname .. "' to be an array") for _, e in ipairs(var) do subcheck(e) end return var end function need_table(varname, subcheck, required) local var = loadvar(varname) if required == false and var == nil then return nil end assert_type(var, 'table', "site.conf error: expected `" .. varname .. "' to be a table") if subcheck then for k, v in pairs(var) do subcheck(k, v) end end return var end function need_one_of(varname, array, required) local var = loadvar(varname) if required == false and var == nil then return nil end assert_one_of(var, array, "site.conf error: expected `" .. varname .. "' to be one of given array: " .. array_to_string(array)) return var 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 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 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 end