readapt 1.4.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec.yml +38 -0
  3. data/.gitignore +16 -16
  4. data/.rspec +2 -2
  5. data/.travis.yml +19 -19
  6. data/CHANGELOG.md +103 -100
  7. data/Gemfile +4 -4
  8. data/LICENSE.txt +21 -21
  9. data/README.md +37 -37
  10. data/Rakefile +14 -14
  11. data/bin/console +14 -14
  12. data/bin/setup +8 -8
  13. data/exe/readapt +5 -5
  14. data/ext/readapt/breakpoints.c +83 -83
  15. data/ext/readapt/breakpoints.h +11 -11
  16. data/ext/readapt/extconf.rb +0 -0
  17. data/ext/readapt/frame.c +137 -137
  18. data/ext/readapt/frame.h +17 -17
  19. data/ext/readapt/inspector.c +51 -51
  20. data/ext/readapt/inspector.h +8 -8
  21. data/ext/readapt/lookup_table.c +211 -211
  22. data/ext/readapt/lookup_table.h +30 -30
  23. data/ext/readapt/monitor.c +0 -0
  24. data/ext/readapt/monitor.h +0 -0
  25. data/ext/readapt/normalize.c +62 -62
  26. data/ext/readapt/normalize.h +7 -7
  27. data/ext/readapt/readapt.c +18 -18
  28. data/ext/readapt/stack.c +86 -86
  29. data/ext/readapt/stack.h +20 -20
  30. data/ext/readapt/threads.c +1 -1
  31. data/ext/readapt/threads.h +0 -0
  32. data/lib/readapt/adapter.rb +98 -98
  33. data/lib/readapt/breakpoint.rb +21 -21
  34. data/lib/readapt/data_reader.rb +62 -62
  35. data/lib/readapt/debugger.rb +227 -227
  36. data/lib/readapt/error.rb +63 -63
  37. data/lib/readapt/finder.rb +34 -34
  38. data/lib/readapt/frame.rb +40 -40
  39. data/lib/readapt/input.rb +7 -7
  40. data/lib/readapt/message/attach.rb +11 -11
  41. data/lib/readapt/message/base.rb +32 -32
  42. data/lib/readapt/message/configuration_done.rb +11 -11
  43. data/lib/readapt/message/continue.rb +15 -15
  44. data/lib/readapt/message/disconnect.rb +13 -13
  45. data/lib/readapt/message/evaluate.rb +19 -19
  46. data/lib/readapt/message/initialize.rb +21 -21
  47. data/lib/readapt/message/launch.rb +11 -11
  48. data/lib/readapt/message/next.rb +12 -12
  49. data/lib/readapt/message/pause.rb +11 -11
  50. data/lib/readapt/message/scopes.rb +26 -26
  51. data/lib/readapt/message/set_breakpoints.rb +25 -25
  52. data/lib/readapt/message/set_exception_breakpoints.rb +11 -11
  53. data/lib/readapt/message/stack_trace.rb +38 -38
  54. data/lib/readapt/message/step_in.rb +11 -11
  55. data/lib/readapt/message/step_out.rb +11 -11
  56. data/lib/readapt/message/threads.rb +18 -18
  57. data/lib/readapt/message/variables.rb +53 -53
  58. data/lib/readapt/message.rb +62 -62
  59. data/lib/readapt/monitor.rb +0 -0
  60. data/lib/readapt/output.rb +25 -25
  61. data/lib/readapt/references.rb +27 -27
  62. data/lib/readapt/server.rb +22 -22
  63. data/lib/readapt/shell.rb +104 -104
  64. data/lib/readapt/snapshot.rb +0 -0
  65. data/lib/readapt/thread.rb +20 -20
  66. data/lib/readapt/variable.rb +0 -0
  67. data/lib/readapt/version.rb +3 -3
  68. data/lib/readapt.rb +21 -21
  69. data/readapt.gemspec +39 -39
  70. metadata +8 -7
