rudebug 0.3.0 → 0.3.1

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.
@@ -1,109 +1,109 @@
1
- class Connection
2
- class RemoteException < Exception
3
- end
4
-
5
- class Base
6
- attr_accessor :on_session, :on_disconnect
7
-
8
- Code = <<-END_CODE
9
- $rudebug = Module.new do
10
- extend self
11
-
12
- def inspect()
13
- "$rudebug"
14
- end
15
- alias :name :inspect
16
-
17
- attr_accessor :selected
18
-
19
- const_set(:Refs, [])
20
-
21
- def add_ref(ref)
22
- $rudebug::Refs << ref
23
- return ref
24
- end
25
-
26
- const_set(:Pairs, Class.new {
27
- def self.[](*pairs)
28
- new(*pairs)
29
- end
30
-
31
- def self.to_s()
32
- "$rudebug::Pairs"
33
- end
34
-
35
- def initialize(*pairs)
36
- @pairs = pairs
37
- end
38
-
39
- def inspect()
40
- "{ %s }" % @pairs.map do |key, value|
41
- [
42
- key.is_a?(Numeric) ? key : key.to_sym.inspect,
43
- $rudebug.inspect_obj(value)
44
- ].join(" => ")
45
- end.join(", ")
46
- end
47
-
48
- def each(&block)
49
- @pairs.each(&block)
50
- end
51
-
52
- def size()
53
- @pairs.size
54
- end
55
-
56
- include Enumerable
57
- })
58
-
59
- def to_pairs(items, &block)
60
- $rudebug::Pairs[*items.map { |item| [item, block.call(item)] }]
61
- end
62
-
63
- def to_list(items)
64
- to_pairs(0 .. items.size - 1) { |idx| items[idx] }
65
- end
66
-
67
- def inspect_obj(obj)
68
- case obj
69
- when UnboundMethod, Method then
70
- inspect_method(obj)
71
- else
72
- #require 'pp'
73
- #PP.pp(obj, "", 30).chomp
74
- obj.inspect
75
- end
76
- end
77
-
78
- def inspect_method(method)
79
- re = /^\x23<(?:Unbound)?Method: ([^(]+)(?:\\(([^)]+)\\))?\x23(.+?)>$/
80
- if md = re.match(method.inspect) then
81
- klass, diff_origin, name = *md.captures
82
- origin = diff_origin || klass
83
- argc = method.arity
84
- more = argc < 0
85
- argc = -argc if more
86
-
87
- old_name = "a"
88
- args = (1 .. argc).map do |idx|
89
- arg_name = old_name.dup
90
- old_name.succ!
91
- arg_name
92
- end
93
- args[-1][0, 0] = "*" if more
94
-
95
- "%s\x23%s(%s)" % [origin, name, args.join(", ")]
96
- else
97
- method.inspect
98
- end
99
- end
100
- end
101
- END_CODE
102
-
103
- def self.load_rudebug_code(session)
104
- session.eval(Code)
105
- end
106
- end
107
- end
108
-
109
- eval(Connection::Base::Code)
1
+ class Connection
2
+ class RemoteException < Exception
3
+ end
4
+
5
+ class Base
6
+ attr_accessor :on_session, :on_disconnect
7
+
8
+ Code = <<-END_CODE
9
+ $rudebug = Module.new do
10
+ extend self
11
+
12
+ def inspect()
13
+ "$rudebug"
14
+ end
15
+ alias :name :inspect
16
+
17
+ attr_accessor :selected
18
+
19
+ const_set(:Refs, [])
20
+
21
+ def add_ref(ref)
22
+ $rudebug::Refs << ref
23
+ return ref
24
+ end
25
+
26
+ const_set(:Pairs, Class.new {
27
+ def self.[](*pairs)
28
+ new(*pairs)
29
+ end
30
+
31
+ def self.to_s()
32
+ "$rudebug::Pairs"
33
+ end
34
+
35
+ def initialize(*pairs)
36
+ @pairs = pairs
37
+ end
38
+
39
+ def inspect()
40
+ "{ %s }" % @pairs.map do |key, value|
41
+ [
42
+ key.is_a?(Numeric) ? key : key.to_sym.inspect,
43
+ $rudebug.inspect_obj(value)
44
+ ].join(" => ")
45
+ end.join(", ")
46
+ end
47
+
48
+ def each(&block)
49
+ @pairs.each(&block)
50
+ end
51
+
52
+ def size()
53
+ @pairs.size
54
+ end
55
+
56
+ include Enumerable
57
+ })
58
+
59
+ def to_pairs(items, &block)
60
+ $rudebug::Pairs[*items.map { |item| [item, block.call(item)] }]
61
+ end
62
+
63
+ def to_list(items)
64
+ to_pairs(0 .. items.size - 1) { |idx| items[idx] }
65
+ end
66
+
67
+ def inspect_obj(obj)
68
+ case obj
69
+ when UnboundMethod, Method then
70
+ inspect_method(obj)
71
+ else
72
+ #require 'pp'
73
+ #PP.pp(obj, "", 30).chomp
74
+ obj.inspect
75
+ end
76
+ end
77
+
78
+ def inspect_method(method)
79
+ re = /^\x23<(?:Unbound)?Method: ([^(]+)(?:\\(([^)]+)\\))?\x23(.+?)>$/
80
+ if md = re.match(method.inspect) then
81
+ klass, diff_origin, name = *md.captures
82
+ origin = diff_origin || klass
83
+ argc = method.arity
84
+ more = argc < 0
85
+ argc = -argc if more
86
+
87
+ old_name = "a"
88
+ args = (1 .. argc).map do |idx|
89
+ arg_name = old_name.dup
90
+ old_name.succ!
91
+ arg_name
92
+ end
93
+ args[-1][0, 0] = "*" if more
94
+
95
+ "%s\x23%s(%s)" % [origin, name, args.join(", ")]
96
+ else
97
+ method.inspect
98
+ end
99
+ end
100
+ end
101
+ END_CODE
102
+
103
+ def self.load_rudebug_code(session)
104
+ session.eval(Code)
105
+ end
106
+ end
107
+ end
108
+
109
+ eval(Connection::Base::Code)
@@ -1,109 +1,109 @@
1
- require 'rudebug/connection/base'
2
-
3
- class Connection::Breakpoint < Connection::Base
4
- def stepping_support?()
5
- false
6
- end
7
-
8
- class Session
9
- attr_reader :title
10
-
11
- def initialize(workspace, title = nil)
12
- @workspace = workspace
13
- @title = title
14
- @done = false
15
-
16
- Connection::Base.load_rudebug_code(self)
17
- end
18
-
19
- def eval(code)
20
- @workspace.evaluate(nil, code).inspect
21
- rescue Exception => e
22
- raise(Connection::RemoteException, e.inspect)
23
- end
24
-
25
- def current_file()
26
- Kernel.eval(eval("bp.file rescue @__bp_file"))
27
- end
28
-
29
- def current_line()
30
- Kernel.eval(eval("bp.line rescue @__bp_line")).to_i
31
- end
32
-
33
- def source_code(file)
34
- Kernel.eval(eval("File.read(%p)" % file)).chomp
35
- end
36
-
37
- def continue()
38
- @done = true
39
- return nil
40
- end
41
-
42
- def done?()
43
- @done
44
- end
45
-
46
- # Safety
47
- def step_into() end
48
- def step_over() end
49
- end
50
-
51
- def connect(server)
52
- require 'breakpoint'
53
- require 'breakpoint/drb'
54
- require 'drb'
55
-
56
- DRb.start_service()
57
-
58
- @service = DRbObject.new(nil, server)
59
- @service.eval_handler = method(:eval_handler)
60
- @service.handler = method(:breakpoint_handler)
61
-
62
- @check_thread = Thread.new(
63
- @service, @on_disconnect
64
- ) do |service, on_disconnect|
65
- loop do
66
- begin
67
- service.ping
68
- rescue DRb::DRbConnError => error
69
- on_disconnect.call()
70
- disconnect()
71
- break
72
- end
73
-
74
- sleep(0.5)
75
- end
76
- end
77
- end
78
-
79
- def disconnect()
80
- begin
81
- @service.handler = nil
82
- @service.eval_handler = nil
83
- rescue Exception
84
- end
85
-
86
- @check_thread.kill if @check_thread
87
- @check_thread = nil
88
-
89
- DRb.stop_service()
90
- @service = nil
91
- end
92
-
93
- def title_filter(message)
94
- message[/"([^"]+)"/, 1] || message #"
95
- end
96
-
97
- def breakpoint_handler(workspace, message)
98
- title = title_filter(message)
99
- session = Session.new(workspace, title)
100
- @on_session.call(session)
101
- sleep 0.1 until session.done?
102
- end
103
-
104
- def eval_handler(code)
105
- result = eval(code, TOPLEVEL_BINDING)
106
- Breakpoint.undumpify(result)
107
- return result
108
- end
109
- end
1
+ require 'rudebug/connection/base'
2
+
3
+ class Connection::Breakpoint < Connection::Base
4
+ def stepping_support?()
5
+ false
6
+ end
7
+
8
+ class Session
9
+ attr_reader :title
10
+
11
+ def initialize(workspace, title = nil)
12
+ @workspace = workspace
13
+ @title = title
14
+ @done = false
15
+
16
+ Connection::Base.load_rudebug_code(self)
17
+ end
18
+
19
+ def eval(code)
20
+ @workspace.evaluate(nil, code).inspect
21
+ rescue Exception => e
22
+ raise(Connection::RemoteException, e.inspect)
23
+ end
24
+
25
+ def current_file()
26
+ Kernel.eval(eval("bp.file rescue @__bp_file"))
27
+ end
28
+
29
+ def current_line()
30
+ Kernel.eval(eval("bp.line rescue @__bp_line")).to_i
31
+ end
32
+
33
+ def source_code(file)
34
+ Kernel.eval(eval("File.read(%p)" % file)).chomp
35
+ end
36
+
37
+ def continue()
38
+ @done = true
39
+ return nil
40
+ end
41
+
42
+ def done?()
43
+ @done
44
+ end
45
+
46
+ # Safety
47
+ def step_into() end
48
+ def step_over() end
49
+ end
50
+
51
+ def connect(server)
52
+ require 'breakpoint'
53
+ require 'breakpoint/drb'
54
+ require 'drb'
55
+
56
+ DRb.start_service()
57
+
58
+ @service = DRbObject.new(nil, server)
59
+ @service.eval_handler = method(:eval_handler)
60
+ @service.handler = method(:breakpoint_handler)
61
+
62
+ @check_thread = Thread.new(
63
+ @service, @on_disconnect
64
+ ) do |service, on_disconnect|
65
+ loop do
66
+ begin
67
+ service.ping
68
+ rescue DRb::DRbConnError => error
69
+ on_disconnect.call()
70
+ disconnect()
71
+ break
72
+ end
73
+
74
+ sleep(0.5)
75
+ end
76
+ end
77
+ end
78
+
79
+ def disconnect()
80
+ begin
81
+ @service.handler = nil
82
+ @service.eval_handler = nil
83
+ rescue Exception
84
+ end
85
+
86
+ @check_thread.kill if @check_thread
87
+ @check_thread = nil
88
+
89
+ DRb.stop_service()
90
+ @service = nil
91
+ end
92
+
93
+ def title_filter(message)
94
+ message[/"([^"]+)"/, 1] || message #"
95
+ end
96
+
97
+ def breakpoint_handler(workspace, message)
98
+ title = title_filter(message)
99
+ session = Session.new(workspace, title)
100
+ @on_session.call(session)
101
+ sleep 0.1 until session.done?
102
+ end
103
+
104
+ def eval_handler(code)
105
+ result = eval(code, TOPLEVEL_BINDING)
106
+ Breakpoint.undumpify(result)
107
+ return result
108
+ end
109
+ end
@@ -1,133 +1,133 @@
1
- require 'rudebug/connection/base'
2
-
3
- class Connection::RubyDebug < Connection::Base
4
- def stepping_support?()
5
- true
6
- end
7
-
8
- class Session
9
- attr_reader :title
10
-
11
- def initialize(connection, location)
12
- @connection = connection
13
- @location = location
14
- @title = location.join(":")
15
- @done = false
16
-
17
- Connection::Base.load_rudebug_code(self)
18
- end
19
-
20
- def execute(cmd)
21
- result = @connection.execute(cmd)
22
- result ? result.chomp : result
23
- end
24
-
25
- def eval(code)
26
- cmd = %(
27
- p begin;
28
- [eval(%p, nil, *([
29
- caller[0].split(":")[0],
30
- caller[0].split(":")[1].to_i
31
- ] rescue [])).inspect, nil];
32
- rescue Exception;
33
- [nil, $!.inspect];
34
- end
35
- ).strip.gsub(/\n\s*/, "")
36
- result, error = *Kernel.eval(execute(cmd % [code, @location]))
37
-
38
- raise(Connection::RemoteException, error) if error
39
- return result
40
- end
41
-
42
- def current_file()
43
- @location[0]
44
- end
45
-
46
- def current_line()
47
- @location[1].to_i
48
- end
49
-
50
- def source_code(file)
51
- Kernel.eval(eval("File.read(%p)" % file)).chomp
52
- end
53
-
54
- def generic_step(cmd)
55
- result = execute(cmd)
56
-
57
- if result then
58
- @connection.location?(result)
59
- else
60
- @connection.on_disconnect.call()
61
- @connection.disconnect()
62
- return nil
63
- end
64
- end
65
-
66
- def continue()
67
- generic_step("cont")
68
- end
69
-
70
- def step_into()
71
- generic_step("step")
72
- end
73
-
74
- def step_over()
75
- generic_step("next")
76
- end
77
- end
78
-
79
- def connect(server)
80
- require 'ruby-debug'
81
- require 'socket'
82
- require 'thread'
83
-
84
- host, port = */^(.+):(\d+)$/.match(server).captures
85
- port = port.to_i
86
-
87
- @socket = TCPSocket.new(host, port)
88
- line = @socket.gets
89
- location = location?(line)
90
-
91
- result = @socket.gets.strip rescue nil
92
- if !prompt?(result) then
93
- raise "Not a ruby-debug server"
94
- end
95
-
96
- @mutex = Mutex.new
97
-
98
- session = Session.new(self, location)
99
- @on_session.call(session)
100
- end
101
-
102
- def prompt?(line)
103
- line[/^PROMPT /] rescue nil
104
- end
105
-
106
- def location?(line)
107
- if md = /^(.+?):(\d+): /.match(line) then
108
- file, line = *md.captures
109
- [file, line.to_i]
110
- end
111
- end
112
-
113
- def execute(cmd)
114
- @mutex.synchronize do
115
- @socket.puts(cmd)
116
- result = @socket.gets
117
- prompt = @socket.gets
118
-
119
- #p result
120
- #p [:prompt, prompt]
121
- return result
122
- end
123
- end
124
-
125
- def disconnect()
126
- begin
127
- @socket.close
128
- rescue Exception
129
- end
130
-
131
- @socket = @mutex = nil
132
- end
133
- end
1
+ require 'rudebug/connection/base'
2
+
3
+ class Connection::RubyDebug < Connection::Base
4
+ def stepping_support?()
5
+ true
6
+ end
7
+
8
+ class Session
9
+ attr_reader :title
10
+
11
+ def initialize(connection, location)
12
+ @connection = connection
13
+ @location = location
14
+ @title = location.join(":")
15
+ @done = false
16
+
17
+ Connection::Base.load_rudebug_code(self)
18
+ end
19
+
20
+ def execute(cmd)
21
+ result = @connection.execute(cmd)
22
+ result ? result.chomp : result
23
+ end
24
+
25
+ def eval(code)
26
+ cmd = %(
27
+ p begin;
28
+ [eval(%p, nil, *([
29
+ caller[0].split(":")[0],
30
+ caller[0].split(":")[1].to_i
31
+ ] rescue [])).inspect, nil];
32
+ rescue Exception;
33
+ [nil, $!.inspect];
34
+ end
35
+ ).strip.gsub(/\n\s*/, "")
36
+ result, error = *Kernel.eval(execute(cmd % [code, @location]))
37
+
38
+ raise(Connection::RemoteException, error) if error
39
+ return result
40
+ end
41
+
42
+ def current_file()
43
+ @location[0]
44
+ end
45
+
46
+ def current_line()
47
+ @location[1].to_i
48
+ end
49
+
50
+ def source_code(file)
51
+ Kernel.eval(eval("File.read(%p)" % file)).chomp
52
+ end
53
+
54
+ def generic_step(cmd)
55
+ result = execute(cmd)
56
+
57
+ if result then
58
+ @connection.location?(result)
59
+ else
60
+ @connection.on_disconnect.call()
61
+ @connection.disconnect()
62
+ return nil
63
+ end
64
+ end
65
+
66
+ def continue()
67
+ generic_step("cont")
68
+ end
69
+
70
+ def step_into()
71
+ generic_step("step")
72
+ end
73
+
74
+ def step_over()
75
+ generic_step("next")
76
+ end
77
+ end
78
+
79
+ def connect(server)
80
+ require 'ruby-debug'
81
+ require 'socket'
82
+ require 'thread'
83
+
84
+ host, port = */^(.+):(\d+)$/.match(server).captures
85
+ port = port.to_i
86
+
87
+ @socket = TCPSocket.new(host, port)
88
+ line = @socket.gets
89
+ location = location?(line)
90
+
91
+ result = @socket.gets.strip rescue nil
92
+ if !prompt?(result) then
93
+ raise "Not a ruby-debug server"
94
+ end
95
+
96
+ @mutex = Mutex.new
97
+
98
+ session = Session.new(self, location)
99
+ @on_session.call(session)
100
+ end
101
+
102
+ def prompt?(line)
103
+ line[/^PROMPT /] rescue nil
104
+ end
105
+
106
+ def location?(line)
107
+ if md = /^(.+?):(\d+): /.match(line) then
108
+ file, line = *md.captures
109
+ [file, line.to_i]
110
+ end
111
+ end
112
+
113
+ def execute(cmd)
114
+ @mutex.synchronize do
115
+ @socket.puts(cmd)
116
+ result = @socket.gets
117
+ prompt = @socket.gets
118
+
119
+ #p result
120
+ #p [:prompt, prompt]
121
+ return result
122
+ end
123
+ end
124
+
125
+ def disconnect()
126
+ begin
127
+ @socket.close
128
+ rescue Exception
129
+ end
130
+
131
+ @socket = @mutex = nil
132
+ end
133
+ end