mirror of
https://github.com/joe7575/techpack.git
synced 2024-12-01 19:43:52 +01:00
SaferLua Controller: Lua error messages output improved
This commit is contained in:
parent
42ea101b15
commit
c0b30d88b9
@ -1,6 +1,21 @@
|
|||||||
# Release Notes for ModPack TechPack [techpack]
|
# Release Notes for ModPack TechPack [techpack]
|
||||||
|
|
||||||
|
|
||||||
|
## V2.00.03 (2019-01-19)
|
||||||
|
|
||||||
|
### Additions
|
||||||
|
|
||||||
|
### Removals
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- SaferLua-Controller: Lua error messages output improved
|
||||||
|
- SmartLine Display: row 0 can be used to set the infotext
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## V2.00.02 (2019-01-15)
|
## V2.00.02 (2019-01-15)
|
||||||
|
|
||||||
### Additions
|
### Additions
|
||||||
|
@ -12,10 +12,9 @@
|
|||||||
|
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
safer_lua.MaxCodeSize = 2000 -- size in length of byte code
|
safer_lua.MaxCodeSize = 5000 -- size if source code in bytes
|
||||||
safer_lua.MaxTableSize = 1000 -- sum over all table sizes
|
safer_lua.MaxTableSize = 1000 -- sum over all table sizes
|
||||||
|
|
||||||
|
|
||||||
local function memsize()
|
local function memsize()
|
||||||
return safer_lua.MaxTableSize
|
return safer_lua.MaxTableSize
|
||||||
end
|
end
|
||||||
@ -60,14 +59,31 @@ function safer_lua.config(max_code_size, max_table_size)
|
|||||||
safer_lua.MaxTableSize = max_table_size
|
safer_lua.MaxTableSize = max_table_size
|
||||||
end
|
end
|
||||||
|
|
||||||
local function format_error(err, tab)
|
local function format_error_str(str, label)
|
||||||
|
local tbl = {}
|
||||||
|
for s in str:gmatch("[^\r\n]+") do
|
||||||
|
s = s:match("^%s*(.-)%s*$")
|
||||||
|
if s:find("function 'xpcall'") then
|
||||||
|
break
|
||||||
|
elseif s:find(".-%.lua:%d+:(.+)") then
|
||||||
|
local err = s:gsub(".-%.lua:%d+:%s*(.+)", "extern: %1")
|
||||||
|
table.insert(tbl, err)
|
||||||
|
elseif s:find('%[string ".-"%]') then
|
||||||
|
local line, err = s:match('^%[string ".-"%]:(%d+): (.+)$')
|
||||||
|
table.insert(tbl, label..":"..line..": "..err)
|
||||||
|
elseif s:find('%(load%):(%d+):') then
|
||||||
|
local line, err = s:match('%(load%):(%d+): (.+)$')
|
||||||
|
table.insert(tbl, label..":"..line..": "..err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return "Error: "..table.concat(tbl, "\n >> ")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function format_error(err, label)
|
||||||
if err:find("stack overflow") then
|
if err:find("stack overflow") then
|
||||||
return "Error: Stack overflow due to recursive function calls!"
|
return "Error: Stack overflow due to recursive function calls!"
|
||||||
end
|
end
|
||||||
err = err:gsub('%[string "%-%-.-"%]:', "in "..tab.." line ")
|
return format_error_str(err, label)
|
||||||
err = err:gsub('in main chunk.+', "")
|
|
||||||
err = err:gsub('%.%.%..-:%d+:', "Error")
|
|
||||||
return err
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function compile(pos, text, label, err_clbk)
|
local function compile(pos, text, label, err_clbk)
|
||||||
@ -75,8 +91,7 @@ local function compile(pos, text, label, err_clbk)
|
|||||||
text = text:gsub("%$", "S:")
|
text = text:gsub("%$", "S:")
|
||||||
local code, err = loadstring(text)
|
local code, err = loadstring(text)
|
||||||
if not code then
|
if not code then
|
||||||
err = err:gsub("%(load%):", label)
|
err_clbk(pos, format_error(err, label))
|
||||||
err_clbk(pos, err)
|
|
||||||
else
|
else
|
||||||
return code
|
return code
|
||||||
end
|
end
|
||||||
@ -87,15 +102,11 @@ end
|
|||||||
-- Standard init/loop controller
|
-- Standard init/loop controller
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
function safer_lua.init(pos, init, loop, environ, err_clbk)
|
function safer_lua.init(pos, init, loop, environ, err_clbk)
|
||||||
if #init > safer_lua.MaxCodeSize then
|
if (#init + #loop) > safer_lua.MaxCodeSize then
|
||||||
err_clbk(pos, "init() Code size limit exceeded")
|
err_clbk(pos, "Error: Code size limit exceeded")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if #loop > safer_lua.MaxCodeSize then
|
local code = compile(pos, init, "init", err_clbk, 0)
|
||||||
err_clbk(pos, "loop() Code size limit exceeded")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local code = compile(pos, init, "init() ", err_clbk)
|
|
||||||
if code then
|
if code then
|
||||||
local env = table.copy(BASE_ENV)
|
local env = table.copy(BASE_ENV)
|
||||||
env.S = {}
|
env.S = {}
|
||||||
@ -103,10 +114,10 @@ function safer_lua.init(pos, init, loop, environ, err_clbk)
|
|||||||
setfenv(code, env)
|
setfenv(code, env)
|
||||||
local res, err = xpcall(code, debug.traceback)
|
local res, err = xpcall(code, debug.traceback)
|
||||||
if not res then
|
if not res then
|
||||||
err_clbk(pos, format_error(err, "init()"))
|
err_clbk(pos, format_error(err, "init"))
|
||||||
else
|
else
|
||||||
env = getfenv(code)
|
env = getfenv(code)
|
||||||
code = compile(pos, loop, "loop() ", err_clbk)
|
code = compile(pos, loop, "loop", err_clbk)
|
||||||
if code then
|
if code then
|
||||||
setfenv(code, env)
|
setfenv(code, env)
|
||||||
return code
|
return code
|
||||||
@ -126,11 +137,11 @@ function safer_lua.run_loop(pos, elapsed, code, err_clbk)
|
|||||||
end
|
end
|
||||||
local res, err = xpcall(code, debug.traceback)
|
local res, err = xpcall(code, debug.traceback)
|
||||||
if calc_used_mem_size(env) > safer_lua.MaxTableSize then
|
if calc_used_mem_size(env) > safer_lua.MaxTableSize then
|
||||||
err_clbk(pos, "Memory limit exceeded")
|
err_clbk(pos, "Error: Data memory limit exceeded")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not res then
|
if not res then
|
||||||
err_clbk(pos, format_error(err, "loop()"))
|
err_clbk(pos, format_error(err, "loop"))
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
@ -141,15 +152,14 @@ end
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
local function thread(pos, code, err_clbk)
|
local function thread(pos, code, err_clbk)
|
||||||
while true do
|
while true do
|
||||||
local res, err = pcall(code)
|
local res, err = xpcall(code, debug.traceback)
|
||||||
if not res then
|
if not res then
|
||||||
err = err:gsub("%[string .+%]:", "loop() ")
|
err_clbk(pos, format_error(err, "loop"))
|
||||||
err_clbk(pos, err)
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local env = getfenv(code)
|
local env = getfenv(code)
|
||||||
if calc_used_mem_size(env) > safer_lua.MaxTableSize then
|
if calc_used_mem_size(env) > safer_lua.MaxTableSize then
|
||||||
err_clbk(pos, "Memory limit exceeded")
|
err_clbk(pos, "Error: Memory limit exceeded")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
@ -164,8 +174,7 @@ end
|
|||||||
function safer_lua.co_resume(pos, co, code, err_clbk)
|
function safer_lua.co_resume(pos, co, code, err_clbk)
|
||||||
local res, err = coroutine.resume(co, pos, code, err_clbk)
|
local res, err = coroutine.resume(co, pos, code, err_clbk)
|
||||||
if not res then
|
if not res then
|
||||||
err = err:gsub("%[string .+%]:", "loop() ")
|
err_clbk(pos, format_error(err, "loop"))
|
||||||
err_clbk(pos, err)
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
|
@ -105,15 +105,15 @@ function safer_lua:check(pos, text, label, err_clbk)
|
|||||||
if token == "for" then
|
if token == "for" then
|
||||||
-- invalid for statement?
|
-- invalid for statement?
|
||||||
if lToken[idx + 3] ~= "in" or lToken[idx + 5] ~= "next" then
|
if lToken[idx + 3] ~= "in" or lToken[idx + 5] ~= "next" then
|
||||||
err_clbk(pos, label..lineno..": Invalid use of 'for'")
|
err_clbk(pos, label..":"..lineno..": Invalid use of 'for'")
|
||||||
errno = errno + 1
|
errno = errno + 1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
err_clbk(pos, label..lineno..": Invalid keyword '"..token.."'")
|
err_clbk(pos, label..":"..lineno..": Invalid keyword '"..token.."'")
|
||||||
errno = errno + 1
|
errno = errno + 1
|
||||||
end
|
end
|
||||||
elseif InvalidChars[token] then
|
elseif InvalidChars[token] then
|
||||||
err_clbk(pos, label..lineno..": Invalid character '"..token.."'")
|
err_clbk(pos, label..":"..lineno..": Invalid character '"..token.."'")
|
||||||
errno = errno + 1
|
errno = errno + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -205,7 +205,7 @@ local function formspec4(meta)
|
|||||||
default.gui_bg_img..
|
default.gui_bg_img..
|
||||||
default.gui_slots..
|
default.gui_slots..
|
||||||
"tabheader[0,0;tab;init,func,loop,outp,notes,help;4;;true]"..
|
"tabheader[0,0;tab;init,func,loop,outp,notes,help;4;;true]"..
|
||||||
"table[0.2,0.2;9.5,7;output;"..output..";]"..
|
"table[0.2,0.2;9.5,7;output;"..output..";200]"..
|
||||||
"button[4.4,7.5;1.8,1;clear;Clear]"..
|
"button[4.4,7.5;1.8,1;clear;Clear]"..
|
||||||
"button[6.3,7.5;1.8,1;update;Update]"..
|
"button[6.3,7.5;1.8,1;update;Update]"..
|
||||||
"button[8.2,7.5;1.8,1;"..cmnd.."]"
|
"button[8.2,7.5;1.8,1;"..cmnd.."]"
|
||||||
@ -236,9 +236,31 @@ local function formspec6(items, pos, text)
|
|||||||
"textarea[0.3,1.3;10,8;help;Help:;"..text.."]"
|
"textarea[0.3,1.3;10,8;help;Help:;"..text.."]"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function patch_error_string(err, line_offs)
|
||||||
|
local tbl = {}
|
||||||
|
for s in err:gmatch("[^\r\n]+") do
|
||||||
|
if s:find("loop:(%d+):") then
|
||||||
|
local prefix, line, err = s:match("(.+)loop:(%d+):(.+)")
|
||||||
|
if tonumber(line) < line_offs then
|
||||||
|
table.insert(tbl, prefix.."func:"..line..":"..err)
|
||||||
|
else
|
||||||
|
line = tonumber(line) - line_offs
|
||||||
|
table.insert(tbl, prefix.."loop:"..line..":"..err)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
table.insert(tbl, s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(tbl, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
local function error(pos, err)
|
local function error(pos, err)
|
||||||
output(pos, err)
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
|
local func = meta:get_string("func")
|
||||||
|
local _,line_offs = string.gsub(func, "\n", "\n")
|
||||||
|
line_offs = line_offs + 1
|
||||||
|
err = patch_error_string(err, line_offs)
|
||||||
|
output(pos, err)
|
||||||
local number = meta:get_string("number")
|
local number = meta:get_string("number")
|
||||||
meta:set_string("infotext", "Controller "..number..": error")
|
meta:set_string("infotext", "Controller "..number..": error")
|
||||||
meta:set_int("state", tubelib.STOPPED)
|
meta:set_int("state", tubelib.STOPPED)
|
||||||
@ -255,7 +277,7 @@ local function compile(pos, meta, number)
|
|||||||
local owner = meta:get_string("owner")
|
local owner = meta:get_string("owner")
|
||||||
local env = table.copy(tCommands)
|
local env = table.copy(tCommands)
|
||||||
env.meta = {pos=pos, owner=owner, number=number, error=error}
|
env.meta = {pos=pos, owner=owner, number=number, error=error}
|
||||||
local code = safer_lua.init(pos, init .."\n".. func, loop, env, error)
|
local code = safer_lua.init(pos, init, func.."\n"..loop, env, error)
|
||||||
|
|
||||||
if code then
|
if code then
|
||||||
Cache[number] = {code=code, inputs={}}
|
Cache[number] = {code=code, inputs={}}
|
||||||
@ -457,6 +479,10 @@ minetest.register_node("sl_controller:controller", {
|
|||||||
meta:set_string("func", "-- for your functions")
|
meta:set_string("func", "-- for your functions")
|
||||||
meta:set_string("loop", "-- called every second")
|
meta:set_string("loop", "-- called every second")
|
||||||
meta:set_string("notes", "For your notes / snippets")
|
meta:set_string("notes", "For your notes / snippets")
|
||||||
|
meta:mark_as_private("init")
|
||||||
|
meta:mark_as_private("func")
|
||||||
|
meta:mark_as_private("loop")
|
||||||
|
meta:mark_as_private("notes")
|
||||||
meta:set_string("formspec", formspec1(meta))
|
meta:set_string("formspec", formspec1(meta))
|
||||||
meta:set_string("infotext", "Controller "..number..": stopped")
|
meta:set_string("infotext", "Controller "..number..": stopped")
|
||||||
end,
|
end,
|
||||||
|
@ -108,8 +108,13 @@ end
|
|||||||
local function write_row(meta, payload)
|
local function write_row(meta, payload)
|
||||||
local text = meta:get_string("text")
|
local text = meta:get_string("text")
|
||||||
if type(payload) == "table" then
|
if type(payload) == "table" then
|
||||||
local row = tonumber(payload.row) or 1
|
local row = tonumber(payload.row) or 0
|
||||||
|
if row > 9 then row = 9 end
|
||||||
local str = payload.str or "oops"
|
local str = payload.str or "oops"
|
||||||
|
if row == 0 then
|
||||||
|
meta:set_string("infotext", str)
|
||||||
|
return
|
||||||
|
end
|
||||||
local rows
|
local rows
|
||||||
if meta:get_int("startscreen") == 1 then
|
if meta:get_int("startscreen") == 1 then
|
||||||
rows = {}
|
rows = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user