ruby-debug-ide19 0.4.10

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 (39) hide show
  1. data/CHANGES +75 -0
  2. data/ChangeLog +465 -0
  3. data/ChangeLog.archive +1073 -0
  4. data/MIT-LICENSE +24 -0
  5. data/Rakefile +110 -0
  6. data/bin/rdebug-ide +88 -0
  7. data/ext/mkrf_conf.rb +28 -0
  8. data/lib/ruby-debug-ide.rb +172 -0
  9. data/lib/ruby-debug/command.rb +169 -0
  10. data/lib/ruby-debug/commands/breakpoints.rb +129 -0
  11. data/lib/ruby-debug/commands/catchpoint.rb +52 -0
  12. data/lib/ruby-debug/commands/condition.rb +51 -0
  13. data/lib/ruby-debug/commands/control.rb +129 -0
  14. data/lib/ruby-debug/commands/enable.rb +203 -0
  15. data/lib/ruby-debug/commands/eval.rb +64 -0
  16. data/lib/ruby-debug/commands/frame.rb +155 -0
  17. data/lib/ruby-debug/commands/inspect.rb +24 -0
  18. data/lib/ruby-debug/commands/jump.rb +73 -0
  19. data/lib/ruby-debug/commands/load.rb +18 -0
  20. data/lib/ruby-debug/commands/stepping.rb +108 -0
  21. data/lib/ruby-debug/commands/threads.rb +153 -0
  22. data/lib/ruby-debug/commands/variables.rb +136 -0
  23. data/lib/ruby-debug/event_processor.rb +74 -0
  24. data/lib/ruby-debug/helper.rb +33 -0
  25. data/lib/ruby-debug/interface.rb +39 -0
  26. data/lib/ruby-debug/printers.rb +2 -0
  27. data/lib/ruby-debug/processor.rb +152 -0
  28. data/lib/ruby-debug/xml_printer.rb +268 -0
  29. data/test/rd_basic_test.rb +10 -0
  30. data/test/rd_catchpoint_test.rb +20 -0
  31. data/test/rd_condition_test.rb +11 -0
  32. data/test/rd_enable_disable_test.rb +43 -0
  33. data/test/rd_inspect_test.rb +11 -0
  34. data/test/rd_stepping_breakpoints_test.rb +36 -0
  35. data/test/rd_test_base.rb +44 -0
  36. data/test/rd_threads_and_frames_test.rb +11 -0
  37. data/test/rd_variables_test.rb +11 -0
  38. data/test/ruby-debug/xml_printer_test.rb +105 -0
  39. metadata +103 -0
