X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=libs%2Fcore%2Fluasrc%2Futil.lua;h=7856d11629cb452255dfda184621689c67892713;hb=8ee6d915ee10fed7ad229cfd143d7b446cb18480;hp=94b5ce67f10343c3ebd9321edca592074906a71f;hpb=a4f6748205c6afd17811c9548aaae6b17476e6d8;p=project%2Fluci.git diff --git a/libs/core/luasrc/util.lua b/libs/core/luasrc/util.lua index 94b5ce67f..7856d1162 100644 --- a/libs/core/luasrc/util.lua +++ b/libs/core/luasrc/util.lua @@ -31,6 +31,7 @@ local debug = require "debug" local ldebug = require "luci.debug" local string = require "string" local coroutine = require "coroutine" +local tparser = require "luci.template.parser" local getmetatable, setmetatable = getmetatable, setmetatable local rawget, rawset, unpack = rawget, rawset, unpack @@ -49,8 +50,10 @@ getmetatable("").__mod = function(a, b) if not b then return a elseif type(b) == "table" then + for k, _ in pairs(b) do if type(b[k]) == "userdata" then b[k] = tostring(b[k]) end end return a:format(unpack(b)) else + if type(b) == "userdata" then b = tostring(b) end return a:format(b) end end @@ -114,19 +117,16 @@ end -- Scope manipulation routines -- ---- Create a new or get an already existing thread local store associated with --- the current active coroutine. A thread local store is private a table object --- whose values can't be accessed from outside of the running coroutine. --- @return Table value representing the corresponding thread local store -function threadlocal() - local tbl = {} +local tl_meta = { + __mode = "k", - local function get(self, key) - local t = rawget(self, coxpt[coroutine.running()] or coroutine.running() or 0) + __index = function(self, key) + local t = rawget(self, coxpt[coroutine.running()] + or coroutine.running() or 0) return t and t[key] - end + end, - local function set(self, key, value) + __newindex = function(self, key, value) local c = coxpt[coroutine.running()] or coroutine.running() or 0 if not rawget(self, c) then rawset(self, c, { [key] = value }) @@ -134,10 +134,14 @@ function threadlocal() rawget(self, c)[key] = value end end +} - setmetatable(tbl, {__index = get, __newindex = set, __mode = "k"}) - - return tbl +--- Create a new or get an already existing thread local store associated with +-- the current active coroutine. A thread local store is private a table object +-- whose values can't be accessed from outside of the running coroutine. +-- @return Table value representing the corresponding thread local store +function threadlocal(tbl) + return setmetatable(tbl or {}, tl_meta) end @@ -190,32 +194,15 @@ end --- Create valid XML PCDATA from given string. -- @param value String value containing the data to escape -- @return String value containing the escaped data -local function _pcdata_repl(c) - local i = string.byte(c) - - if ( i >= 0x00 and i <= 0x08 ) or ( i >= 0x0B and i <= 0x0C ) or - ( i >= 0x0E and i <= 0x1F ) or ( i == 0x7F ) - then - return "" - - elseif ( i == 0x26 ) or ( i == 0x27 ) or ( i == 0x22 ) or - ( i == 0x3C ) or ( i == 0x3E ) - then - return string.format("&#%i;", i) - end - - return c -end - function pcdata(value) - return value and tostring(value):gsub("[&\"'<>%c]", _pcdata_repl) + return value and tparser.sanitize_pcdata(tostring(value)) end --- Strip HTML tags from given string. -- @param value String containing the HTML text -- @return String with HTML tags stripped of function striptags(s) - return pcdata(s:gsub("]*>", " "):gsub("%s+", " ")) + return pcdata(tostring(s):gsub("]*>", " "):gsub("%s+", " ")) end --- Splits given string on a defined separator sequence and return a table @@ -279,6 +266,24 @@ function cmatch(str, pat) return count end +--- Return a matching iterator for the given value. The iterator will return +-- one token per invocation, the tokens are separated by whitespace. If the +-- input value is a table, it is transformed into a string first. A nil value +-- will result in a valid interator which aborts with the first invocation. +-- @param val The value to scan (table, string or nil) +-- @return Iterator which returns one token per call +function imatch(v) + if v == nil then + v = "" + elseif type(v) == "table" then + v = table.concat(v, " ") + elseif type(v) ~= "string" then + v = tostring(v) + end + + return v:gmatch("%S+") +end + --- Parse certain units from the given string and return the canonical integer -- value or 0 if the unit is unknown. Upper- or lower case is irrelevant. -- Recognized units are: @@ -522,7 +527,7 @@ function get_bytecode(val) code = string.dump( loadstring( "return " .. serialize_data(val) ) ) end - return code and strip_bytecode(code) + return code -- and strip_bytecode(code) end --- Strips unnescessary lua bytecode from given string. Information like line @@ -772,20 +777,15 @@ function handleReturnValue(err, co, status, ...) if not status then return false, err(debug.traceback(co, (...)), ...) end - if coroutine.status(co) == 'suspended' then - return performResume(err, co, coroutine.yield(...)) - else + + if coroutine.status(co) ~= 'suspended' then return true, ... end + + return performResume(err, co, coroutine.yield(...)) end -- Resume execution of protected function call function performResume(err, co, ...) - if get_memory_limit and get_memory_limit() > 0 and - collectgarbage("count") > (get_memory_limit() * 0.8) - then - collectgarbage("collect") - end - return handleReturnValue(err, co, coroutine.resume(co, ...)) end