unroller 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/unroller.rb +76 -8
- metadata +4 -4
data/lib/unroller.rb
CHANGED
@@ -5,6 +5,8 @@ require 'facets/core/kernel/with'
|
|
5
5
|
require 'facets/core/kernel/set_with'
|
6
6
|
require 'facets/core/string/bracket'
|
7
7
|
require 'facets/core/kernel/singleton_class'
|
8
|
+
require 'facets/core/symbol/to_proc'
|
9
|
+
require 'facets/core/string/index_all'
|
8
10
|
gem 'qualitysmith_extensions'
|
9
11
|
require 'qualitysmith_extensions/object/send_if_not_nil'
|
10
12
|
require 'qualitysmith_extensions/kernel/trap_chain'
|
@@ -19,8 +21,13 @@ require 'qualitysmith_extensions/enumerable/select_until'
|
|
19
21
|
require 'qualitysmith_extensions/module/bool_attr_accessor'
|
20
22
|
gem 'colored'
|
21
23
|
require 'colored'
|
22
|
-
|
23
|
-
require '
|
24
|
+
|
25
|
+
require 'English'
|
26
|
+
require 'pp'
|
27
|
+
require 'stringio'
|
28
|
+
gem 'termios'
|
29
|
+
require 'termios'
|
30
|
+
gem 'colored'
|
24
31
|
|
25
32
|
# To disable color, uncomment this:
|
26
33
|
#class String
|
@@ -29,8 +36,39 @@ require 'extensions/symbol' # to_proc
|
|
29
36
|
# end
|
30
37
|
#end
|
31
38
|
|
39
|
+
begin
|
40
|
+
# Set up termios so that it returns immediately when you press a key.
|
41
|
+
# (http://blog.rezra.com/articles/2005/12/05/single-character-input)
|
42
|
+
t = Termios.tcgetattr(STDIN)
|
43
|
+
save_terminal_attributes = t.dup
|
44
|
+
t.lflag &= ~Termios::ICANON
|
45
|
+
Termios.tcsetattr(STDIN, 0, t)
|
46
|
+
end
|
32
47
|
|
48
|
+
class String
|
49
|
+
# Makes the first character bold and underlined. Makes the whole string of the given color.
|
50
|
+
# :todo: Move out to extensions/console/menu_item
|
51
|
+
def menu_item(color = :white, letter = self[0..0], which_occurence = 0)
|
52
|
+
index = index_all(/#{letter}/)[which_occurence]
|
53
|
+
raise "Could not find a #{which_occurence}th occurence of '#{letter}' in string '#{self}'" if index.nil?
|
54
|
+
before = self[0..index-1].send(color) unless index == 0
|
55
|
+
middle = self[index..index].send(color).bold.underline
|
56
|
+
after = self[index+1..-1].send(color)
|
57
|
+
before.to_s + middle + after
|
58
|
+
end
|
59
|
+
end
|
60
|
+
def confirm(question, options = ['Yes', 'No'])
|
61
|
+
print question + " " +
|
62
|
+
"Yes".menu_item(:red) + ", " +
|
63
|
+
"No".menu_item(:green) +
|
64
|
+
" > "
|
65
|
+
response = ''
|
66
|
+
# Currently allow user to press Enter to accept the default.
|
67
|
+
response = $stdin.getc.chr.downcase while !['y', 'n', "\n"].include?(begin response.downcase!; response end)
|
68
|
+
response
|
69
|
+
end
|
33
70
|
|
71
|
+
begin # Reset terminal_attributes
|
34
72
|
|
35
73
|
class Unroller
|
36
74
|
#-------------------------------------------------------------------------------------------------
|
@@ -123,6 +161,7 @@ class Unroller
|
|
123
161
|
@always_show_raise_events = false
|
124
162
|
@show_file_load_errors = false
|
125
163
|
@interactive = false # Set to true to make it more like an interactive debugger.
|
164
|
+
@show_menu = true # Set to false if you don't need the hints.
|
126
165
|
# (In the future, might add "break out of this call" option to stop watching anything until we return from the current method... etc.)
|
127
166
|
instance_variables.each do |v|
|
128
167
|
self.class.class_eval do
|
@@ -261,10 +300,23 @@ class Unroller
|
|
261
300
|
#printf "- (event=%8s) (klass=%10s) (id=%10s) (%s:%-2d)\n", event, klass, id, file, line #if klass.to_s == 'false'
|
262
301
|
#puts 'false!!!!!!!'+klass.inspect if klass.to_s == 'false'
|
263
302
|
|
264
|
-
return if ['c-call', 'c-return'].include?
|
303
|
+
return if ['c-call', 'c-return'].include?(event) unless include_c_calls
|
265
304
|
#(puts 'exclude') if @silent_until_return_to_this_depth unless event == 'return' # Until we hit a return and can break out of this uninteresting call, we don't want to do *anything*.
|
266
305
|
#return if uninteresting_class?(klass.to_s) unless (klass == false)
|
267
306
|
|
307
|
+
if @only_makes_sense_if_next_event_is_call
|
308
|
+
if event == 'call'
|
309
|
+
@only_makes_sense_if_next_event_is_call = nil
|
310
|
+
else
|
311
|
+
# Cancel @silent_until_return_to_this_depth because it didn't make sense / wasn't necessary. They could have
|
312
|
+
# ("should have") simply done a 'step into', because unless it's a 'call', there's nothing to step over anyway...
|
313
|
+
# Not only is it unnecessary, but it would cause confusing behavior unless we cancelled this. As in, it
|
314
|
+
# wouldn't show *any* tracing for the remainder of the method, because it's kind of looking for a "return"...
|
315
|
+
#puts "Cancelling @silent_until_return_to_this_depth..."
|
316
|
+
@silent_until_return_to_this_depth = nil
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
268
320
|
if too_far?
|
269
321
|
puts "We've read #{@max_lines} (@max_lines) lines now. Turning off tracing..."
|
270
322
|
trace_off
|
@@ -294,10 +346,10 @@ class Unroller
|
|
294
346
|
|
295
347
|
@lines_output += 1
|
296
348
|
|
297
|
-
@call_stack.push current_call
|
298
349
|
|
299
350
|
@depth += 1
|
300
351
|
end
|
352
|
+
@call_stack.push current_call
|
301
353
|
@internal_depth += 1
|
302
354
|
|
303
355
|
|
@@ -326,14 +378,25 @@ class Unroller
|
|
326
378
|
|
327
379
|
# Interactive debugger!
|
328
380
|
response = nil
|
329
|
-
|
330
|
-
(print '(o = Step out of | s = Skip = Step over | default = Step into > '; response = $stdin.gets) if @interactive
|
381
|
+
if @interactive && !(@last_call == current_call)
|
382
|
+
#(print '(o = Step out of | s = Skip = Step over | default = Step into > '; response = $stdin.gets) if @interactive
|
383
|
+
|
384
|
+
print "Debugger (" +
|
385
|
+
"Step out".menu_item(:red, 'u') + ' | ' +
|
386
|
+
"Step over (or Enter key)".menu_item(:cyan, 'v') + ' | ' +
|
387
|
+
"Step into (Space or any key)".menu_item(:green, 'i') +
|
388
|
+
') > '
|
389
|
+
response = $stdin.getc.chr.downcase
|
331
390
|
end
|
332
391
|
if response
|
333
|
-
|
392
|
+
case response
|
393
|
+
when 'u' # Step out
|
334
394
|
@silent_until_return_to_this_depth = @internal_depth - 1
|
335
|
-
|
395
|
+
when 'v', "\n" # Step over = Ignore anything with a greater depth.
|
396
|
+
@only_makes_sense_if_next_event_is_call = true
|
336
397
|
@silent_until_return_to_this_depth = @internal_depth
|
398
|
+
else
|
399
|
+
# 'i', ' ', or any other key will simply do the default, which is to keep right on tracing...
|
337
400
|
end
|
338
401
|
end
|
339
402
|
|
@@ -1331,3 +1394,8 @@ if $0 == __FILE__
|
|
1331
1394
|
herald '-----------------------------------------------------------'
|
1332
1395
|
|
1333
1396
|
end # if $0 == __FILE__ (Tests)
|
1397
|
+
|
1398
|
+
ensure # Or should this be in an at_exit?
|
1399
|
+
# Set terminal_attributes back to how we found them...
|
1400
|
+
Termios.tcsetattr(STDIN, 0, save_terminal_attributes)
|
1401
|
+
end
|
metadata
CHANGED
@@ -3,13 +3,13 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: unroller
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
6
|
+
version: 0.0.19
|
7
7
|
date: 2007-06-05 00:00:00 -07:00
|
8
|
-
summary: A tool for generating human-readable "execution traces"
|
8
|
+
summary: "Ruby Code Unroller: A tool for generating human-readable \"execution traces\""
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email:
|
12
|
-
homepage: http://
|
12
|
+
homepage: http://unroller.rubyforge.org
|
13
13
|
rubyforge_project: unroller
|
14
14
|
description: A debugging/tracing tool for Ruby. While it is enabled, it will watch every Ruby statement and method call that gets executed and will display the source code that is being executed in real time on your screen.
|
15
15
|
autorequire:
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: 0.0.0
|
77
77
|
version:
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
79
|
+
name: termios
|
80
80
|
version_requirement:
|
81
81
|
version_requirements: !ruby/object:Gem::Version::Requirement
|
82
82
|
requirements:
|