diff options
| author | ruki <[email protected]> | 2018-12-05 22:49:24 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2018-12-05 10:56:25 +0800 |
| commit | b7e17b562985e6854ddcf67c5524da9c5d045875 (patch) | |
| tree | c048e2309c86cebe234b9d42dc6db830f707c036 /xmake/core/base/table.lua | |
| parent | 824a61bb67014f10313b2f872b039fc47b51e5db (diff) | |
serialize table and function
Diffstat (limited to 'xmake/core/base/table.lua')
| -rw-r--r-- | xmake/core/base/table.lua | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua index 3de4be277..6b600ad1e 100644 --- a/xmake/core/base/table.lua +++ b/xmake/core/base/table.lua @@ -26,10 +26,12 @@ local table = table or {} -- make string with the level -function table._makestr(self, deflate, level) - if type(self) == "string" or type(self) == "boolean" or type(self) == "number" then +function table._makestr(self, deflate, serialize, level) + if type(self) == "string" then + return serialize and string.format("%q", self) or self + elseif type(self) == "boolean" or type(self) == "number" then return tostring(self) - elseif type(self) == "table" and (getmetatable(self) or {}).__tostring then + elseif not serialize and type(self) == "table" and (getmetatable(self) or {}).__tostring then return tostring(self) elseif type(self) == "table" then @@ -64,13 +66,20 @@ function table._makestr(self, deflate, level) -- make key = value if type(k) == "string" then + if serialize then + k = string.format("[%q]", k) + end if deflate then s = s .. k .. "=" else s = s .. k .. " = " end end - s = s .. table._makestr(v, deflate, level + 1) + local substr, errors = table._makestr(v, deflate, serialize, level + 1) + if substr == nil then + return nil, errors + end + s = s .. substr if not deflate then s = s .. "\n" @@ -86,6 +95,10 @@ function table._makestr(self, deflate, level) end s = s .. "}" return s + elseif serialize and type(self) == "function" then + return string.format("%q", string.dump(self)) + elseif serialize then + return nil, "cannot serialize object: " .. type(self) elseif self ~= nil then return "<" .. tostring(self) .. ">" else @@ -93,6 +106,24 @@ function table._makestr(self, deflate, level) end end +-- load table from string in table +function table._loadstr(self) + -- only load luajit function data: e.g. "\27LJ\2\0\6=stdin" + if type(self) == "string" and self:startswith("\27LJ") then + return loadstring(self) + elseif type(self) == "table" then + for k, v in pairs(self) do + local value, errors = table._loadstr(v) + if value ~= nil then + self[k] = value + else + return nil, errors + end + end + end + return self +end + -- clear the table function table.clear(self) for k in next, self do @@ -259,13 +290,57 @@ function table.is_dictionary(dict) end -- dump table -function table.dump(self, deflate) - io.write(table.makestr(self, deflate)) +function table.dump(self, deflate, serialize) + local str = table.makestr(self, deflate, serialize) + if str then + io.write(str) + end end -- make string from the given table -function table.makestr(self, deflate) - return table._makestr(self, deflate, 0) +-- +-- @param deflate deflate empty characters +-- @param serialize make string which can be deserialized, we can use table.loadstr to load it +-- +-- @return string, errors +-- +function table.makestr(self, deflate, serialize) + return table._makestr(self, deflate, serialize, 0) +end + +-- load table from the serialized string +-- +-- @param str the serialized string +-- +-- @return table, errors +-- +function table.loadstr(str) + + -- load table as script + local result = nil + local script, errors = loadstring("return " .. str) + if script then + + -- load object + local ok, object = pcall(script) + if ok and object then + result = object + elseif object then + -- error + errors = object + else + -- error + errors = string.format("cannot deserialize string: %s", str) + end + end + + -- load function from string in table + if result then + result, errors = table._loadstr(result) + end + + -- ok? + return result, errors end -- unwrap object if be only one |
