11 |
11 |
12 local termcolours = require "util.termcolours"; |
12 local termcolours = require "util.termcolours"; |
13 local getstring = termcolours.getstring; |
13 local getstring = termcolours.getstring; |
14 local styles; |
14 local styles; |
15 do |
15 do |
16 _ = termcolours.getstyle; |
16 local _ = termcolours.getstyle; |
17 styles = { |
17 styles = { |
18 boundary_padding = _("bright"); |
18 boundary_padding = _("bright"); |
19 filename = _("bright", "blue"); |
19 filename = _("bright", "blue"); |
20 level_num = _("green"); |
20 level_num = _("green"); |
21 funcname = _("yellow"); |
21 funcname = _("yellow"); |
22 location = _("yellow"); |
22 location = _("yellow"); |
23 }; |
23 }; |
24 end |
24 end |
25 module("debugx", package.seeall); |
25 |
26 |
26 local function get_locals_table(thread, level) |
27 function get_locals_table(thread, level) |
|
28 local locals = {}; |
27 local locals = {}; |
29 for local_num = 1, math.huge do |
28 for local_num = 1, math.huge do |
30 local name, value; |
29 local name, value; |
31 if thread then |
30 if thread then |
32 name, value = debug.getlocal(thread, level, local_num); |
31 name, value = debug.getlocal(thread, level, local_num); |
37 table.insert(locals, { name = name, value = value }); |
36 table.insert(locals, { name = name, value = value }); |
38 end |
37 end |
39 return locals; |
38 return locals; |
40 end |
39 end |
41 |
40 |
42 function get_upvalues_table(func) |
41 local function get_upvalues_table(func) |
43 local upvalues = {}; |
42 local upvalues = {}; |
44 if func then |
43 if func then |
45 for upvalue_num = 1, math.huge do |
44 for upvalue_num = 1, math.huge do |
46 local name, value = debug.getupvalue(func, upvalue_num); |
45 local name, value = debug.getupvalue(func, upvalue_num); |
47 if not name then break; end |
46 if not name then break; end |
49 end |
48 end |
50 end |
49 end |
51 return upvalues; |
50 return upvalues; |
52 end |
51 end |
53 |
52 |
54 function string_from_var_table(var_table, max_line_len, indent_str) |
53 local function string_from_var_table(var_table, max_line_len, indent_str) |
55 local var_string = {}; |
54 local var_string = {}; |
56 local col_pos = 0; |
55 local col_pos = 0; |
57 max_line_len = max_line_len or math.huge; |
56 max_line_len = max_line_len or math.huge; |
58 indent_str = "\n"..(indent_str or ""); |
57 indent_str = "\n"..(indent_str or ""); |
59 for _, var in ipairs(var_table) do |
58 for _, var in ipairs(var_table) do |
85 else |
84 else |
86 return "{ "..table.concat(var_string, ", "):gsub(indent_str..", ", indent_str).." }"; |
85 return "{ "..table.concat(var_string, ", "):gsub(indent_str..", ", indent_str).." }"; |
87 end |
86 end |
88 end |
87 end |
89 |
88 |
90 function get_traceback_table(thread, start_level) |
89 local function get_traceback_table(thread, start_level) |
91 local levels = {}; |
90 local levels = {}; |
92 for level = start_level, math.huge do |
91 for level = start_level, math.huge do |
93 local info; |
92 local info; |
94 if thread then |
93 if thread then |
95 info = debug.getinfo(thread, level); |
94 info = debug.getinfo(thread, level); |
106 }; |
105 }; |
107 end |
106 end |
108 return levels; |
107 return levels; |
109 end |
108 end |
110 |
109 |
111 function traceback(...) |
|
112 local ok, ret = pcall(_traceback, ...); |
|
113 if not ok then |
|
114 return "Error in error handling: "..ret; |
|
115 end |
|
116 return ret; |
|
117 end |
|
118 |
|
119 local function build_source_boundary_marker(last_source_desc) |
110 local function build_source_boundary_marker(last_source_desc) |
120 local padding = string.rep("-", math.floor(((optimal_line_length - 6) - #last_source_desc)/2)); |
111 local padding = string.rep("-", math.floor(((optimal_line_length - 6) - #last_source_desc)/2)); |
121 return getstring(styles.boundary_padding, "v"..padding).." "..getstring(styles.filename, last_source_desc).." "..getstring(styles.boundary_padding, padding..(#last_source_desc%2==0 and "-v" or "v ")); |
112 return getstring(styles.boundary_padding, "v"..padding).." "..getstring(styles.filename, last_source_desc).." "..getstring(styles.boundary_padding, padding..(#last_source_desc%2==0 and "-v" or "v ")); |
122 end |
113 end |
123 |
114 |
124 function _traceback(thread, message, level) |
115 local function _traceback(thread, message, level) |
125 |
116 |
126 -- Lua manual says: debug.traceback ([thread,] [message [, level]]) |
117 -- Lua manual says: debug.traceback ([thread,] [message [, level]]) |
127 -- I fathom this to mean one of: |
118 -- I fathom this to mean one of: |
128 -- () |
119 -- () |
129 -- (thread) |
120 -- (thread) |
190 -- table.insert(lines, "\t "..build_source_boundary_marker(last_source_desc)); |
181 -- table.insert(lines, "\t "..build_source_boundary_marker(last_source_desc)); |
191 |
182 |
192 return message.."stack traceback:\n"..table.concat(lines, "\n"); |
183 return message.."stack traceback:\n"..table.concat(lines, "\n"); |
193 end |
184 end |
194 |
185 |
195 function use() |
186 local function traceback(...) |
|
187 local ok, ret = pcall(_traceback, ...); |
|
188 if not ok then |
|
189 return "Error in error handling: "..ret; |
|
190 end |
|
191 return ret; |
|
192 end |
|
193 |
|
194 local function use() |
196 debug.traceback = traceback; |
195 debug.traceback = traceback; |
197 end |
196 end |
198 |
197 |
199 return _M; |
198 return { |
|
199 get_locals_table = get_locals_table; |
|
200 get_upvalues_table = get_upvalues_table; |
|
201 string_from_var_table = string_from_var_table; |
|
202 get_traceback_table = get_traceback_table; |
|
203 traceback = traceback; |
|
204 use = use; |
|
205 }; |