@@ -0,0 +1,129 @@
1
+ module Debugger
2
+ class AddBreakpoint < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ / ^\s*
7
+ b(?:reak)?
8
+ (?: \s+
9
+ (?:
10
+ (\d+) |
11
+ (.+?)[:.#]([^.:\s]+)
12
+ ))?
13
+ (?:\s+
14
+ if\s+(.+)
15
+ )?
16
+ $
17
+ /x
18
+ end
19
+
20
+ def execute
21
+ if @match[1]
22
+ line, _, _, expr = @match.captures
23
+ else
24
+ _, file, line, expr = @match.captures
25
+ end
26
+
27
+ if file.nil?
28
+ file = File.basename(@state.file)
29
+ else
30
+ if line !~ /^\d+$/
31
+ klass = debug_silent_eval(file)
32
+ if klass && !klass.kind_of?(Module)
33
+ print_error "Unknown class #{file}"
34
+ throw :debug_error
35
+ end
36
+ file = klass.name if klass
37
+ else
38
+ file = File.expand_path(file) if file.index(File::SEPARATOR) || \
39
+ File::ALT_SEPARATOR && file.index(File::ALT_SEPARATOR)
40
+ end
41
+ end
42
+
43
+ if line =~ /^\d+$/
44
+ line = line.to_i
45
+ else
46
+ line = line.intern.id2name
47
+ end
48
+
49
+ b = Debugger.add_breakpoint file, line, expr
50
+ print_breakpoint_added b
51
+ end
52
+
53
+ class << self
54
+ def help_command
55
+ 'break'
56
+ end
57
+
58
+ def help(cmd)
59
+ %{
60
+ b[reak] file:line [if expr]
61
+ b[reak] [file|class(:|.|#)]<line|method> [if expr] -
62
+ \tset breakpoint to some position, (optionally) if expr == true
63
+ }
64
+ end
65
+ end
66
+ end
67
+
68
+ class BreakpointsCommand < Command # :nodoc:
69
+ self.control = true
70
+
71
+ def regexp
72
+ /^\s*b(?:reak)?$/
73
+ end
74
+
75
+ def execute
76
+ print_breakpoints Debugger.breakpoints
77
+ end
78
+
79
+ class << self
80
+ def help_command
81
+ 'break'
82
+ end
83
+
84
+ def help(cmd)
85
+ %{
86
+ b[reak]\tlist breakpoints
87
+ }
88
+ end
89
+ end
90
+ end
91
+
92
+ class DeleteBreakpointCommand < Command # :nodoc:
93
+ self.control = true
94
+
95
+ def regexp
96
+ /^\s*del(?:ete)?(?:\s+(.*))?$/
97
+ end
98
+
99
+ def execute
100
+ brkpts = @match[1]
101
+ unless brkpts
102
+ Debugger.breakpoints.clear
103
+ else
104
+ brkpts.split(/[ \t]+/).each do |pos|
105
+ pos = get_int(pos, "Delete", 1)
106
+ return unless pos
107
+ b = Debugger.remove_breakpoint(pos)
108
+ if b
109
+ print_breakpoint_deleted b
110
+ else
111
+ print_error "No breakpoint number %d\n", pos
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ class << self
118
+ def help_command
119
+ 'delete'
120
+ end
121
+
122
+ def help(cmd)
123
+ %{
124
+ del[ete][ nnn...]\tdelete some or all breakpoints
125
+ }
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,52 @@
1
+ module Debugger
2
+ class CatchCommand < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ /^\s* cat(?:ch)?
7
+ (?:\s+ (\S+))?
8
+ (?:\s+ (off))? \s* $/ix
9
+ end
10
+
11
+ def execute
12
+ excn = @match[1]
13
+ if not excn
14
+ # No args given.
15
+ errmsg "Exception class must be specified for 'catch' command"
16
+ elsif not @match[2]
17
+ # One arg given.
18
+ if 'off' == excn
19
+ Debugger.catchpoints.clear
20
+ else
21
+ binding = @state.context ? get_binding : TOPLEVEL_BINDING
22
+ unless debug_eval("#{excn}.is_a?(Class)", binding)
23
+ print_msg "Warning #{excn} is not known to be a Class"
24
+ end
25
+ Debugger.add_catchpoint(excn)
26
+ print_catchpoint_set(excn)
27
+ end
28
+ elsif @match[2] != 'off'
29
+ errmsg "Off expected. Got %s\n", @match[2]
30
+ elsif Debugger.catchpoints.member?(excn)
31
+ Debugger.catchpoints.delete(excn)
32
+ print_catchpoint_set(excn)
33
+ #print "Catch for exception %s removed.\n", excn
34
+ else
35
+ errmsg "Catch for exception %s not found.\n", excn
36
+ end
37
+ end
38
+
39
+ class << self
40
+ def help_command
41
+ 'catch'
42
+ end
43
+
44
+ def help(cmd)
45
+ %{
46
+ cat[ch]\t\t\tshow catchpoint
47
+ cat[ch] <an Exception>\tset catchpoint to an exception
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,51 @@
1
+ module Debugger
2
+
3
+ class ConditionCommand < Command # :nodoc:
4
+ self.control = true
5
+
6
+ def regexp
7
+ /^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix
8
+ end
9
+
10
+ def execute
11
+ if not @match[1]
12
+ errmsg "\"condition\" must be followed a breakpoint number and expression\n"
13
+ else
14
+ breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
15
+ largest = breakpoints.inject(0) do |largest, b|
16
+ largest = b.id if b.id > largest
17
+ end
18
+ if 0 == largest
19
+ print "No breakpoints have been set.\n"
20
+ return
21
+ end
22
+ pos = get_int(@match[1], "Condition", 1, largest)
23
+ return unless pos
24
+ breakpoints.each do |b|
25
+ if b.id == pos
26
+ b.expr = @match[2].empty? ? nil : @match[2]
27
+ print_contdition_set(b.id)
28
+ break
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+
35
+ class << self
36
+ def help_command
37
+ 'condition'
38
+ end
39
+
40
+ def help(cmd)
41
+ %{
42
+ Condition breakpoint-number expression
43
+ Specify breakpoint number N to break only if COND is true.
44
+ N is an integer and COND is an expression to be evaluated whenever
45
+ breakpoint N is reached. If the empty string is used, the condition is removed.
46
+ }
47
+ end
48
+ end
49
+ end
50
+
51
+ end # module Debugger
@@ -0,0 +1,129 @@
1
+ module Debugger
2
+ class QuitCommand < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ /^\s*(?:q(?:uit)?|exit)\s*$/
7
+ end
8
+
9
+ def execute
10
+ begin
11
+ @printer.print_msg("finished")
12
+ @printer.print_debug("Exiting debugger.")
13
+ ensure
14
+ exit! # exit -> exit!: No graceful way to stop threads...
15
+ end
16
+ end
17
+
18
+ class << self
19
+ def help_command
20
+ %w[quit exit]
21
+ end
22
+
23
+ def help(cmd)
24
+ %{
25
+ q[uit]\texit from debugger,
26
+ exit\talias to quit
27
+ }
28
+ end
29
+ end
30
+ end
31
+
32
+ class RestartCommand < Command # :nodoc:
33
+ self.control = true
34
+
35
+ def regexp
36
+ / ^\s*
37
+ (restart|R)
38
+ (\s+ \S+ .*)?
39
+ $
40
+ /x
41
+ end
42
+
43
+ def execute
44
+ if not defined? Debugger::RDEBUG_SCRIPT or not defined? Debugger::ARGV
45
+ print "We are not in a context we can restart from.\n"
46
+ return
47
+ end
48
+ if @match[2]
49
+ args = Debugger::PROG_SCRIPT + " " + @match[2]
50
+ else
51
+ args = Debugger::ARGV.join(" ")
52
+ end
53
+
54
+ # An execv would be preferable to the "exec" below.
55
+ cmd = Debugger::RDEBUG_SCRIPT + " " + args
56
+ print "Re exec'ing:\n\t#{cmd}\n"
57
+ exec cmd
58
+ end
59
+
60
+ class << self
61
+ def help_command
62
+ 'restart'
63
+ end
64
+
65
+ def help(cmd)
66
+ %{
67
+ restart|R [args]
68
+ Restart the program. This is is a re-exec - all debugger state
69
+ is lost. If command arguments are passed those are used.
70
+ }
71
+ end
72
+ end
73
+ end
74
+
75
+ class StartCommand < Command # :nodoc:
76
+ self.control = true
77
+
78
+ def regexp
79
+ /^\s*(start)(\s+ \S+ .*)?$/x
80
+ end
81
+
82
+ def execute
83
+ @printer.print_debug("Starting: running program script")
84
+ Debugger.run_prog_script #Debugger.prog_script_running?
85
+ end
86
+
87
+ class << self
88
+ def help_command
89
+ 'start'
90
+ end
91
+
92
+ def help(cmd)
93
+ %{
94
+ run prog script
95
+ }
96
+ end
97
+ end
98
+ end
99
+
100
+
101
+ class InterruptCommand < Command # :nodoc:
102
+ self.event = false
103
+ self.control = true
104
+ self.need_context = true
105
+
106
+ def regexp
107
+ /^\s*i(?:nterrupt)?\s*$/
108
+ end
109
+
110
+ def execute
111
+ unless Debugger.interrupt_last
112
+ context = Debugger.thread_context(Thread.main)
113
+ context.interrupt
114
+ end
115
+ end
116
+
117
+ class << self
118
+ def help_command
119
+ 'interrupt'
120
+ end
121
+
122
+ def help(cmd)
123
+ %{
124
+ i[nterrupt]\tinterrupt the program
125
+ }
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,203 @@
1
+ module Debugger
2
+ # Mix-in module to assist in command parsing.
3
+ module EnableDisableFunctions # :nodoc:
4
+ def enable_disable_breakpoints(is_enable, args)
5
+ breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
6
+ largest = breakpoints.inject(0) do |largest, b|
7
+ largest = b.id if b.id > largest
8
+ end
9
+ if 0 == largest
10
+ errmsg "No breakpoints have been set.\n"
11
+ return
12
+ end
13
+ args.each do |pos|
14
+ pos = get_int(pos, "#{is_enable} breakpoints", 1, largest)
15
+ return nil unless pos
16
+ breakpoints.each do |b|
17
+ if b.id == pos
18
+ enabled = ("Enable" == is_enable)
19
+ if enabled
20
+ unless syntax_valid?(b.expr)
21
+ errmsg("Expression \"#{b.expr}\" syntactically incorrect; breakpoint remains disabled.\n")
22
+ break
23
+ end
24
+ end
25
+ b.enabled = enabled
26
+ enabled ? print_breakpoint_enabled(b) : print_breakpoint_disabled(b)
27
+ break
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def enable_disable_display(is_enable, args)
34
+ if 0 == @state.display.size
35
+ errmsg "No display expressions have been set.\n"
36
+ return
37
+ end
38
+ args.each do |pos|
39
+ pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
40
+ return nil unless pos
41
+ @state.display[pos-1][0] = ("Enable" == is_enable)
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ class EnableCommand < Command # :nodoc:
48
+ Subcommands =
49
+ [
50
+ ['breakpoints', 2, "Enable specified breakpoints",
51
+ "Give breakpoint numbers (separated by spaces) as arguments.
52
+ This is used to cancel the effect of the \"disable\" command."
53
+ ],
54
+ ['display', 2,
55
+ "Enable some expressions to be displayed when program stops",
56
+ "Arguments are the code numbers of the expressions to resume displaying.
57
+ Do \"info display\" to see current list of code numbers."],
58
+ ].map do |name, min, short_help, long_help|
59
+ SubcmdStruct.new(name, min, short_help, long_help)
60
+ end unless defined?(Subcommands)
61
+
62
+ def regexp
63
+ /^\s* en(?:able)? (?:\s+(.*))?$/ix
64
+ end
65
+
66
+ def execute
67
+ if not @match[1]
68
+ errmsg "\"enable\" must be followed \"display\", \"breakpoints\"" +
69
+ " or breakpoint numbers.\n"
70
+ else
71
+ args = @match[1].split(/[ \t]+/)
72
+ param = args.shift
73
+ subcmd = find(Subcommands, param)
74
+ if subcmd
75
+ send("enable_#{subcmd.name}", args)
76
+ else
77
+ send("enable_breakpoints", args.unshift(param))
78
+ end
79
+ end
80
+ end
81
+
82
+ def enable_breakpoints(args)
83
+ enable_disable_breakpoints("Enable", args)
84
+ end
85
+
86
+ def enable_display(args)
87
+ enable_disable_display("Enable", args)
88
+ end
89
+
90
+ class << self
91
+ def help_command
92
+ 'enable'
93
+ end
94
+
95
+ def help(args)
96
+ if args[1]
97
+ s = args[1]
98
+ subcmd = Subcommands.find do |try_subcmd|
99
+ (s.size >= try_subcmd.min) and
100
+ (try_subcmd.name[0..s.size-1] == s)
101
+ end
102
+ if subcmd
103
+ str = subcmd.short_help + '.'
104
+ str += "\n" + subcmd.long_help if subcmd.long_help
105
+ return str
106
+ else
107
+ return "Invalid 'enable' subcommand '#{args[1]}'."
108
+ end
109
+ end
110
+ s = %{
111
+ Enable some things.
112
+ This is used to cancel the effect of the "disable" command.
113
+ --
114
+ List of enable subcommands:
115
+ --
116
+ }
117
+ for subcmd in Subcommands do
118
+ s += "enable #{subcmd.name} -- #{subcmd.short_help}\n"
119
+ end
120
+ return s
121
+ end
122
+ end
123
+ end
124
+
125
+ class DisableCommand < Command # :nodoc:
126
+ Subcommands =
127
+ [
128
+ ['breakpoints', 1, "Disable some breakpoints",
129
+ "Arguments are breakpoint numbers with spaces in between.
130
+ A disabled breakpoint is not forgotten, but has no effect until reenabled."],
131
+ ['display', 1, "Disable some display expressions when program stops",
132
+ "Arguments are the code numbers of the expressions to stop displaying.
133
+ Do \"info display\" to see current list of code numbers."],
134
+ ].map do |name, min, short_help, long_help|
135
+ SubcmdStruct.new(name, min, short_help, long_help)
136
+ end unless defined?(Subcommands)
137
+
138
+ def regexp
139
+ /^\s* dis(?:able)? (?:\s+(.*))?$/ix
140
+ end
141
+
142
+ def execute
143
+ if not @match[1]
144
+ errmsg "\"disable\" must be followed \"display\", \"breakpoints\"" +
145
+ " or breakpoint numbers.\n"
146
+ else
147
+ args = @match[1].split(/[ \t]+/)
148
+ param = args.shift
149
+ subcmd = find(Subcommands, param)
150
+ if subcmd
151
+ send("disable_#{subcmd.name}", args)
152
+ else
153
+ send("disable_breakpoints", args.unshift(param))
154
+ end
155
+ end
156
+ end
157
+
158
+ def disable_breakpoints(args)
159
+ enable_disable_breakpoints("Disable", args)
160
+ end
161
+
162
+ def disable_display(args)
163
+ enable_disable_display("Disable", args)
164
+ end
165
+
166
+ class << self
167
+ def help_command
168
+ 'disable'
169
+ end
170
+
171
+ def help(args)
172
+ if args[1]
173
+ s = args[1]
174
+ subcmd = Subcommands.find do |try_subcmd|
175
+ (s.size >= try_subcmd.min) and
176
+ (try_subcmd.name[0..s.size-1] == s)
177
+ end
178
+ if subcmd
179
+ str = subcmd.short_help + '.'
180
+ str += "\n" + subcmd.long_help if subcmd.long_help
181
+ return str
182
+ else
183
+ return "Invalid 'disable' subcommand '#{args[1]}'."
184
+ end
185
+ end
186
+ s = %{
187
+ Disable some things.
188
+
189
+ A disabled item is not forgotten, but has no effect until reenabled.
190
+ Use the "enable" command to have it take effect again.
191
+ --
192
+ List of disable subcommands:
193
+ --
194
+ }
195
+ for subcmd in Subcommands do
196
+ s += "disable #{subcmd.name} -- #{subcmd.short_help}\n"
197
+ end
198
+ return s
199
+ end
200
+ end
201
+ end
202
+
203
+ end # module Debugger