--- Lua debug script for tracebacks
-- @module 02_Debug

if not debug then
	-- stubs
	debug = {}
	debug.traceback = function()
		return ""
	end
	return
end

-- Override debug.traceback.
function debug.traceback(...)
	local thread = coroutine.running()
	local msg = ""
	local level = 1
	local args = {...}

	if type(args[1]) == "thread" then
		thread = args[1]
		table.remove(args)
	end
	if type(args[1]) == "string" then
		msg = args[1]
		table.remove(args)
	end
	if type(args[1]) == "number" then
		level = args[1]
		table.remove(args)
	end

	if thread == coroutine.running() then
		level = level + 1 -- skip this function
	end

	local stack = {}
	repeat
		local info = debug.getinfo(level, "Sln")
		table.insert(stack, info)
		level = level + 1
	until not info

	if #stack == 0 then
		return ""
	end

	-- The original caller is usually C; remove it.
	if (stack[#stack].what == "C") then
		table.remove(stack)
	end
	local function FormatFrame(level, frame)
		local sFrameInfo = ""
		sFrameInfo = sFrameInfo .. "#" .. level .. "  "
		if (frame.what == "tail") then
			--      sFrameInfo = sFrameInfo .. "(tail call)"
			--      return sFrameInfo
		elseif (frame.what == "main") then
			sFrameInfo = sFrameInfo .. "main in "
		elseif frame.name then
			sFrameInfo = sFrameInfo .. frame.name .. "() in "
		else
			sFrameInfo = sFrameInfo .. "... in "
		end
		sFrameInfo = sFrameInfo .. frame.short_src

		if frame.currentline ~= -1 then
			sFrameInfo = sFrameInfo .. ":" .. frame.currentline
		end

		return sFrameInfo
	end

	local FrameInfo = {}
	for level, frame in ipairs(stack) do
		FrameInfo[level] = FormatFrame(level, frame)
	end
	return table.concat(FrameInfo, "\n")
end

-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
