libs/core: improve luci.util.imatch() to not create temporary strings when iterating...
authorJo-Philipp Wich <jow@openwrt.org>
Tue, 26 Jun 2012 22:58:24 +0000 (22:58 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Tue, 26 Jun 2012 22:58:24 +0000 (22:58 +0000)
libs/core/luasrc/util.lua

index 7856d11..bde803f 100644 (file)
@@ -36,7 +36,7 @@ local tparser = require "luci.template.parser"
 local getmetatable, setmetatable = getmetatable, setmetatable
 local rawget, rawset, unpack = rawget, rawset, unpack
 local tostring, type, assert = tostring, type, assert
 local getmetatable, setmetatable = getmetatable, setmetatable
 local rawget, rawset, unpack = rawget, rawset, unpack
 local tostring, type, assert = tostring, type, assert
-local ipairs, pairs, loadstring = ipairs, pairs, loadstring
+local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
 local require, pcall, xpcall = require, pcall, xpcall
 local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
 
 local require, pcall, xpcall = require, pcall, xpcall
 local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
 
@@ -273,15 +273,27 @@ end
 -- @param val          The value to scan (table, string or nil)
 -- @return                     Iterator which returns one token per call
 function imatch(v)
 -- @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)
+       if type(v) == "table" then
+               local k = nil
+               return function()
+                       k = next(v, k)
+                       return v[k]
+               end
+
+       elseif type(v) == "number" or type(v) == "boolean" then
+               local x = true
+               return function()
+                       if x then
+                               x = false
+                               return tostring(v)
+                       end
+               end
+
+       elseif type(v) == "userdata" or type(v) == "string" then
+               return tostring(v):gmatch("%S+")
        end
 
        end
 
-       return v:gmatch("%S+")
+       return function() end
 end
 
 --- Parse certain units from the given string and return the canonical integer
 end
 
 --- Parse certain units from the given string and return the canonical integer