cgi-bin/tek/lib/debug.lua
changeset 244 3a4291950c9f
parent 226 f16ff668a409
child 247 71a5ca44a68e
     1.1 --- a/cgi-bin/tek/lib/debug.lua	Mon Dec 17 04:31:32 2007 +0100
     1.2 +++ b/cgi-bin/tek/lib/debug.lua	Fri Sep 12 22:00:42 2008 +0200
     1.3 @@ -1,49 +1,73 @@
     1.4  -------------------------------------------------------------------------------
     1.5  --
     1.6  --	tek.lib.debug
     1.7 ---	Written by Timm S. Mueller <tmueller at neoscientists.org>
     1.8 +--	Written by Timm S. Mueller <tmueller at schulze-mueller.de>
     1.9  --	See copyright notice in COPYRIGHT
    1.10  --
    1.11  --	OVERVIEW::
    1.12  --	Debug library - implements debug output and debug levels:
    1.13  --
    1.14 ---	2  || trace || used for tracking bugs
    1.15 ---	4  || info  || informational messages during development
    1.16 ---	5  || warn  || something unexpected happened
    1.17 ---	10 || error || something went wrong, e.g. allocation of a resource
    1.18 ---	20 || fail  || something went wrong that the program can't cope with
    1.19 +--	2  || TRACE || used for tracking bugs
    1.20 +--	4  || INFO  || informational messages
    1.21 +--	5  || WARN  || something unexpected happened
    1.22 +--	10 || ERROR || something went wrong, e.g. resource unavailable
    1.23 +--	20 || FAIL  || something went wrong that can't be coped with
    1.24  --
    1.25 ---	The default debug level is 10 ''error''. To set the debug level
    1.26 +--	The default debug level is 10 {{ERROR}}. To set the debug level
    1.27  --	globally, e.g.:
    1.28  --			db = require "tek.lib.debug"
    1.29 ---			db.level = 4
    1.30 +--			db.level = db.INFO
    1.31  --
    1.32  --	The default debug output stream is {{stderr}}.
    1.33  --	To override it globally, e.g.:
    1.34  --			db = require "tek.lib.debug"
    1.35 ---			f = io.open("logfile", "w")
    1.36 ---			db.out = function(...) f:write(...) end
    1.37 +--			db.out = io.open("logfile", "w")
    1.38 +--
    1.39 +--	FUNCTIONS::
    1.40 +--		- debug.console() - Enter debug console
    1.41 +--		- debug.dump() - Dump a table recursively
    1.42 +--		- debug.error() - Print a text in the {{ERROR}} debug level
    1.43 +--		- debug.execute() - Execute a function in the specified debug level
    1.44 +--		- debug.fail() - Print a text in the {{FAIL}} debug level
    1.45 +--		- debug.info() - Print a text in the {{INFO}} debug level
    1.46 +--		- debug.print() - Print a text in the specified debug level
    1.47 +--		- debug.stacktrace() - Print a stacktrace in the specified debug level
    1.48 +--		- debug.trace() - Print a text in the {{TRACE}} debug level
    1.49 +--		- debug.warn() - Print a text in the {{WARN}} debug level
    1.50  --
    1.51  -------------------------------------------------------------------------------
    1.52  
    1.53 -local getinfo = require "debug".getinfo
    1.54 -local stderr = require "io".stderr
    1.55 +local debug = require "debug"
    1.56 +local getinfo = debug.getinfo
    1.57 +local stderr = io.stderr
    1.58 +local pairs = pairs
    1.59 +local select = select
    1.60 +local time = os.time
    1.61 +local tonumber = tonumber
    1.62  local tostring = tostring
    1.63 -local tonumber = tonumber
    1.64 +local traceback = debug.traceback
    1.65  local type = type
    1.66  local unpack = unpack
    1.67 -local select = select
    1.68 -local time = os.time
    1.69  
    1.70  module "tek.lib.debug"
    1.71 -_VERSION = "Debug 1.1"
    1.72 +_VERSION = "Debug 4.0"
    1.73 +
    1.74 +-- symbolic:
    1.75 +
    1.76 +TRACE = 2
    1.77 +INFO = 4
    1.78 +WARN = 5
    1.79 +ERROR = 10
    1.80 +FAIL = 20
    1.81  
    1.82  -- global defaults:
    1.83 -level = 10
    1.84 -out = function(...) stderr:write(...) end
    1.85 +
    1.86 +level = ERROR
    1.87 +out = stderr
    1.88 +wrout = function(...) out:write(...) end
    1.89  
    1.90  -------------------------------------------------------------------------------
    1.91 ---	print(lvl, msg, ...): prints formatted text if the global debug level
    1.92 +--	print(lvl, msg, ...): Prints formatted text if the global debug level
    1.93  --	is less or equal the specified level.
    1.94  -------------------------------------------------------------------------------
    1.95  
    1.96 @@ -55,13 +79,13 @@
    1.97  			local v = select(i, ...)
    1.98  			arg[i] = v and type(v) ~= "number" and tostring(v) or v or 0
    1.99  		end
   1.100 -		out(("(%02d %d %s:%d) " .. msg):format(lvl,
   1.101 +		wrout(("(%02d %d %s:%d) " .. msg):format(lvl,
   1.102  			time(), t.short_src, t.currentline, unpack(arg)) .. "\n")
   1.103  	end
   1.104  end
   1.105  
   1.106  -------------------------------------------------------------------------------
   1.107 ---	execute(lvl, func, ...): executes the specified function if the global
   1.108 +--	execute(lvl, func, ...): Executes the specified function if the global
   1.109  --	debug library is less or equal the specified level.
   1.110  -------------------------------------------------------------------------------
   1.111  
   1.112 @@ -72,32 +96,84 @@
   1.113  end
   1.114  
   1.115  -------------------------------------------------------------------------------
   1.116 ---	trace(msg, ...): prints formatted debug info with ''trace'' level
   1.117 +--	trace(msg, ...): Prints formatted debug info with {{TRACE}} level
   1.118  -------------------------------------------------------------------------------
   1.119  function trace(msg, ...) print(2, msg, ...) end
   1.120  
   1.121  -------------------------------------------------------------------------------
   1.122 ---	info(msg, ...): prints formatted debug info with ''info'' level
   1.123 +--	info(msg, ...): Prints formatted debug info with {{INFO}} level
   1.124  -------------------------------------------------------------------------------
   1.125  function info(msg, ...) print(4, msg, ...) end
   1.126  
   1.127  -------------------------------------------------------------------------------
   1.128 ---	warn(msg, ...): prints formatted debug info with ''warn'' level
   1.129 +--	warn(msg, ...): Prints formatted debug info with {{WARN}} level
   1.130  -------------------------------------------------------------------------------
   1.131  function warn(msg, ...) print(5, msg, ...) end
   1.132  
   1.133  -------------------------------------------------------------------------------
   1.134 ---	error(msg, ...): prints formatted debug info with ''error'' level
   1.135 +--	error(msg, ...): Prints formatted debug info with {{ERROR}} level
   1.136  -------------------------------------------------------------------------------
   1.137  function error(msg, ...) print(10, msg, ...) end
   1.138  
   1.139  -------------------------------------------------------------------------------
   1.140 ---	fail(msg, ...): prints formatted debug info with ''fail'' level
   1.141 +--	fail(msg, ...): Prints formatted debug info with {{FAIL}} level
   1.142  -------------------------------------------------------------------------------
   1.143  function fail(msg, ...) print(20, msg, ...) end
   1.144  
   1.145 -function dotrace(msg, ...) execute(2, msg, ...) end
   1.146 -function doinfo(msg, ...) execute(4, msg, ...) end
   1.147 -function dowarn(msg, ...) execute(5, msg, ...) end
   1.148 -function doerror(msg, ...) execute(10, msg, ...) end
   1.149 -function dofail(msg, ...) execute(20, msg, ...) end
   1.150 +-------------------------------------------------------------------------------
   1.151 +--	stacktrace(debuglevel, stacklevel): Prints a stacktrace starting at
   1.152 +--	the function of the given {{level}} on the stack (excluding the
   1.153 +--	{{stracktrace}} function itself) if the global debug level is less
   1.154 +--	or equal the specified {{debuglevel}}.
   1.155 +-------------------------------------------------------------------------------
   1.156 +
   1.157 +function stacktrace(lvl, level)
   1.158 +	print(lvl, traceback("", level or 1 + 1))
   1.159 +end
   1.160 +
   1.161 +-------------------------------------------------------------------------------
   1.162 +--	console(): Enter the debug console.
   1.163 +-------------------------------------------------------------------------------
   1.164 +
   1.165 +function console()
   1.166 +	stderr:write('Entering the debug console.\n')
   1.167 +	stderr:write('To redirect the output, e.g.:\n')
   1.168 +	stderr:write('  tek.lib.debug.out = io.open("logfile", "w")\n')
   1.169 +	stderr:write('To dump a table, e.g.:\n')
   1.170 +	stderr:write('  tek.lib.debug.dump("app", app)\n')
   1.171 +	stderr:write('Use "cont" to continue.\n')
   1.172 +	debug.debug()
   1.173 +end
   1.174 +
   1.175 +-------------------------------------------------------------------------------
   1.176 +--	dump(name, table): Dump a table
   1.177 +-------------------------------------------------------------------------------
   1.178 +
   1.179 +local function basicSerialize(o)
   1.180 +	if type(o) == "string" then
   1.181 +		return ("%q"):format(o)
   1.182 +	elseif type(o) == "userdata" then
   1.183 +		return "<userdata>"
   1.184 +	end
   1.185 +	return tostring(o)
   1.186 +end
   1.187 +
   1.188 +function dump(name, value, saved)
   1.189 +	saved = saved or {}       -- initial value
   1.190 +	wrout(name, " = ")
   1.191 +	local t = type(value)
   1.192 +	if t == "table" then
   1.193 +		if saved[value] then    -- value already saved?
   1.194 +			wrout(saved[value], "\n")
   1.195 +		else
   1.196 +			saved[value] = name   -- save name for next time
   1.197 +			wrout("{}\n")
   1.198 +			for k,v in pairs(value) do      -- save its fields
   1.199 +				local fieldname = ("%s[%s]"):format(name, basicSerialize(k))
   1.200 +				dump(fieldname, v, saved)
   1.201 +			end
   1.202 +		end
   1.203 +	else
   1.204 +		wrout(basicSerialize(value), "\n")
   1.205 +	end
   1.206 +end