diff options
| author | ruki <[email protected]> | 2018-12-05 23:23:59 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2018-12-05 14:23:57 +0800 |
| commit | 212e85ed60305fa8c3e74261835ecaa32f881232 (patch) | |
| tree | fd08ae45a2fcdf6bfd4aad6abf8e0f9c46ef67eb /xmake/core/base/string.lua | |
| parent | b7e17b562985e6854ddcf67c5524da9c5d045875 (diff) | |
move table.makestr to string.serialize
Diffstat (limited to 'xmake/core/base/string.lua')
| -rw-r--r-- | xmake/core/base/string.lua | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/xmake/core/base/string.lua b/xmake/core/base/string.lua index abf92e945..c5fe9ef28 100644 --- a/xmake/core/base/string.lua +++ b/xmake/core/base/string.lua @@ -25,6 +25,108 @@ -- define module: string local string = string or {} +-- save original interfaces +string._dump = string._dump or string.dump + +-- make string with the level +function string._makestr(object, deflate, serialize, level) + if type(object) == "string" then + return serialize and string.format("%q", object) or object + elseif type(object) == "boolean" or type(object) == "number" then + return tostring(object) + elseif not serialize and type(object) == "table" and (getmetatable(object) or {}).__tostring then + return tostring(object) + elseif type(object) == "table" then + + -- make head + local s = "" + if deflate then + s = s .. "{" + else + s = s .. "\n" + for l = 1, level do + s = s .. " " + end + s = s .. "{\n" + end + + -- make body + local i = 0 + for k, v in pairs(object) do + + if deflate then + s = s .. (i ~= 0 and "," or "") + else + for l = 1, level do + s = s .. " " + end + if i == 0 then + s = s .. " " + else + s = s .. ", " + end + end + + -- 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 + local substr, errors = string._makestr(v, deflate, serialize, level + 1) + if substr == nil then + return nil, errors + end + s = s .. substr + + if not deflate then + s = s .. "\n" + end + i = i + 1 + end + + -- make tail + if not deflate then + for l = 1, level do + s = s .. " " + end + end + s = s .. "}" + return s + elseif serialize and type(object) == "function" then + return string.format("%q", string._dump(object)) + elseif serialize then + return nil, "cannot serialize object: " .. type(object) + elseif object ~= nil then + return "<" .. tostring(object) .. ">" + else + return "nil" + end +end + +-- load table from string in table +function string._loadstr(object) + -- only load luajit function data: e.g. "\27LJ\2\0\6=stdin" + if type(object) == "string" and object:startswith("\27LJ") then + return loadstring(object) + elseif type(object) == "table" then + for k, v in pairs(object) do + local value, errors = string._loadstr(v) + if value ~= nil then + object[k] = value + else + return nil, errors + end + end + end + return object +end + -- find the last substring with the given pattern function string:find_last(pattern, plain) @@ -211,5 +313,60 @@ function string.ipattern(pattern, brackets) return table.concat(tmp) end +-- dump to string from the given object (more readable) +-- +-- @param deflate deflate empty characters +-- +-- @return string, errors +-- +function string.dump(object, deflate) + return string._makestr(object, deflate, false, 0) +end + +-- serialize to string from the given object +-- +-- @param deflate deflate empty characters +-- +-- @return string, errors +-- +function string.serialize(object, deflate) + return string._makestr(object, deflate, true, 0) +end + +-- deserialize string to object +-- +-- @param str the serialized string +-- +-- @return object, errors +-- +function string:deserialize() + + -- load table as script + local result = nil + local script, errors = loadstring("return " .. self) + 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", self) + end + end + + -- load function from string in table + if result then + result, errors = string._loadstr(result) + end + + -- ok? + return result, errors +end + -- return module: string return string |
