debugger2 1.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +3 -0
  4. data/AUTHORS +10 -0
  5. data/CHANGELOG.md +65 -0
  6. data/CONTRIBUTING.md +1 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +23 -0
  9. data/OLDER_CHANGELOG +334 -0
  10. data/OLD_CHANGELOG +5655 -0
  11. data/OLD_README +122 -0
  12. data/README.md +108 -0
  13. data/Rakefile +78 -0
  14. data/bin/rdebug +397 -0
  15. data/debugger2.gemspec +29 -0
  16. data/doc/.cvsignore +42 -0
  17. data/doc/Makefile.am +63 -0
  18. data/doc/emacs-notes.txt +38 -0
  19. data/doc/hanoi.rb +35 -0
  20. data/doc/primes.rb +28 -0
  21. data/doc/rdebug-emacs.texi +1030 -0
  22. data/doc/ruby-debug.texi +3791 -0
  23. data/doc/test-tri2.rb +18 -0
  24. data/doc/tri3.rb +8 -0
  25. data/doc/triangle.rb +12 -0
  26. data/emacs/Makefile.am +130 -0
  27. data/emacs/rdebug-annotate.el +385 -0
  28. data/emacs/rdebug-breaks.el +407 -0
  29. data/emacs/rdebug-cmd.el +92 -0
  30. data/emacs/rdebug-core.el +502 -0
  31. data/emacs/rdebug-dbg.el +62 -0
  32. data/emacs/rdebug-error.el +79 -0
  33. data/emacs/rdebug-fns.el +111 -0
  34. data/emacs/rdebug-frames.el +230 -0
  35. data/emacs/rdebug-gud.el +242 -0
  36. data/emacs/rdebug-help.el +104 -0
  37. data/emacs/rdebug-info.el +83 -0
  38. data/emacs/rdebug-layouts.el +180 -0
  39. data/emacs/rdebug-locring.el +118 -0
  40. data/emacs/rdebug-output.el +106 -0
  41. data/emacs/rdebug-regexp.el +118 -0
  42. data/emacs/rdebug-secondary.el +260 -0
  43. data/emacs/rdebug-shortkey.el +175 -0
  44. data/emacs/rdebug-source.el +568 -0
  45. data/emacs/rdebug-track.el +392 -0
  46. data/emacs/rdebug-varbuf.el +150 -0
  47. data/emacs/rdebug-vars.el +125 -0
  48. data/emacs/rdebug-watch.el +132 -0
  49. data/emacs/rdebug.el +326 -0
  50. data/emacs/test/elk-test.el +242 -0
  51. data/emacs/test/test-annotate.el +103 -0
  52. data/emacs/test/test-cmd.el +116 -0
  53. data/emacs/test/test-core.el +104 -0
  54. data/emacs/test/test-fns.el +65 -0
  55. data/emacs/test/test-frames.el +62 -0
  56. data/emacs/test/test-gud.el +35 -0
  57. data/emacs/test/test-indent.el +58 -0
  58. data/emacs/test/test-regexp.el +144 -0
  59. data/emacs/test/test-shortkey.el +61 -0
  60. data/ext/ruby_debug/breakpoint.c +630 -0
  61. data/ext/ruby_debug/extconf.rb +11 -0
  62. data/ext/ruby_debug/ruby_debug.c +2203 -0
  63. data/ext/ruby_debug/ruby_debug.h +151 -0
  64. data/lib/debugger.rb +5 -0
  65. data/lib/debugger/version.rb +5 -0
  66. data/lib/debugger2.rb +6 -0
  67. data/lib/ruby-debug-base.rb +307 -0
  68. data/lib/ruby-debug.rb +176 -0
  69. data/lib/ruby-debug/command.rb +227 -0
  70. data/lib/ruby-debug/commands/breakpoints.rb +153 -0
  71. data/lib/ruby-debug/commands/catchpoint.rb +55 -0
  72. data/lib/ruby-debug/commands/condition.rb +49 -0
  73. data/lib/ruby-debug/commands/continue.rb +38 -0
  74. data/lib/ruby-debug/commands/control.rb +107 -0
  75. data/lib/ruby-debug/commands/display.rb +120 -0
  76. data/lib/ruby-debug/commands/edit.rb +48 -0
  77. data/lib/ruby-debug/commands/enable.rb +202 -0
  78. data/lib/ruby-debug/commands/eval.rb +176 -0
  79. data/lib/ruby-debug/commands/finish.rb +42 -0
  80. data/lib/ruby-debug/commands/frame.rb +301 -0
  81. data/lib/ruby-debug/commands/help.rb +56 -0
  82. data/lib/ruby-debug/commands/info.rb +467 -0
  83. data/lib/ruby-debug/commands/irb.rb +123 -0
  84. data/lib/ruby-debug/commands/jump.rb +66 -0
  85. data/lib/ruby-debug/commands/kill.rb +51 -0
  86. data/lib/ruby-debug/commands/list.rb +94 -0
  87. data/lib/ruby-debug/commands/method.rb +84 -0
  88. data/lib/ruby-debug/commands/quit.rb +39 -0
  89. data/lib/ruby-debug/commands/reload.rb +40 -0
  90. data/lib/ruby-debug/commands/save.rb +90 -0
  91. data/lib/ruby-debug/commands/set.rb +223 -0
  92. data/lib/ruby-debug/commands/show.rb +247 -0
  93. data/lib/ruby-debug/commands/skip.rb +35 -0
  94. data/lib/ruby-debug/commands/source.rb +36 -0
  95. data/lib/ruby-debug/commands/stepping.rb +81 -0
  96. data/lib/ruby-debug/commands/threads.rb +189 -0
  97. data/lib/ruby-debug/commands/tmate.rb +36 -0
  98. data/lib/ruby-debug/commands/trace.rb +57 -0
  99. data/lib/ruby-debug/commands/variables.rb +199 -0
  100. data/lib/ruby-debug/debugger.rb +5 -0
  101. data/lib/ruby-debug/helper.rb +69 -0
  102. data/lib/ruby-debug/interface.rb +232 -0
  103. data/lib/ruby-debug/processor.rb +474 -0
  104. data/man/rdebug.1 +241 -0
  105. data/old_scripts/Makefile.am +14 -0
  106. data/old_scripts/README.md +2 -0
  107. data/old_scripts/autogen.sh +4 -0
  108. data/old_scripts/configure.ac +12 -0
  109. data/old_scripts/rdbg.rb +33 -0
  110. data/old_scripts/runner.sh +7 -0
  111. data/old_scripts/svn2cl_usermap +3 -0
  112. data/test/.cvsignore +1 -0
  113. data/test/breakpoints_test.rb +366 -0
  114. data/test/conditions_test.rb +77 -0
  115. data/test/continue_test.rb +28 -0
  116. data/test/display_test.rb +143 -0
  117. data/test/edit_test.rb +55 -0
  118. data/test/eval_test.rb +94 -0
  119. data/test/examples/breakpoint1.rb +15 -0
  120. data/test/examples/breakpoint2.rb +7 -0
  121. data/test/examples/conditions.rb +4 -0
  122. data/test/examples/continue.rb +4 -0
  123. data/test/examples/display.rb +5 -0
  124. data/test/examples/edit.rb +3 -0
  125. data/test/examples/edit2.rb +3 -0
  126. data/test/examples/eval.rb +4 -0
  127. data/test/examples/finish.rb +20 -0
  128. data/test/examples/frame.rb +31 -0
  129. data/test/examples/help.rb +2 -0
  130. data/test/examples/info.rb +48 -0
  131. data/test/examples/info2.rb +3 -0
  132. data/test/examples/irb.rb +6 -0
  133. data/test/examples/jump.rb +14 -0
  134. data/test/examples/kill.rb +2 -0
  135. data/test/examples/list.rb +12 -0
  136. data/test/examples/method.rb +15 -0
  137. data/test/examples/post_mortem.rb +19 -0
  138. data/test/examples/quit.rb +2 -0
  139. data/test/examples/reload.rb +6 -0
  140. data/test/examples/restart.rb +6 -0
  141. data/test/examples/save.rb +3 -0
  142. data/test/examples/set.rb +3 -0
  143. data/test/examples/set_annotate.rb +12 -0
  144. data/test/examples/settings.rb +1 -0
  145. data/test/examples/show.rb +2 -0
  146. data/test/examples/source.rb +3 -0
  147. data/test/examples/stepping.rb +21 -0
  148. data/test/examples/thread.rb +32 -0
  149. data/test/examples/tmate.rb +10 -0
  150. data/test/examples/trace.rb +7 -0
  151. data/test/examples/trace_threads.rb +20 -0
  152. data/test/examples/variables.rb +26 -0
  153. data/test/finish_test.rb +49 -0
  154. data/test/frame_test.rb +140 -0
  155. data/test/help_test.rb +51 -0
  156. data/test/info_test.rb +326 -0
  157. data/test/irb_test.rb +82 -0
  158. data/test/jump_test.rb +70 -0
  159. data/test/kill_test.rb +49 -0
  160. data/test/list_test.rb +147 -0
  161. data/test/method_test.rb +72 -0
  162. data/test/post_mortem_test.rb +25 -0
  163. data/test/quit_test.rb +56 -0
  164. data/test/reload_test.rb +47 -0
  165. data/test/restart_test.rb +145 -0
  166. data/test/save_test.rb +94 -0
  167. data/test/set_test.rb +183 -0
  168. data/test/show_test.rb +294 -0
  169. data/test/source_test.rb +46 -0
  170. data/test/stepping_test.rb +122 -0
  171. data/test/support/breakpoint.rb +12 -0
  172. data/test/support/context.rb +14 -0
  173. data/test/support/matchers.rb +67 -0
  174. data/test/support/mocha_extensions.rb +71 -0
  175. data/test/support/processor.rb +7 -0
  176. data/test/support/test_dsl.rb +206 -0
  177. data/test/support/test_interface.rb +66 -0
  178. data/test/test_helper.rb +9 -0
  179. data/test/thread_test.rb +124 -0
  180. data/test/tmate_test.rb +45 -0
  181. data/test/trace_test.rb +156 -0
  182. data/test/variables_test.rb +116 -0
  183. metadata +319 -0
