require("hook")
local hook = hook
/*---------------------------------------------------------
utilx module
Useful and common functions
---------------------------------------------------------*/
module("utilx")
function KeyValuesToTable( kv, internal )
-- Expected:
-- * "name" "value"
-- * name value
-- * //
-- * { ... }
-- * whitespace
local ST_NAME = 0
local ST_VALUE = 1
local ST_VALUE_OR_CHILD = 2
local ST_CHILD = 3
local name = nil
local value = nil
local current_pos = 1
local current_contents = kv
local state = ST_NAME
local result = {}
local first_name = nil
while (true) do
local c = string.sub(current_contents, current_pos, current_pos)
current_pos = current_pos + 1
if (c == "") then
break
elseif (string.byte(c,1) <= 32) then
-- continue (do nothing)
elseif (c == "/" and string.sub(current_contents, current_pos, current_pos) == "/") then
-- scan till EOL
while (c != "\n") do
c = string.sub(current_contents, current_pos, current_pos)
current_pos = current_pos + 1
if (c == "") then
break
end
end
elseif (c == "}") then
break
elseif (c == "{") then
state = ST_CHILD
local inc_pos = 0
result[name],inc_pos = KeyValuesToTable( string.sub(current_contents, current_pos), true )
current_pos = current_pos + inc_pos
state = ST_NAME
elseif (c != "" or c == "\"") then
if (state == ST_VALUE_OR_CHILD) then state = ST_VALUE end
local quoted = (c == "\"")
local thing = ""
if (not quoted) then
thing = c
end
while (true) do
c = string.sub(current_contents, current_pos, current_pos)
current_pos = current_pos + 1
if (quoted) then
if (c == "\\") then
c = string.sub(current_contents, current_pos, current_pos)
current_pos = current_pos + 1
if (c == "n") then c = "\n"
elseif (c == "r") then c = "\r"
elseif (c == "t") then c = "\t"
elseif (c == "\"") then c = "\""
elseif (c == "\\") then c = "\\"
else c = ""
end
elseif (c == "\"") then
break
end
else
if (string.byte(c,1) <= 32) then
break
end
end
thing = thing .. c
end
current_pos = current_pos + 1
if tonumber(thing) then thing = tonumber(thing) end
if (state == ST_NAME) then
name = thing
if (first_name == nil) then
first_name = name
end
state = ST_VALUE_OR_CHILD
elseif (state == ST_VALUE) then
value = thing
result[name] = value
state = ST_NAME
end
end
end
if (not internal) then
return result[first_name], first_name
else
return result, current_pos
end
end
function TableToKeyValues( val, key, level )
local tabs = level or 0
// Return a string so that it doesn't bug out later
if ( tabs > 8 ) then return "" end
if ( type( val ) != "table" ) then return "" end
local name = key or "Out"
local str
str = string.rep("\t", tabs) .. "\""..name.."\"\n"
str = str .. string.rep("\t", tabs) .. "{\n"
for k,v in pairs(val) do
k = stringx.Replace(k, "\\", "\\\\")
k = stringx.Replace(k, "\"", "\\\"")
k = stringx.Replace(k, "\t", "\\t")
k = stringx.Replace(k, "\n", "\\n")
k = stringx.Replace(k, "\r", "\\r")
if ( type( v ) == "table" ) then
str = str .. TableToKeyValues(v,k,tabs+1)
else
v = stringx.Replace(v, "\\", "\\\\")
v = stringx.Replace(v, "\"", "\\\"")
v = stringx.Replace(v, "\t", "\\t")
v = stringx.Replace(v, "\n", "\\r")
v = stringx.Replace(v, "\r", "\\n")
str = str .. string.rep("\t", tabs+1) .. "\""..k.."\"\t\""..v.."\"\n"
end
end
str = str .. string.rep("\t", tabs) .. "}\n"
return str
end