data/ext/readapt/stack.c CHANGED
@@ -1,86 +1,86 @@
1
- #include <stdlib.h>
2
- #include "stack.h"
3
-
4
- #define STACK_CAPACITY 20
5
-
6
- /**
7
- * Allocate a stack. The `elem_size` is the expected size of each element,
8
- * e.g., `sizeof(some_struct)`. The optional `free_func` argument is a pointer
9
- * to a function that will be called when an element is popped off the stack.
10
- */
11
- readapt_stack_t *stack_alloc(size_t elem_size, void (*free_func)(void *))
12
- {
13
- readapt_stack_t *s = malloc(sizeof(readapt_stack_t));
14
- s->elem_size = elem_size;
15
- s->free_func = free_func;
16
- s->size = 0;
17
- s->capacity = 0;
18
- return s;
19
- }
20
-
21
- /**
22
- * Add an element to the end of the stack
23
- */
24
- void stack_push(readapt_stack_t *stack, void *element)
25
- {
26
- if (stack->size == stack->capacity)
27
- {
28
- if (stack->capacity == 0)
29
- {
30
- stack->capacity = STACK_CAPACITY;
31
- stack->elements = malloc(stack->elem_size * stack->capacity);
32
- }
33
- else
34
- {
35
- stack->capacity += STACK_CAPACITY;
36
- stack->elements = realloc(stack->elements, stack->elem_size * stack->capacity);
37
- }
38
- }
39
- stack->elements[stack->size] = element;
40
- stack->size++;
41
- }
42
-
43
- /**
44
- * Get a pointer to the last element in the stack.
45
- */
46
- void *stack_peek(readapt_stack_t *stack)
47
- {
48
- return stack->size == 0 ? NULL : stack->elements[stack->size - 1];
49
- }
50
-
51
- /**
52
- * Pop the last element off the stack and pass it to free_func.
53
- */
54
- void stack_pop(readapt_stack_t *stack)
55
- {
56
- void *e;
57
-
58
- if (stack->size > 0)
59
- {
60
- e = stack->elements[stack->size - 1];
61
- if (stack->free_func)
62
- {
63
- stack->free_func(e);
64
- }
65
- // stack->elements[stack->size - 1] = NULL;
66
- stack->size--;
67
- }
68
- }
69
-
70
- /**
71
- * Free the stack from memory. If it still contains any elements, pass them to
72
- * free_func.
73
- */
74
- void stack_free(readapt_stack_t *stack)
75
- {
76
- int i;
77
-
78
- if (stack->free_func)
79
- {
80
- for (i = 0; i < stack->size; i++)
81
- {
82
- stack->free_func(stack->elements[i]);
83
- }
84
- }
85
- free(stack);
86
- }
1
+ #include <stdlib.h>
2
+ #include "stack.h"
3
+
4
+ #define STACK_CAPACITY 20
5
+
6
+ /**
7
+ * Allocate a stack. The `elem_size` is the expected size of each element,
8
+ * e.g., `sizeof(some_struct)`. The optional `free_func` argument is a pointer
9
+ * to a function that will be called when an element is popped off the stack.
10
+ */
11
+ readapt_stack_t *stack_alloc(size_t elem_size, void (*free_func)(void *))
12
+ {
13
+ readapt_stack_t *s = malloc(sizeof(readapt_stack_t));
14
+ s->elem_size = elem_size;
15
+ s->free_func = free_func;
16
+ s->size = 0;
17
+ s->capacity = 0;
18
+ return s;
19
+ }
20
+
21
+ /**
22
+ * Add an element to the end of the stack
23
+ */
24
+ void stack_push(readapt_stack_t *stack, void *element)
25
+ {
26
+ if (stack->size == stack->capacity)
27
+ {
28
+ if (stack->capacity == 0)
29
+ {
30
+ stack->capacity = STACK_CAPACITY;
31
+ stack->elements = malloc(stack->elem_size * stack->capacity);
32
+ }
33
+ else
34
+ {
35
+ stack->capacity += STACK_CAPACITY;
36
+ stack->elements = realloc(stack->elements, stack->elem_size * stack->capacity);
37
+ }
38
+ }
39
+ stack->elements[stack->size] = element;
40
+ stack->size++;
41
+ }
42
+
43
+ /**
44
+ * Get a pointer to the last element in the stack.
45
+ */
46
+ void *stack_peek(readapt_stack_t *stack)
47
+ {
48
+ return stack->size == 0 ? NULL : stack->elements[stack->size - 1];
49
+ }
50
+
51
+ /**
52
+ * Pop the last element off the stack and pass it to free_func.
53
+ */
54
+ void stack_pop(readapt_stack_t *stack)
55
+ {
56
+ void *e;
57
+
58
+ if (stack->size > 0)
59
+ {
60
+ e = stack->elements[stack->size - 1];
61
+ if (stack->free_func)
62
+ {
63
+ stack->free_func(e);
64
+ }
65
+ // stack->elements[stack->size - 1] = NULL;
66
+ stack->size--;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Free the stack from memory. If it still contains any elements, pass them to
72
+ * free_func.
73
+ */
74
+ void stack_free(readapt_stack_t *stack)
75
+ {
76
+ int i;
77
+
78
+ if (stack->free_func)
79
+ {
80
+ for (i = 0; i < stack->size; i++)
81
+ {
82
+ stack->free_func(stack->elements[i]);
83
+ }
84
+ }
85
+ free(stack);
86
+ }
data/ext/readapt/stack.h CHANGED
@@ -1,20 +1,20 @@
1
- #ifndef STACK_H_
2
- #define STACK_H_
3
-
4
- #include "stddef.h"
5
-
6
- typedef struct readapt_stack_struct {
7
- int size;
8
- size_t elem_size;
9
- void (*free_func)(void *);
10
- int capacity;
11
- void **elements;
12
- } readapt_stack_t;
13
-
14
- readapt_stack_t *stack_alloc(size_t elem_size, void(*free_func)(void*));
15
- void stack_push(readapt_stack_t *stack, void *element);
16
- void *stack_peek(readapt_stack_t *stack);
17
- void stack_pop(readapt_stack_t *stack);
18
- void stack_free(readapt_stack_t *stack);
19
-
20
- #endif
1
+ #ifndef STACK_H_
2
+ #define STACK_H_
3
+
4
+ #include "stddef.h"
5
+
6
+ typedef struct readapt_stack_struct {
7
+ int size;
8
+ size_t elem_size;
9
+ void (*free_func)(void *);
10
+ int capacity;
11
+ void **elements;
12
+ } readapt_stack_t;
13
+
14
+ readapt_stack_t *stack_alloc(size_t elem_size, void(*free_func)(void*));
15
+ void stack_push(readapt_stack_t *stack, void *element);
16
+ void *stack_peek(readapt_stack_t *stack);
17
+ void stack_pop(readapt_stack_t *stack);
18
+ void stack_free(readapt_stack_t *stack);
19
+
20
+ #endif
@@ -190,7 +190,7 @@ void initialize_threads(VALUE m_Readapt)
190
190
  {
191
191
  next_id = 1;
192
192
 
193
- c_Thread = rb_define_class_under(m_Readapt, "Thread", rb_cData);
193
+ c_Thread = rb_define_class_under(m_Readapt, "Thread", rb_cObject);
194
194
  rb_define_alloc_func(c_Thread, thread_allocate_s);
195
195
  rb_define_method(c_Thread, "id", thread_id_m, 0);
196
196
  rb_define_method(c_Thread, "frames", frames_m, 0);
File without changes
@@ -1,98 +1,98 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
-
5
- module Readapt
6
- module Adapter
7
- # @!parse include Backport::Adapter
8
-
9
- @@debugger = nil
10
-
11
- def self.host debugger
12
- @@debugger = debugger
13
- end
14
-
15
- def self.procid= pid
16
- @@procid = pid
17
- end
18
-
19
- def procid
20
- @@procid
21
- end
22
-
23
- def open_message
24
- @@open_message ||= "<readapt-#{procid}>"
25
- end
26
-
27
- def close_message
28
- @@close_message ||= "</readapt-#{procid}>"
29
- end
30
-
31
- def format result
32
- write_line result.to_protocol.to_json
33
- end
34
-
35
- def opening
36
- @@debugger.add_observer self
37
- @data_reader = DataReader.new
38
- @data_reader.set_message_handler do |message|
39
- process message
40
- end
41
- end
42
-
43
- def closing
44
- @@debugger.delete_observer(self)
45
- end
46
-
47
- def receiving data
48
- @data_reader.receive data
49
- end
50
-
51
- def update event, data
52
- obj = {
53
- type: 'event',
54
- event: event
55
- }
56
- obj[:body] = data unless data.nil?
57
- json = obj.to_json
58
- envelope = "#{open_message}Content-Length: #{json.bytesize}\r\n\r\n#{json}#{close_message}"
59
- write envelope
60
- write "#{open_message}__TERMINATE__#{close_message}" if event == 'terminated'
61
- end
62
-
63
- private
64
-
65
- # @param data [Hash]
66
- # @return [void]
67
- def process data
68
- message = Message.process(data, @@debugger)
69
- if data['seq']
70
- json = {
71
- type: 'response',
72
- request_seq: data['seq'],
73
- success: true,
74
- command: data['command'],
75
- body: message.body
76
- }.to_json
77
- envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
78
- write "#{open_message}#{envelope}#{close_message}"
79
- if data['command'] == 'disconnect'
80
- @@debugger.disconnect
81
- # @todo It does not appear necessary to close the adapter after
82
- # disconnecting the debugger.
83
- # close
84
- end
85
- return unless data['command'] == 'initialize'
86
- json = {
87
- type: 'event',
88
- event: 'initialized'
89
- }.to_json
90
- envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
91
- write "#{open_message}#{envelope}#{close_message}"
92
- end
93
- rescue RuntimeError => e
94
- STDERR.puts "[#{e.class}] #{e.message}"
95
- STDERR.puts e.backtrace.join
96
- end
97
- end
98
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Readapt
6
+ module Adapter
7
+ # @!parse include Backport::Adapter
8
+
9
+ @@debugger = nil
10
+
11
+ def self.host debugger
12
+ @@debugger = debugger
13
+ end
14
+
15
+ def self.procid= pid
16
+ @@procid = pid
17
+ end
18
+
19
+ def procid
20
+ @@procid
21
+ end
22
+
23
+ def open_message
24
+ @@open_message ||= "<readapt-#{procid}>"
25
+ end
26
+
27
+ def close_message
28
+ @@close_message ||= "</readapt-#{procid}>"
29
+ end
30
+
31
+ def format result
32
+ write_line result.to_protocol.to_json
33
+ end
34
+
35
+ def opening
36
+ @@debugger.add_observer self
37
+ @data_reader = DataReader.new
38
+ @data_reader.set_message_handler do |message|
39
+ process message
40
+ end
41
+ end
42
+
43
+ def closing
44
+ @@debugger.delete_observer(self)
45
+ end
46
+
47
+ def receiving data
48
+ @data_reader.receive data
49
+ end
50
+
51
+ def update event, data
52
+ obj = {
53
+ type: 'event',
54
+ event: event
55
+ }
56
+ obj[:body] = data unless data.nil?
57
+ json = obj.to_json
58
+ envelope = "#{open_message}Content-Length: #{json.bytesize}\r\n\r\n#{json}#{close_message}"
59
+ write envelope
60
+ write "#{open_message}__TERMINATE__#{close_message}" if event == 'terminated'
61
+ end
62
+
63
+ private
64
+
65
+ # @param data [Hash]
66
+ # @return [void]
67
+ def process data
68
+ message = Message.process(data, @@debugger)
69
+ if data['seq']
70
+ json = {
71
+ type: 'response',
72
+ request_seq: data['seq'],
73
+ success: true,
74
+ command: data['command'],
75
+ body: message.body
76
+ }.to_json
77
+ envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
78
+ write "#{open_message}#{envelope}#{close_message}"
79
+ if data['command'] == 'disconnect'
80
+ @@debugger.disconnect
81
+ # @todo It does not appear necessary to close the adapter after
82
+ # disconnecting the debugger.
83
+ # close
84
+ end
85
+ return unless data['command'] == 'initialize'
86
+ json = {
87
+ type: 'event',
88
+ event: 'initialized'
89
+ }.to_json
90
+ envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
91
+ write "#{open_message}#{envelope}#{close_message}"
92
+ end
93
+ rescue RuntimeError => e
94
+ STDERR.puts "[#{e.class}] #{e.message}"
95
+ STDERR.puts e.backtrace.join
96
+ end
97
+ end
98
+ end
@@ -1,21 +1,21 @@
1
- module Readapt
2
- class Breakpoint
3
- attr_reader :source
4
- attr_reader :line
5
- attr_reader :condition
6
- attr_reader :hit_condition
7
- attr_writer :hit_cursor
8
-
9
- def initialize source, line, condition, hit_condition
10
- @source = source
11
- @line = line
12
- @condition = condition
13
- @hit_condition = hit_condition
14
- end
15
-
16
- # @return [Integer]
17
- def hit_cursor
18
- @hit_cursor ||= 0
19
- end
20
- end
21
- end
1
+ module Readapt
2
+ class Breakpoint
3
+ attr_reader :source
4
+ attr_reader :line
5
+ attr_reader :condition
6
+ attr_reader :hit_condition
7
+ attr_writer :hit_cursor
8
+
9
+ def initialize source, line, condition, hit_condition
10
+ @source = source
11
+ @line = line
12
+ @condition = condition
13
+ @hit_condition = hit_condition
14
+ end
15
+
16
+ # @return [Integer]
17
+ def hit_cursor
18
+ @hit_cursor ||= 0
19
+ end
20
+ end
21
+ end
@@ -1,62 +1,62 @@
1
- module Readapt
2
- class DataReader
3
- def initialize
4
- @in_header = true
5
- @content_length = 0
6
- @buffer = String.new
7
- end
8
-
9
- # Declare a block to be executed for each message received from the
10
- # client.
11
- #
12
- # @yieldparam [Hash] The message received from the client
13
- def set_message_handler &block
14
- @message_handler = block
15
- end
16
-
17
- # Process raw data received from the client. The data will be parsed
18
- # into messages based on the JSON-RPC protocol. Each message will be
19
- # passed to the block declared via set_message_handler. Incomplete data
20
- # will be buffered and subsequent data will be appended to the buffer.
21
- #
22
- # @param data [String]
23
- def receive data
24
- data.each_char do |char|
25
- @buffer.concat char
26
- if @in_header
27
- prepare_to_parse_message if @buffer.end_with?("\r\n\r\n")
28
- else
29
- parse_message_from_buffer if @buffer.bytesize == @content_length
30
- end
31
- end
32
- end
33
-
34
- private
35
-
36
- def prepare_to_parse_message
37
- @in_header = false
38
- @buffer.each_line do |line|
39
- parts = line.split(':').map(&:strip)
40
- if parts[0] == 'Content-Length'
41
- @content_length = parts[1].to_i
42
- break
43
- end
44
- end
45
- @buffer.clear
46
- end
47
-
48
- def parse_message_from_buffer
49
- begin
50
- msg = JSON.parse(@buffer)
51
- @message_handler.call msg unless @message_handler.nil?
52
- rescue JSON::ParserError => e
53
- Solargraph::Logging.logger.warn "Failed to parse request: #{e.message}"
54
- Solargraph::Logging.logger.debug "Buffer: #{@buffer}"
55
- ensure
56
- @buffer.clear
57
- @in_header = true
58
- @content_length = 0
59
- end
60
- end
61
- end
62
- end
1
+ module Readapt
2
+ class DataReader
3
+ def initialize
4
+ @in_header = true
5
+ @content_length = 0
6
+ @buffer = String.new
7
+ end
8
+
9
+ # Declare a block to be executed for each message received from the
10
+ # client.
11
+ #
12
+ # @yieldparam [Hash] The message received from the client
13
+ def set_message_handler &block
14
+ @message_handler = block
15
+ end
16
+
17
+ # Process raw data received from the client. The data will be parsed
18
+ # into messages based on the JSON-RPC protocol. Each message will be
19
+ # passed to the block declared via set_message_handler. Incomplete data
20
+ # will be buffered and subsequent data will be appended to the buffer.
21
+ #
22
+ # @param data [String]
23
+ def receive data
24
+ data.each_char do |char|
25
+ @buffer.concat char
26
+ if @in_header
27
+ prepare_to_parse_message if @buffer.end_with?("\r\n\r\n")
28
+ else
29
+ parse_message_from_buffer if @buffer.bytesize == @content_length
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def prepare_to_parse_message
37
+ @in_header = false
38
+ @buffer.each_line do |line|
39
+ parts = line.split(':').map(&:strip)
40
+ if parts[0] == 'Content-Length'
41
+ @content_length = parts[1].to_i
42
+ break
43
+ end
44
+ end
45
+ @buffer.clear
46
+ end
47
+
48
+ def parse_message_from_buffer
49
+ begin
50
+ msg = JSON.parse(@buffer)
51
+ @message_handler.call msg unless @message_handler.nil?
52
+ rescue JSON::ParserError => e
53
+ Solargraph::Logging.logger.warn "Failed to parse request: #{e.message}"
54
+ Solargraph::Logging.logger.debug "Buffer: #{@buffer}"
55
+ ensure
56
+ @buffer.clear
57
+ @in_header = true
58
+ @content_length = 0
59
+ end
60
+ end
61
+ end
62
+ end