@@ -0,0 +1,35 @@
1
+ module Debugger
2
+
3
+ # Implements debugger "skip" command
4
+ class SkipCommand < Command
5
+ self.allow_in_control = true
6
+
7
+ def regexp
8
+ / ^\s*
9
+ sk(?:ip)? \s*
10
+ $
11
+ /ix
12
+ end
13
+
14
+ def execute
15
+ Debugger::skip_next_exception
16
+ print "ok\n"
17
+ end
18
+
19
+ class << self
20
+ def help_command
21
+ %w[skip]
22
+ end
23
+
24
+ def help(cmd)
25
+ %{
26
+ sk[ip]\tskip the next thrown exception
27
+
28
+ This is useful if you've explicitly caught an exception through
29
+ the "catch" command, and wish to pass the exception on to the
30
+ code that you're debugging.
31
+ }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ module Debugger
2
+ # Implements debugger "source" command.
3
+ class SourceCommand < Command
4
+ self.allow_in_control = true
5
+
6
+ def regexp
7
+ /^\s* so(?:urce)? \s+ (.+) $/x
8
+ end
9
+
10
+ def execute
11
+ file = File.expand_path(@match[1]).strip
12
+ unless File.exist?(file)
13
+ errmsg "Command file '#{file}' is not found\n"
14
+ return
15
+ end
16
+ if @state and @state.interface
17
+ @state.interface.command_queue += File.open(file).readlines
18
+ else
19
+ Debugger.run_script(file, @state)
20
+ end
21
+ end
22
+
23
+ class << self
24
+ def help_command
25
+ 'source'
26
+ end
27
+
28
+ def help(cmd)
29
+ %{
30
+ source FILE\texecutes a file containing debugger commands
31
+ }
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,81 @@
1
+ module Debugger
2
+ # Mix-in module to assist in command parsing.
3
+ module SteppingFunctions # :nodoc:
4
+ def parse_stepping_args(command_name, match)
5
+ if match[1].nil?
6
+ force = Command.settings[:force_stepping]
7
+ elsif match[1] == '+'
8
+ force = true
9
+ elsif match[1] == '-'
10
+ force = false
11
+ end
12
+ steps = get_int(match[2], command_name, 1)
13
+ return [steps, force]
14
+ end
15
+ end
16
+ # Implements debugger "next" command.
17
+ class NextCommand < Command
18
+ self.allow_in_post_mortem = false
19
+ self.need_context = true
20
+
21
+ def regexp
22
+ /^\s* n(?:ext)?
23
+ ([+-])?(?:\s+(\S+))?
24
+ \s*$/x
25
+ end
26
+
27
+ def execute
28
+ steps, force = parse_stepping_args("Next", @match)
29
+ return unless steps
30
+ @state.context.step_over steps, @state.frame_pos, force
31
+ @state.proceed
32
+ end
33
+
34
+ class << self
35
+ def help_command
36
+ 'next'
37
+ end
38
+
39
+ def help(cmd)
40
+ %{
41
+ n[ext][+-]?[ nnn]\tstep over once or nnn times,
42
+ \t\t'+' forces to move to another line.
43
+ \t\t'-' is the opposite of '+' and disables the force_stepping setting.
44
+ }
45
+ end
46
+ end
47
+ end
48
+
49
+ # Implements debugger "step" command.
50
+ class StepCommand < Command
51
+ self.allow_in_post_mortem = false
52
+ self.need_context = true
53
+
54
+ def regexp
55
+ /^\s* s(?:tep)?
56
+ ([+-])?(?:\s+(\S+))?
57
+ \s*$/x
58
+ end
59
+
60
+ def execute
61
+ steps, force = parse_stepping_args("Step", @match)
62
+ return unless steps
63
+ @state.context.step(steps, force)
64
+ @state.proceed
65
+ end
66
+
67
+ class << self
68
+ def help_command
69
+ 'step'
70
+ end
71
+
72
+ def help(cmd)
73
+ %{
74
+ s[tep][+-]?[ nnn]\tstep (into methods) once or nnn times
75
+ \t\t'+' forces to move to another line.
76
+ \t\t'-' is the opposite of '+' and disables the force_stepping setting.
77
+ }
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,189 @@
1
+ module Debugger
2
+ module ThreadFunctions # :nodoc:
3
+ def display_context(c, show_top_frame=true)
4
+ c_flag = c.thread == Thread.current ? '+' : ' '
5
+ c_flag = '$' if c.suspended?
6
+ d_flag = c.ignored? ? '!' : ' '
7
+ print "%s%s", c_flag, d_flag
8
+ print "%d ", c.thnum
9
+ print "%s\t", c.thread.inspect
10
+ if c.stack_size > 0 and show_top_frame
11
+ print "%s:%d", c.frame_file(0), c.frame_line(0)
12
+ end
13
+ print "\n"
14
+ end
15
+
16
+ def parse_thread_num(subcmd, arg)
17
+ if '' == arg
18
+ errmsg "'%s' needs a thread number\n" % subcmd
19
+ nil
20
+ else
21
+ thread_num = get_int(arg, "thread #{subcmd}", 1)
22
+ return nil unless thread_num
23
+ get_context(thread_num)
24
+ end
25
+ end
26
+
27
+ def parse_thread_num_for_cmd(subcmd, arg)
28
+ c = parse_thread_num(subcmd, arg)
29
+ return nil unless c
30
+ case
31
+ when nil == c
32
+ errmsg "No such thread.\n"
33
+ when @state.context == c
34
+ errmsg "It's the current thread.\n"
35
+ when c.ignored?
36
+ errmsg "Can't #{subcmd} to the debugger thread #{arg}.\n"
37
+ else # Everything is okay
38
+ return c
39
+ end
40
+ return nil
41
+ end
42
+ end
43
+
44
+ class ThreadListCommand < Command # :nodoc:
45
+ self.allow_in_control = true
46
+
47
+ def regexp
48
+ /^\s*th(?:read)?\s+l(?:ist)?\s*$/
49
+ end
50
+
51
+ def execute
52
+ threads = Debugger.contexts.sort_by{|c| c.thnum}.each do |c|
53
+ display_context(c)
54
+ end
55
+ end
56
+
57
+ class << self
58
+ def help_command
59
+ 'thread'
60
+ end
61
+
62
+ def help(cmd)
63
+ %{
64
+ th[read] l[ist]\t\t\tlist all threads
65
+ }
66
+ end
67
+ end
68
+ end
69
+
70
+ class ThreadStopCommand < Command # :nodoc:
71
+ self.allow_in_control = true
72
+ self.allow_in_post_mortem = false
73
+ self.need_context = true
74
+
75
+ def regexp
76
+ /^\s*th(?:read)?\s+stop\s*(\S*)\s*$/
77
+ end
78
+
79
+ def execute
80
+ c = parse_thread_num_for_cmd("thread stop", @match[1])
81
+ return unless c
82
+ c.suspend
83
+ display_context(c)
84
+ end
85
+
86
+ class << self
87
+ def help_command
88
+ 'thread'
89
+ end
90
+
91
+ def help(cmd)
92
+ %{
93
+ th[read] stop <nnn>\t\tstop thread nnn
94
+ }
95
+ end
96
+ end
97
+ end
98
+
99
+ class ThreadResumeCommand < Command # :nodoc:
100
+ self.allow_in_post_mortem = false
101
+ self.allow_in_control = true
102
+ self.need_context = true
103
+
104
+ def regexp
105
+ /^\s*th(?:read)?\s+resume\s*(\S*)\s*$/
106
+ end
107
+
108
+ def execute
109
+ c = parse_thread_num_for_cmd("thread resume", @match[1])
110
+ return unless c
111
+ if !c.thread.stop?
112
+ print "Already running."
113
+ return
114
+ end
115
+ c.resume
116
+ display_context(c)
117
+ end
118
+
119
+ class << self
120
+ def help_command
121
+ 'thread'
122
+ end
123
+
124
+ def help(cmd)
125
+ %{
126
+ th[read] resume <nnn>\t\tresume thread nnn
127
+ }
128
+ end
129
+ end
130
+ end
131
+
132
+ # Thread switch Must come after "Thread resume" because "switch" is
133
+ # optional
134
+
135
+ class ThreadSwitchCommand < Command # :nodoc:
136
+ self.allow_in_control = true
137
+ self.allow_in_post_mortem = false
138
+ self.need_context = true
139
+
140
+ def regexp
141
+ /^\s*th(?:read)?\s*(?:sw(?:itch)?)?\s+(\S+)\s*$/
142
+ end
143
+
144
+ def execute
145
+ c = parse_thread_num_for_cmd("thread switch", @match[1])
146
+ return unless c
147
+ display_context(c)
148
+ c.stop_next = 1
149
+ c.thread.run
150
+ @state.proceed
151
+ end
152
+
153
+ class << self
154
+ def help_command
155
+ 'thread'
156
+ end
157
+
158
+ def help(cmd)
159
+ %{
160
+ th[read] [sw[itch]] <nnn>\tswitch thread context to nnn
161
+ }
162
+ end
163
+ end
164
+ end
165
+
166
+ class ThreadCurrentCommand < Command # :nodoc:
167
+ self.need_context = true
168
+
169
+ def regexp
170
+ /^\s*th(?:read)?\s*(?:cur(?:rent)?)?\s*$/
171
+ end
172
+
173
+ def execute
174
+ display_context(@state.context)
175
+ end
176
+
177
+ class << self
178
+ def help_command
179
+ 'thread'
180
+ end
181
+
182
+ def help(cmd)
183
+ %{
184
+ th[read] [cur[rent]]\t\tshow current thread
185
+ }
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,36 @@
1
+ module Debugger
2
+ if RUBY_PLATFORM =~ /darwin/
3
+ class TextMateCommand < Command # :nodoc:
4
+ def regexp
5
+ /^\s*tm(?:ate)?(?:\s*(\d+))?$/
6
+ end
7
+
8
+ def execute
9
+ if @match[1]
10
+ frm_n = @match[1].to_i
11
+ if frm_n > @state.context.stack_size || frm_n == 0
12
+ print "Wrong frame number\n"
13
+ return
14
+ end
15
+ file, line = @state.context.frame_file(frm_n-1), @state.context.frame_line(frm_n-1)
16
+ else
17
+ file, line = @state.file, @state.line
18
+ end
19
+ %x|open 'txmt://open?url=file://#{File.expand_path(file)}&line=#{line}'|
20
+ end
21
+
22
+ class << self
23
+ def help_command
24
+ 'tmate'
25
+ end
26
+
27
+ def help(cmd)
28
+ %{
29
+ tm[ate] n\topens a current file in TextMate.
30
+ \t\tIt uses n-th frame if arg (n) is specifed.
31
+ }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,57 @@
1
+ module Debugger
2
+ class TraceCommand < Command # :nodoc:
3
+ def regexp
4
+ /^\s* tr(?:ace)? (?: \s+ (\S+)) # on |off | var(iable)
5
+ (?: \s+ (\S+))? # (all | variable-name)?
6
+ (?: \s+ (\S+))? \s* # (stop | nostop)?
7
+ $/ix
8
+ end
9
+
10
+ def execute
11
+ if @match[1] =~ /on|off/
12
+ onoff = 'on' == @match[1]
13
+ if @match[2]
14
+ Debugger.tracing = onoff
15
+ print "Tracing %s all threads.\n" % (onoff ? 'on' : 'off')
16
+ else
17
+ Debugger.current_context.tracing = onoff
18
+ print "Tracing %s on current thread.\n" % (onoff ? 'on' : 'off')
19
+ end
20
+ elsif @match[1] =~ /var(?:iable)?/
21
+ varname=@match[2]
22
+ if debug_eval("defined?(#{varname})")
23
+ if @match[3] && @match[3] !~ /(:?no)?stop/
24
+ errmsg("expecting 'stop' or 'nostop'; got %s\n" % @match[3])
25
+ else
26
+ dbg_cmd = if @match[3] && (@match[3] !~ /nostop/)
27
+ 'debugger' else '' end
28
+ end
29
+ eval("
30
+ trace_var(:#{varname}) do |val|
31
+ print \"traced variable #{varname} has value \#{val}\n\"
32
+ #{dbg_cmd}
33
+ end")
34
+ else
35
+ errmsg "#{varname} is not a global variable.\n"
36
+ end
37
+ else
38
+ errmsg("expecting 'on', 'off', 'var' or 'variable'; got: %s\n" %
39
+ @match[1])
40
+ end
41
+ end
42
+
43
+ class << self
44
+ def help_command
45
+ 'trace'
46
+ end
47
+
48
+ def help(cmd)
49
+ %{
50
+ tr[ace] (on|off)\tset trace mode of current thread
51
+ tr[ace] (on|off) all\tset trace mode of all threads
52
+ tr[ace] var(iable) VARNAME [stop|nostop]\tset trace variable on VARNAME
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,199 @@
1
+ module Debugger
2
+ module VarFunctions # :nodoc:
3
+ def var_list(ary, b = get_binding)
4
+ ary.sort!
5
+ for v in ary
6
+ begin
7
+ s = debug_eval(v.to_s, b).inspect
8
+ rescue
9
+ begin
10
+ s = debug_eval(v.to_s, b).to_s
11
+ rescue
12
+ s = "*Error in evaluation*"
13
+ end
14
+ end
15
+ if s.size > self.class.settings[:width]
16
+ s[self.class.settings[:width]-3 .. -1] = "..."
17
+ end
18
+ print "%s = %s\n", v, s
19
+ end
20
+ end
21
+ def var_class_self
22
+ obj = debug_eval('self')
23
+ var_list(obj.class.class_variables, get_binding)
24
+ end
25
+ end
26
+
27
+ # Implements the debugger 'var class' command.
28
+ class VarClassVarCommand < Command
29
+ def regexp
30
+ /^\s*v(?:ar)?\s+cl(?:ass)?/
31
+ end
32
+
33
+ def execute
34
+ unless @state.context
35
+ errmsg "can't get class variables here.\n"
36
+ return
37
+ end
38
+ var_class_self
39
+ end
40
+
41
+ class << self
42
+ def help_command
43
+ 'var'
44
+ end
45
+
46
+ def help(cmd)
47
+ %{
48
+ v[ar] cl[ass] \t\t\tshow class variables of self
49
+ }
50
+ end
51
+ end
52
+ end
53
+
54
+ class VarConstantCommand < Command # :nodoc:
55
+ def regexp
56
+ /^\s*v(?:ar)?\s+co(?:nst(?:ant)?)?\s+/
57
+ end
58
+
59
+ def execute
60
+ obj = debug_eval(@match.post_match)
61
+ if obj.kind_of? Module
62
+ constants = debug_eval("#{@match.post_match}.constants")
63
+ constants.sort!
64
+ for c in constants
65
+ next if c =~ /SCRIPT/
66
+ value = obj.const_get(c) rescue "ERROR: #{$!}"
67
+ print " %s => %p\n", c, value
68
+ end
69
+ else
70
+ print "Should be Class/Module: %s\n", @match.post_match
71
+ end
72
+ end
73
+
74
+ class << self
75
+ def help_command
76
+ 'var'
77
+ end
78
+
79
+ def help(cmd)
80
+ %{
81
+ v[ar] co[nst] <object>\t\tshow constants of object
82
+ }
83
+ end
84
+ end
85
+ end
86
+
87
+ class VarGlobalCommand < Command # :nodoc:
88
+ def regexp
89
+ /^\s*v(?:ar)?\s+g(?:lobal)?\s*$/
90
+ end
91
+
92
+ def execute
93
+ var_list(global_variables)
94
+ end
95
+
96
+ class << self
97
+ def help_command
98
+ 'var'
99
+ end
100
+
101
+ def help(cmd)
102
+ %{
103
+ v[ar] g[lobal]\t\t\tshow global variables
104
+ }
105
+ end
106
+ end
107
+ end
108
+
109
+ class VarInstanceCommand < Command # :nodoc:
110
+ def regexp
111
+ /^\s*v(?:ar)?\s+ins(?:tance)?\s*/
112
+ end
113
+
114
+ def execute
115
+ obj = debug_eval(@match.post_match.empty? ? 'self' : @match.post_match)
116
+ var_list(obj.instance_variables, obj.instance_eval{binding()})
117
+ end
118
+
119
+ class << self
120
+ def help_command
121
+ 'var'
122
+ end
123
+
124
+ def help(cmd)
125
+ %{
126
+ v[ar] i[nstance] <object>\tshow instance variables of object
127
+ }
128
+ end
129
+ end
130
+ end
131
+
132
+ # Implements the debugger 'var local' command.
133
+ class VarLocalCommand < Command
134
+ def regexp
135
+ /^\s*v(?:ar)?\s+l(?:ocal)?\s*$/
136
+ end
137
+
138
+ def execute
139
+ locals = @state.context.frame_locals(@state.frame_pos)
140
+ _self = @state.context.frame_self(@state.frame_pos)
141
+ locals.keys.sort.each do |name|
142
+ print " %s => %p\n", name, locals[name]
143
+ end
144
+ end
145
+
146
+ class << self
147
+ def help_command
148
+ 'var'
149
+ end
150
+
151
+ def help(cmd)
152
+ %{
153
+ v[ar] l[ocal]\t\t\tshow local variables
154
+ }
155
+ end
156
+ end
157
+ end
158
+
159
+ # Implements the debugger 'var inherit' command.
160
+ begin
161
+ require 'classtree'
162
+ have_classtree = true
163
+ rescue LoadError
164
+ have_classtree = false
165
+ end
166
+
167
+ class VarInheritCommand < Command
168
+ def regexp
169
+ /^\s*v(?:ar)?\s+ct\s*/
170
+ end
171
+
172
+ def execute
173
+ unless @state.context
174
+ errmsg "can't get object inheritance.\n"
175
+ return
176
+ end
177
+ puts @match.post_match
178
+ obj = debug_eval("#{@match.post_match}.classtree")
179
+ if obj
180
+ print obj
181
+ else
182
+ errmsg "Trouble getting object #{@match.post_match}\n"
183
+ end
184
+ end
185
+
186
+ class << self
187
+ def help_command
188
+ 'var'
189
+ end
190
+
191
+ def help(cmd)
192
+ %{
193
+ v[ar] ct\t\t\tshow class heirarchy of object
194
+ }
195
+ end
196
+ end
197
+ end if have_classtree
198
+
199
+ end