1 -------------------------------------------------------------------------------
4 -- Written by Timm S. Mueller <tmueller at schulze-mueller.de>
5 -- See copyright notice in COPYRIGHT
8 -- Debug library - implements debug output and debug levels:
10 -- 2 || TRACE || used for tracking bugs
11 -- 4 || INFO || informational messages
12 -- 5 || WARN || something unexpected happened
13 -- 10 || ERROR || something went wrong, e.g. resource unavailable
14 -- 20 || FAIL || something went wrong that can't be coped with
16 -- The default debug level is 10 {{ERROR}}. To set the debug level
18 -- db = require "tek.lib.debug"
21 -- The default debug output stream is {{stderr}}.
22 -- To override it globally, e.g.:
23 -- db = require "tek.lib.debug"
24 -- db.out = io.open("logfile", "w")
27 -- - debug.console() - Enter debug console
28 -- - debug.dump() - Dump a table recursively
29 -- - debug.error() - Print a text in the {{ERROR}} debug level
30 -- - debug.execute() - Execute a function in the specified debug level
31 -- - debug.fail() - Print a text in the {{FAIL}} debug level
32 -- - debug.info() - Print a text in the {{INFO}} debug level
33 -- - debug.print() - Print a text in the specified debug level
34 -- - debug.stacktrace() - Print a stacktrace in the specified debug level
35 -- - debug.trace() - Print a text in the {{TRACE}} debug level
36 -- - debug.warn() - Print a text in the {{WARN}} debug level
38 -------------------------------------------------------------------------------
40 local debug = require "debug"
41 local getinfo = debug.getinfo
42 local stderr = io.stderr
46 local tonumber = tonumber
47 local tostring = tostring
48 local traceback = debug.traceback
52 module "tek.lib.debug"
53 _VERSION = "Debug 4.0"
67 wrout = function(...) out:write(...) end
69 -------------------------------------------------------------------------------
70 -- print(lvl, msg, ...): Prints formatted text if the global debug level
71 -- is less or equal the specified level.
72 -------------------------------------------------------------------------------
74 function print(lvl, msg, ...)
75 if level and lvl >= level then
76 local t = getinfo(3, "lS")
78 for i = 1, select('#', ...) do
79 local v = select(i, ...)
80 arg[i] = v and type(v) ~= "number" and tostring(v) or v or 0
82 wrout(("(%02d %d %s:%d) " .. msg):format(lvl,
83 time(), t.short_src, t.currentline, unpack(arg)) .. "\n")
87 -------------------------------------------------------------------------------
88 -- execute(lvl, func, ...): Executes the specified function if the global
89 -- debug library is less or equal the specified level.
90 -------------------------------------------------------------------------------
92 function execute(lvl, func, ...)
93 if level and lvl >= level then
98 -------------------------------------------------------------------------------
99 -- trace(msg, ...): Prints formatted debug info with {{TRACE}} level
100 -------------------------------------------------------------------------------
101 function trace(msg, ...) print(2, msg, ...) end
103 -------------------------------------------------------------------------------
104 -- info(msg, ...): Prints formatted debug info with {{INFO}} level
105 -------------------------------------------------------------------------------
106 function info(msg, ...) print(4, msg, ...) end
108 -------------------------------------------------------------------------------
109 -- warn(msg, ...): Prints formatted debug info with {{WARN}} level
110 -------------------------------------------------------------------------------
111 function warn(msg, ...) print(5, msg, ...) end
113 -------------------------------------------------------------------------------
114 -- error(msg, ...): Prints formatted debug info with {{ERROR}} level
115 -------------------------------------------------------------------------------
116 function error(msg, ...) print(10, msg, ...) end
118 -------------------------------------------------------------------------------
119 -- fail(msg, ...): Prints formatted debug info with {{FAIL}} level
120 -------------------------------------------------------------------------------
121 function fail(msg, ...) print(20, msg, ...) end
123 -------------------------------------------------------------------------------
124 -- stacktrace(debuglevel, stacklevel): Prints a stacktrace starting at
125 -- the function of the given {{level}} on the stack (excluding the
126 -- {{stracktrace}} function itself) if the global debug level is less
127 -- or equal the specified {{debuglevel}}.
128 -------------------------------------------------------------------------------
130 function stacktrace(lvl, level)
131 print(lvl, traceback("", level or 1 + 1))
134 -------------------------------------------------------------------------------
135 -- console(): Enter the debug console.
136 -------------------------------------------------------------------------------
139 stderr:write('Entering the debug console.\n')
140 stderr:write('To redirect the output, e.g.:\n')
141 stderr:write(' tek.lib.debug.out = io.open("logfile", "w")\n')
142 stderr:write('To dump a table, e.g.:\n')
143 stderr:write(' tek.lib.debug.dump("app", app)\n')
144 stderr:write('Use "cont" to continue.\n')
148 -------------------------------------------------------------------------------
149 -- dump(name, table): Dump a table
150 -------------------------------------------------------------------------------
152 local function basicSerialize(o)
153 if type(o) == "string" then
154 return ("%q"):format(o)
155 elseif type(o) == "userdata" then
161 function dump(name, value, saved)
162 saved = saved or {} -- initial value
164 local t = type(value)
166 if saved[value] then -- value already saved?
167 wrout(saved[value], "\n")
169 saved[value] = name -- save name for next time
171 for k,v in pairs(value) do -- save its fields
172 local fieldname = ("%s[%s]"):format(name, basicSerialize(k))
173 dump(fieldname, v, saved)
177 wrout(basicSerialize(value), "\n")