X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=libs%2Fcore%2Fluasrc%2Futil.lua;h=51d66e08e5a34b1a6e3423742ae636c637f79a0d;hp=3f65a80fba6452ad5ae827bad866c6cddb3c14eb;hb=2b0e8c6d7fc72c5c4d090dd3311c341f280e2237;hpb=714d72296147941029a72b63524ad199ae08c737 diff --git a/libs/core/luasrc/util.lua b/libs/core/luasrc/util.lua index 3f65a80fb..51d66e08e 100644 --- a/libs/core/luasrc/util.lua +++ b/libs/core/luasrc/util.lua @@ -320,7 +320,7 @@ end --- Combines two or more numerically indexed tables into one. -- @param tbl1 Table value to combine -- @param tbl2 Table value to combine --- @param tblN More values to combine +-- @param ... More tables to combine -- @return Table value containing all values of given tables function combine(...) local result = {} @@ -375,27 +375,27 @@ function clone(object, deep) return copy end --- Test whether the given table value is a numerically indexed table. -function _is_numeric_table(t) - local k = pairs(t)(t) - return ( tonumber(k) ~= nil ) + +--- Create a dynamic table which automatically creates subtables. +-- @return Dynamic Table +function dtable() + return setmetatable({}, { __index = + function(tbl, key) + return rawget(tbl, key) + or rawget(rawset(tbl, key, dtable()), key) + end + }) end + -- Serialize the contents of a table value. function _serialize_table(t) local data = "" - if _is_numeric_table(t) then - for i, v in ipairs(t) do - v = serialize_data(v) - data = data .. ( #data > 0 and ", " or "" ) .. v - end - else - for k, v in pairs(t) do - k = serialize_data(k) - v = serialize_data(v) - data = data .. ( #data > 0 and "; " or "" ) .. - '[' .. k .. '] = ' .. v - end + for k, v in pairs(t) do + k = serialize_data(k) + v = serialize_data(v) + data = data .. ( #data > 0 and ", " or "" ) .. + '[' .. k .. '] = ' .. v end return data end @@ -410,13 +410,13 @@ function serialize_data(val) if val == nil then return "nil" elseif type(val) == "number" then - return tostring(val) + return val elseif type(val) == "string" then - val = val:gsub("\\", "\\\\") - :gsub("\r", "\\r") - :gsub("\n", "\\n") - :gsub('"','\\"') - return '"' .. val .. '"' + return string.format("%q", val) + elseif type(val) == "boolean" then + return val and "true" or "false" + elseif type(val) == "function" then + return string.format("loadstring(%q)", get_bytecode(val)) elseif type(val) == "table" then return "{ " .. _serialize_table(val) .. " }" else @@ -439,16 +439,19 @@ end -- --- Return the current runtime bytecode of the given data. The byte code --- will be stripped before it is returned if the given value is a function. +-- will be stripped before it is returned. -- @param val Value to return as bytecode -- @return String value containing the bytecode of the given data function get_bytecode(val) + local code + if type(val) == "function" then - local code = string.dump(val) - return code and strip_bytecode(code) + code = string.dump(val) else - return string.dump( loadstring( "return " .. serialize_data(val) ) ) + code = string.dump( loadstring( "return " .. serialize_data(val) ) ) end + + return code and strip_bytecode(code) end --- Strips unnescessary lua bytecode from given string. Information like line @@ -571,10 +574,89 @@ end -- +-- System utility functions +-- + +--- Test whether the current system is operating in big endian mode. +-- @return Boolean value indicating whether system is big endian +function bigendian() + return string.byte(string.dump(function() end), 7) == 0 +end + +--- Execute given commandline and gather stdout. +-- @param command String containing command to execute +-- @return String containing the command's stdout +function exec(command) + local pp = io.popen(command) + local data = pp:read("*a") + pp:close() + + return data +end + +--- Return a line-buffered iterator over the output of given command. +-- @param command String containing the command to execute +-- @return Iterator +function execi(command) + local pp = io.popen(command) + + return pp and function() + local line = pp:read() + + if not line then + pp:close() + end + + return line + end +end + +-- Deprecated +function execl(command) + local pp = io.popen(command) + local line = "" + local data = {} + + while true do + line = pp:read() + if (line == nil) then break end + table.insert(data, line) + end + pp:close() + + return data +end + +--- Returns the absolute path to LuCI base directory. +-- @return String containing the directory path +function libpath() + return luci.fs.dirname(require("luci.debug").__file__) +end + + +-- -- Coroutine safe xpcall and pcall versions modified for Luci -- original version: -- coxpcall 1.13 - Copyright 2005 - Kepler Project (www.keplerproject.org) -- +-- Copyright © 2005 Kepler Project. +-- Permission is hereby granted, free of charge, to any person obtaining a +-- copy of this software and associated documentation files (the "Software"), +-- to deal in the Software without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Software, and to permit persons to whom the +-- Software is furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be +-- included in all copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +-- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +-- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local performResume, handleReturnValue local oldpcall, oldxpcall = pcall, xpcall