Moved luci.sys.exec, luci.sys.execl and luci.sys.bigendian to luci.util
[project/luci.git] / libs / core / luasrc / util.lua
index 3f65a80fba6452ad5ae827bad866c6cddb3c14eb..2f6cfad4c21a8f1e06e01a0343be4b9111946029 100644 (file)
@@ -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
@@ -570,6 +573,45 @@ function vspairs(t)
 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
+
+--- Execute given commandline and gather stdout.
+-- @param command      String containing the command to execute
+-- @return                     Table containing the command's stdout splitted up in lines
+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
+
 --
 -- Coroutine safe xpcall and pcall versions modified for Luci
 -- original version: