|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://anggtwu.net/LUA/XPCall1.lua.html
-- http://anggtwu.net/LUA/XPCall1.lua
-- (find-angg "LUA/XPCall1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2023nov12
--
-- This class implements a modular wrapper around pcall and xpcall
-- that can be used in many ways. For example:
--
-- 1) as an unwind/protect that sets global variables temporarily
-- 2) as an xpcall that displays the error and a pretraceback
-- 3) as an xpcall that returns the error and a pretraceback
--
-- The methods ":stb0()" and ":stb()" save a pretraceback in the
-- global variable ptb, but they only do that if the current value of
-- ptb is nil. (Explain clobbering)
-- ... as an unwind/protect. The xpcall methods save a
-- pretraceback that can be used for post-mortem debugging.
--
-- (defun xp () (interactive) (find-angg "LUA/XPCall1.lua"))
-- (defun pc () (interactive) (find-angg "LUA/PCall1.lua"))
-- This is more powerful than:
-- (find-angg "LUA/PCall1.lua")
-- but the classes here and there are disjoint and the
-- two files can be loaded at the same time.
-- Some of the methods in the XPCall class use pretracebacks:
-- (find-angg "LUA/PrintFunction1.lua" "PreTraceback")
--
-- See:
-- (find-angg "LUA/lua50init.lua" "pack-and-unpack")
-- (find-emlua "Repl1.lua" "WithFakePrint")
-- Used by:
-- (find-angg "LUA/Repl3.lua")
-- «.XPCall» (to "XPCall")
-- «.XPCall-tests» (to "XPCall-tests")
-- «.XPCall-tests-x» (to "XPCall-tests-x")
require "PreTraceback1" -- (find-angg "LUA/PreTraceback1.lua")
-- __ ______ ____ _ _
-- \ \/ / _ \ / ___|__ _| | |
-- \ /| |_) | | / _` | | |
-- / \| __/| |__| (_| | | |
-- /_/\_\_| \____\__,_|_|_|
--
-- «XPCall» (to ".XPCall")
XPCall = Class {
type = "XPCall",
__tostring = function (pc) return mytostringv(pc) end,
__index = {
m = function (pc,f,...)
if type(f) == "string" then f = pc[f] end
if f then f(pc,...) end
return pc
end,
--
a = function (pc) return pc:m("before") end,
b = function (pc,...)
local fargs = pack(...)
local g = function () return pc.f(unpack(fargs)) end
pc.presults = pack(pcall(g))
return pc
end,
c = function (pc) return pc:m("after") end,
--
ok = function (pc) return pc.presults[1] end,
e = function (pc) return pc.presults[2] end,
r = function (pc) return unpack(pc.presults, 2, pc.presults.n) end,
re = function (pc) return false,pc:e() end,
rr = function (pc) return true,pc:r() end,
rre = function (pc) if pc:ok() then return pc:rr() else return pc:re() end end,
okr = function (pc) if pc:ok() then return pc:r() end end,
--
pcall = function (pc,...) return pc:a():b(...):c():rre() end,
pcall0 = function (pc,...) return pc:a():b(...):c():okr() end,
--
eh = function (...) return false end,
xb = function (pc, ...)
local fargs = pack(...)
local g = function () return pc.f(unpack(fargs)) end
local geh = function (...)
pc.gehargs = pack(...)
pc.errmsg = ...
pc.traceback = debug.traceback()
pc.pretraceback = PreTraceback.new(true,true)
return pc:eh()
end
pc.presults = pack(xpcall(g, geh))
return pc
end,
ptb00 = function (pc,a,b) return pc.pretraceback:tostring(a, b) end,
ptb0 = function (pc,a,b) return pc:ptb00(a or #pc.pretraceback, b or 5) end,
ptb = function (pc,a,b) return pc:ptb0(a,b).."\n"..pc.errmsg end,
stb0 = function (pc) ptb = ptb or pc.pretraceback; return pc end,
stb = function (pc) if not pc:ok() then pc:stb0() end; return pc end,
xpe = function (pc) if not pc:ok() then print(pc:ptb()) end; return pc end,
--
xpcall3 = function (pc,...) return pc:a():xb(...):c() end,
xpcall5 = function (pc,...) return pc:a():xb(...):c():xpe():okr() end,
xpcall6 = function (pc,...) return pc:a():xb(...):c():stb():xpe():okr() end,
--
clr = function (pc)
pc = copy(pc)
pc.traceback,pc.pretraceback = nil,nil
return pc
end,
},
}
-- «XPCall-tests-x» (to ".XPCall-tests-x")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "XPCall1.lua"
p = XPCall {
f = function (a,b) print(a,b); return a+b,a*b end,
}
p:xpcall3(2,3)
p:xpcall5(2,3)
= p:xpcall5(2,3)
= p:clr()
= ptb
p:xpcall3(2,false)
p:xpcall5(2,false)
p:xpcall6(2,false)
= ptb
= ptb[2]
= ptb[2].locals
= ptb[2].locals:inames()
= p.pretraceback
= p:ptb()
= p:ptb(nil, 0)
= p
= p:clr()
= p:xpcall3(2,false)
= p:xpcall4(2,false)
--]]
-- «XPCall-tests» (to ".XPCall-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "XPCall1.lua"
p = XPCall {
before = function () print "(before)" end,
f = function (a,b) print(a,b); return a+b,a*b end,
after = function () print "(after)" end,
}
= p:pcall (2,3)
= p:pcall0(2,3)
= p
= p:ok()
= p:r()
= p:rr()
= p:rre()
= p:okr()
= p:pcall(2,false)
= p
= p:e()
= p:re()
= p:rre()
= p:okr()
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: