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