readapt 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4b5e04188dcfb29b88bd7d6ffaecab9e9d6803e6dc4d376b925e672007f1b5f
4
- data.tar.gz: 4feb9f343b159051ad41e45c93ee27e37d2da8d6fd5a7c2a5e09d3447956c8a2
3
+ metadata.gz: e935059da5afc7fe4f6a68e6574ad096dcf90c2b166b81f3c0e50260e3d740ba
4
+ data.tar.gz: 26f8dce0349345c4f0fa5953f179e833c8848e5cf90f57632661f97603967d4b
5
5
  SHA512:
6
- metadata.gz: 7f45a365a1baa3217b6480755e6ad77bf8ac096b19e522c5770801682675b4c7261b21e66c21c2e75e8c8784b822fc5d31fc6001f3c62b0763a2a6c049e02bf4
7
- data.tar.gz: 1cd6ca54346c2a4d9caac8516a25ab0e4e7f71773f9ff3b7b8b2a3651e582059f9bfd61d721813e59fc81be4b08c6ea5631c90621268da0b3a7824bbaafd784c
6
+ metadata.gz: 979309cb99c3e4eb81768965b2a564ae14dd057f424383b28ae4e9f4a38dded3a2afc135aaca70d04207e470fd241c195ed207ae4712e98e6efbf19ae79ec6a2
7
+ data.tar.gz: a22d57be02bb01fb3535cb7c6c3047dcb33ec6a132ead776dbea44022924cfe026de4e99eb28632e6690a3a0e920f78d2131f2a7f5dac70ecb6dda939b79e4fb
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
- --format documentation
2
1
  --color
3
2
  --require spec_helper
@@ -1,3 +1,7 @@
1
+ # 0.4.0 - August 19. 2019
2
+ - Breakpoints use C implementation of hash tables
3
+ - Simplified entry point detection
4
+
1
5
  # 0.3.5 - August 16, 2019
2
6
  - Variables message checks for null frames
3
7
 
@@ -0,0 +1,88 @@
1
+ #include "ruby.h"
2
+ #include "hash_table.h"
3
+
4
+ static VALUE m_Breakpoints;
5
+ ht_hash_table *ht;
6
+
7
+ void breakpoints_set(char *file, long *lines)
8
+ {
9
+
10
+ }
11
+
12
+ static VALUE breakpoints_set_s(VALUE self, VALUE file, VALUE lines)
13
+ {
14
+ long length = NUM2LONG(rb_funcall(lines, rb_intern("length"), 0));
15
+ long *ll;
16
+ long i;
17
+
18
+ ll = malloc(sizeof(long) * length);
19
+ for (i = 0; i < length; i++)
20
+ {
21
+ ll[i] = NUM2LONG(rb_ary_entry(lines, i));
22
+ }
23
+ ht_insert(ht, StringValueCStr(file), ll, length);
24
+ free(ll);
25
+ return Qnil;
26
+ }
27
+
28
+ void breakpoints_delete(char *file)
29
+ {
30
+
31
+ }
32
+
33
+ static VALUE breakpoints_delete_s(VALUE self, VALUE file)
34
+ {
35
+ return Qnil;
36
+ }
37
+
38
+ int breakpoints_match(char *file, long line)
39
+ {
40
+ ht_long_array *lines;
41
+ long i;
42
+
43
+ lines = ht_search(ht, file);
44
+ if (lines != NULL)
45
+ {
46
+ for (i = 0; i < lines->size; i++)
47
+ {
48
+ if (lines->items[i] == line)
49
+ {
50
+ return 1;
51
+ }
52
+ }
53
+ }
54
+ return 0;
55
+ }
56
+
57
+ // int breakpoints_match(char *file, long line)
58
+ // {
59
+ // return breakpoints_match_id(rb_intern(file), line);
60
+ // }
61
+
62
+ static VALUE breakpoints_match_s(VALUE self, VALUE file, VALUE line)
63
+ {
64
+ return breakpoints_match(StringValueCStr(file), NUM2LONG(line)) == 0 ? Qfalse : Qtrue;
65
+ }
66
+
67
+ static VALUE breakpoints_clear_s(VALUE self)
68
+ {
69
+ ht_del_hash_table(ht);
70
+ ht = ht_new();
71
+ return Qnil;
72
+ }
73
+
74
+ long breakpoints_files()
75
+ {
76
+ return ht->size;
77
+ }
78
+
79
+ void initialize_breakpoints(VALUE m_Readapt)
80
+ {
81
+ m_Breakpoints = rb_define_module_under(m_Readapt, "Breakpoints");
82
+ rb_define_singleton_method(m_Breakpoints, "set", breakpoints_set_s, 2);
83
+ rb_define_singleton_method(m_Breakpoints, "delete", breakpoints_delete_s, 1);
84
+ rb_define_singleton_method(m_Breakpoints, "match", breakpoints_match_s, 2);
85
+ rb_define_singleton_method(m_Breakpoints, "clear", breakpoints_clear_s, 0);
86
+
87
+ ht = ht_new(); // TODO Need to free?
88
+ }
@@ -0,0 +1,12 @@
1
+ #ifndef BREAKPOINTS_H_
2
+ #define BREAKPOINTS_H_
3
+
4
+ void initialize_breakpoints(VALUE m_Readapt);
5
+
6
+ void breakpoints_set(char *file, long *lines);
7
+ void breakpoints_delete(char *file);
8
+ int breakpoints_match(char *file, long line);
9
+ // int breakpoints_match_id(ht_key file, long line);
10
+ long breakpoints_files();
11
+
12
+ #endif
@@ -0,0 +1,216 @@
1
+ #include <math.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+
5
+ #include "hash_table.h"
6
+ #include "ruby.h"
7
+
8
+ static ht_long_array *copy_array(const long *value, const long size)
9
+ {
10
+ long i;
11
+ long *items = malloc(sizeof(long) * size);
12
+ ht_long_array *result;
13
+
14
+ for (i = 0; i < size; i++)
15
+ {
16
+ items[i] = value[i];
17
+ }
18
+ result = malloc(sizeof(ht_long_array));
19
+ result->items = (size ? items : NULL);
20
+ result->size = size;
21
+ return result;
22
+ }
23
+
24
+ /*
25
+ * Initialize a new item
26
+ */
27
+ static ht_item *ht_new_item(char *key, const long *value, const long size)
28
+ {
29
+ ht_item *i = malloc(sizeof(ht_item));
30
+ i->key = malloc(sizeof(char) * (strlen(key) + 1));
31
+ strcpy(i->key, key);
32
+ i->value = copy_array(value, size);
33
+ return i;
34
+ }
35
+
36
+ /*
37
+ * Delete the ht_item
38
+ */
39
+ static void ht_del_item(ht_item *i)
40
+ {
41
+ free(i->key);
42
+ free(i->value->items);
43
+ free(i);
44
+ }
45
+
46
+ /*
47
+ * Initialize a new empty hash table
48
+ */
49
+ ht_hash_table *ht_new()
50
+ {
51
+ ht_hash_table *ht = malloc(sizeof(ht_hash_table));
52
+ ht->items = NULL;
53
+ ht->size = 0;
54
+ return ht;
55
+ }
56
+
57
+ /*
58
+ * Delete the hash table
59
+ */
60
+ void ht_del_hash_table(ht_hash_table *ht)
61
+ {
62
+ int i;
63
+ ht_item *item;
64
+
65
+ // Iterate through items and delete any that are found
66
+ for (i = 0; i < ht->size; i++)
67
+ {
68
+ item = ht->items[i];
69
+ ht_del_item(item);
70
+ }
71
+ free(ht->items);
72
+ free(ht);
73
+ }
74
+
75
+ static ht_long_array *ht_search_part(ht_hash_table *ht, char *key, long cursor, long next)
76
+ {
77
+ int cmp;
78
+
79
+ if (cursor >= ht->size)
80
+ {
81
+ return NULL;
82
+ }
83
+
84
+ cmp = strcmp(ht->items[cursor]->key, key);
85
+ if (cmp == 0)
86
+ {
87
+ return ht->items[cursor]->value;
88
+ }
89
+ if (next > cursor && next < ht->size)
90
+ {
91
+ cmp = strcmp(ht->items[next]->key, key);
92
+ if (cmp == 0)
93
+ {
94
+ return ht->items[next]->value;
95
+ }
96
+ else if (cmp < 0)
97
+ {
98
+ return ht_search_part(ht, key, next + 1, next + ((ht->size - next) / 2));
99
+ }
100
+ else
101
+ {
102
+ return ht_search_part(ht, key, cursor + 1, next / 2);
103
+ }
104
+ }
105
+ return ht_search_part(ht, key, cursor + 1, next / 2);
106
+ }
107
+
108
+ static ht_long_array *ht_search_key(ht_hash_table *ht, char *key)
109
+ {
110
+ return ht_search_part(ht, key, 0, ht->size / 2);
111
+ }
112
+
113
+ static void ht_delete_key(ht_hash_table *ht, char *key)
114
+ {
115
+ ht_long_array *found;
116
+ ht_item **tmp;
117
+ long i;
118
+ long cursor = 0;
119
+
120
+ found = ht_search_key(ht, key);
121
+ if (found)
122
+ {
123
+ tmp = malloc(sizeof(ht_item) * (ht->size - 1));
124
+ for (i = 0; i < ht->size; i++)
125
+ {
126
+ if (ht->items[i]->key == key)
127
+ {
128
+ ht_del_item(ht->items[i]);
129
+ }
130
+ else
131
+ {
132
+ tmp[cursor] = ht->items[cursor];
133
+ cursor++;
134
+ }
135
+ }
136
+ free(ht->items);
137
+ ht->items = tmp;
138
+ ht->size--;
139
+ }
140
+ }
141
+
142
+ static void ht_insert_key(ht_hash_table *ht, char *key, const long *value, const long size)
143
+ {
144
+ ht_item *item;
145
+ ht_item **tmp;
146
+ long i;
147
+ long cursor = 0;
148
+ int inserted = 0;
149
+ int cmp;
150
+
151
+ ht_delete_key(ht, key);
152
+
153
+ if (size == 0)
154
+ {
155
+ return;
156
+ }
157
+
158
+ item = ht_new_item(key, value, size);
159
+ tmp = malloc(sizeof(ht_item) * (ht->size + 1));
160
+
161
+ for (i = 0; i <= ht->size; i++)
162
+ {
163
+ if (!inserted)
164
+ {
165
+ if (i == ht->size)
166
+ {
167
+ tmp[i] = item;
168
+ inserted = 1;
169
+ }
170
+ else
171
+ {
172
+ cmp = strcmp(item->key, ht->items[i]->key);
173
+ if (cmp > 0)
174
+ {
175
+ tmp[i] = item;
176
+ tmp[i + 1] = ht->items[cursor];
177
+ inserted = 1;
178
+ cursor++;
179
+ i++;
180
+ }
181
+ }
182
+ }
183
+ else
184
+ {
185
+ tmp[i] = ht->items[cursor];
186
+ cursor++;
187
+ }
188
+ }
189
+ free(ht->items);
190
+ ht->items = tmp;
191
+ ht->size++;
192
+ }
193
+
194
+ /*
195
+ * Add an item to the hash table
196
+ */
197
+ void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size)
198
+ {
199
+ ht_insert_key(ht, key, value, size);
200
+ }
201
+
202
+ /*
203
+ * Get the key's value or NULL if it doesn't exist
204
+ */
205
+ ht_long_array *ht_search(ht_hash_table *ht, char *key)
206
+ {
207
+ return ht_search_key(ht, key);
208
+ }
209
+
210
+ /*
211
+ * Delete the key's item if it exists
212
+ */
213
+ void ht_delete(ht_hash_table *ht, char *key)
214
+ {
215
+ ht_delete_key(ht, key);
216
+ }
@@ -0,0 +1,32 @@
1
+ #ifndef HASH_TABLE_H_
2
+ #define HASH_TABLE_H_
3
+
4
+ #include "ruby.h"
5
+
6
+ typedef struct ht_long_array
7
+ {
8
+ long *items;
9
+ long size;
10
+ } ht_long_array;
11
+
12
+ // ht_item is an item in the hash table
13
+ typedef struct ht_item
14
+ {
15
+ char *key;
16
+ ht_long_array *value;
17
+ } ht_item;
18
+
19
+ typedef struct ht_hash_table
20
+ {
21
+ long size;
22
+ ht_item **items;
23
+ } ht_hash_table;
24
+
25
+ ht_hash_table *ht_new();
26
+ void ht_del_hash_table(ht_hash_table *ht);
27
+
28
+ void ht_insert(ht_hash_table *ht, char *key, const long *value, const long size);
29
+ ht_long_array *ht_search(ht_hash_table *ht, char *key);
30
+ void ht_delete(ht_hash_table *h, char *key);
31
+
32
+ #endif // HASH_TABLE_H_
@@ -2,6 +2,7 @@
2
2
  #include "ruby/debug.h"
3
3
  #include "threads.h"
4
4
  #include "normalize.h"
5
+ #include "breakpoints.h"
5
6
 
6
7
  static VALUE readapt;
7
8
  static VALUE m_Monitor;
@@ -14,39 +15,16 @@ static VALUE tpReturn;
14
15
  static VALUE tpThreadBegin;
15
16
  static VALUE tpThreadEnd;
16
17
  static VALUE debugProc;
17
- static VALUE breakpoints;
18
- static int knownBreakpoints;
19
18
  static int firstLineEvent = 0;
19
+ static VALUE entryFile;
20
20
 
21
- static int match_line(VALUE next_file, int next_line, thread_reference_t *ptr)
22
- {
23
- if (rb_str_equal(next_file, ptr->prev_file) && next_line == ptr->prev_line) {
24
- return 1;
25
- }
26
- return 0;
27
- }
28
-
29
- static int match_breakpoint(VALUE file, int line)
30
- {
31
- VALUE bps, b;
32
- long len, i;
33
-
34
- bps = rb_funcall(breakpoints, rb_intern("for"), 1, file);
35
- len = rb_array_len(bps);
36
- for (i = 0; i < len; i++)
37
- {
38
- b = rb_ary_entry(bps, i);
39
- if (NUM2INT(rb_funcall(b, rb_intern("line"), 0)) == line)
40
- {
41
- return 1;
42
- }
43
- }
44
- return 0;
45
- }
21
+ static ID id_continue;
22
+ static ID id_pause;
23
+ static ID id_entry;
46
24
 
47
25
  static int match_step(thread_reference_t *ptr)
48
26
  {
49
- if (ptr->control == rb_intern("continue"))
27
+ if (ptr->control == id_continue)
50
28
  {
51
29
  return 0;
52
30
  }
@@ -66,7 +44,7 @@ static int match_step(thread_reference_t *ptr)
66
44
  }
67
45
 
68
46
  static ID
69
- monitor_debug(VALUE file, int line, VALUE tracepoint, thread_reference_t *ptr, ID event)
47
+ monitor_debug(VALUE file, long line, VALUE tracepoint, thread_reference_t *ptr, ID event)
70
48
  {
71
49
  VALUE bind, bid, snapshot, result;
72
50
 
@@ -90,8 +68,6 @@ monitor_debug(VALUE file, int line, VALUE tracepoint, thread_reference_t *ptr, I
90
68
  ptr->cursor = ptr->depth;
91
69
  ptr->control = result;
92
70
  }
93
- ptr->prev_file = file;
94
- ptr->prev_line = line;
95
71
  return result;
96
72
  }
97
73
 
@@ -99,67 +75,57 @@ static void
99
75
  process_line_event(VALUE tracepoint, void *data)
100
76
  {
101
77
  VALUE ref, tp_file;
102
- int tp_line;
78
+ long tp_line;
103
79
  thread_reference_t *ptr;
104
80
  rb_trace_arg_t *tp;
105
81
  int threadPaused;
106
- ID dapEvent, result;
82
+ ID dapEvent;
107
83
 
108
84
  ref = thread_current_reference();
109
85
  if (ref != Qnil)
110
86
  {
111
87
  ptr = thread_reference_pointer(ref);
112
- if (ptr->depth > 0 /*|| !firstLineEvent*/)
88
+ if (ptr->depth > 0)
113
89
  {
114
- threadPaused = (ptr->control == rb_intern("pause"));
115
- if (!firstLineEvent || threadPaused || knownBreakpoints || ptr->control != rb_intern("continue"))
90
+ threadPaused = (ptr->control == id_pause);
91
+ if (firstLineEvent && ptr->control == id_continue && breakpoints_files() == 0)
116
92
  {
117
- tp = rb_tracearg_from_tracepoint(tracepoint);
118
- tp_file = normalize_path(rb_tracearg_path(tp));
119
- tp_line = NUM2INT(rb_tracearg_lineno(tp));
120
-
121
- dapEvent = rb_intern("continue");
122
- if (!firstLineEvent)
123
- {
124
- dapEvent = rb_intern("initialize");
125
- }
126
- else if (threadPaused)
127
- {
128
- dapEvent = rb_intern("pause");
129
- }
130
- else if (match_step(ptr))
131
- {
132
- dapEvent = rb_intern("step");
133
- }
134
- else if (match_breakpoint(tp_file, tp_line))
135
- {
136
- dapEvent = rb_intern("breakpoint");
137
- }
138
- else if (ptr->control == rb_intern("entry"))
139
- {
140
- dapEvent = rb_intern("entry");
141
- }
93
+ return;
94
+ }
95
+ tp = rb_tracearg_from_tracepoint(tracepoint);
96
+ tp_file = normalize_path(rb_tracearg_path(tp));
97
+ tp_line = NUM2LONG(rb_tracearg_lineno(tp));
142
98
 
143
- if (dapEvent != rb_intern("continue"))
144
- {
145
- result = monitor_debug(tp_file, tp_line, tracepoint, ptr, dapEvent);
146
- if (dapEvent == rb_intern("initialize") && result == rb_intern("ready"))
147
- {
148
- firstLineEvent = 1;
149
- ptr->control = rb_intern("entry");
150
- process_line_event(tracepoint, data);
151
- }
152
- }
153
- else
99
+ dapEvent = id_continue;
100
+ if (!firstLineEvent)
101
+ {
102
+ if (rb_str_equal(tp_file, entryFile))
154
103
  {
155
- ptr->prev_file = Qnil;
156
- ptr->prev_line = Qnil;
104
+ firstLineEvent = 1;
105
+ ptr->control = rb_intern("entry");
106
+ process_line_event(tracepoint, data);
157
107
  }
158
108
  }
159
- else
109
+ else if (threadPaused)
110
+ {
111
+ dapEvent = id_pause;
112
+ }
113
+ else if (match_step(ptr))
114
+ {
115
+ dapEvent = rb_intern("step");
116
+ }
117
+ else if (breakpoints_match(StringValueCStr(tp_file), tp_line))
118
+ {
119
+ dapEvent = rb_intern("breakpoint");
120
+ }
121
+ else if (ptr->control == id_entry)
122
+ {
123
+ dapEvent = id_entry;
124
+ }
125
+
126
+ if (dapEvent != id_continue)
160
127
  {
161
- ptr->prev_file = Qnil;
162
- ptr->prev_line = Qnil;
128
+ monitor_debug(tp_file, tp_line, tracepoint, ptr, dapEvent);
163
129
  }
164
130
  }
165
131
  }
@@ -214,7 +180,7 @@ process_thread_begin_event(VALUE tracepoint, void *data)
214
180
  ptr = thread_reference_pointer(ref);
215
181
  monitor_debug(
216
182
  rb_funcall(tracepoint, rb_intern("path"), 0),
217
- NUM2INT(rb_funcall(tracepoint, rb_intern("lineno"), 0)),
183
+ NUM2LONG(rb_funcall(tracepoint, rb_intern("lineno"), 0)),
218
184
  tracepoint,
219
185
  ptr,
220
186
  rb_intern("thread_begin")
@@ -236,13 +202,13 @@ process_thread_end_event(VALUE tracepoint, void *data)
236
202
  if (ref != Qnil)
237
203
  {
238
204
  ptr = thread_reference_pointer(ref);
239
- monitor_debug(ptr->prev_file, ptr->prev_line, tracepoint, ptr, rb_intern("thread_end"));
205
+ monitor_debug(rb_funcall(tracepoint, rb_intern("path"), 0), NUM2LONG(rb_funcall(tracepoint, rb_intern("lineno"), 0)), tracepoint, ptr, rb_intern("thread_end"));
240
206
  thread_delete_reference(thr);
241
207
  }
242
208
  }
243
209
 
244
210
  static VALUE
245
- monitor_enable_s(VALUE self)
211
+ monitor_enable_s(VALUE self, VALUE file)
246
212
  {
247
213
  VALUE previous, ref;
248
214
  thread_reference_t *ptr;
@@ -254,7 +220,8 @@ monitor_enable_s(VALUE self)
254
220
  rb_raise(rb_eArgError, "must be called with a block");
255
221
  }
256
222
 
257
- firstLineEvent = 0;
223
+ entryFile = file;
224
+ firstLineEvent = (entryFile == Qnil ? 1 : 0);
258
225
 
259
226
  ref = thread_add_reference(rb_thread_current());
260
227
  ptr = thread_reference_pointer(ref);
@@ -286,7 +253,7 @@ monitor_disable_s(VALUE self)
286
253
  rb_tracepoint_disable(tpReturn);
287
254
  rb_tracepoint_disable(tpThreadBegin);
288
255
  rb_tracepoint_disable(tpThreadEnd);
289
-
256
+
290
257
  return previous;
291
258
  }
292
259
 
@@ -302,12 +269,6 @@ monitor_pause_s(VALUE self, VALUE id)
302
269
  ptr = thread_reference_pointer(ref);
303
270
  ptr->control = rb_intern("pause");
304
271
  }
305
- }
306
-
307
- static VALUE
308
- monitor_know_breakpoints_s(VALUE self)
309
- {
310
- knownBreakpoints = (rb_funcall(breakpoints, rb_intern("empty?"), 0) == Qfalse) ? 1 : 0;
311
272
  return Qnil;
312
273
  }
313
274
 
@@ -319,9 +280,8 @@ void initialize_monitor(VALUE m_Readapt)
319
280
 
320
281
  initialize_threads();
321
282
 
322
- rb_define_singleton_method(m_Monitor, "start", monitor_enable_s, 0);
283
+ rb_define_singleton_method(m_Monitor, "start", monitor_enable_s, 1);
323
284
  rb_define_singleton_method(m_Monitor, "stop", monitor_disable_s, 0);
324
- rb_define_singleton_method(m_Monitor, "know_breakpoints", monitor_know_breakpoints_s, 0);
325
285
  rb_define_singleton_method(m_Monitor, "pause", monitor_pause_s, 1);
326
286
 
327
287
  tpLine = rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, process_line_event, NULL);
@@ -330,8 +290,10 @@ void initialize_monitor(VALUE m_Readapt)
330
290
  tpThreadBegin = rb_tracepoint_new(Qnil, RUBY_EVENT_THREAD_BEGIN, process_thread_begin_event, NULL);
331
291
  tpThreadEnd = rb_tracepoint_new(Qnil, RUBY_EVENT_THREAD_END, process_thread_end_event, NULL);
332
292
  debugProc = Qnil;
333
- breakpoints = rb_funcall(m_Monitor, rb_intern("breakpoints"), 0);
334
- knownBreakpoints = 0;
293
+
294
+ id_continue = rb_intern("continue");
295
+ id_pause = rb_intern("pause");
296
+ id_entry = rb_intern("entry");
335
297
 
336
298
  // Avoid garbage collection
337
299
  rb_global_variable(&tpLine);
@@ -339,4 +301,5 @@ void initialize_monitor(VALUE m_Readapt)
339
301
  rb_global_variable(&tpReturn);
340
302
  rb_global_variable(&tpThreadBegin);
341
303
  rb_global_variable(&tpThreadEnd);
304
+ rb_global_variable(&entryFile);
342
305
  }
@@ -1 +1,6 @@
1
+ #ifndef MONITOR_H_
2
+ #define MONITOR_H_
3
+
1
4
  void initialize_monitor(VALUE);
5
+
6
+ #endif
@@ -1,5 +1,6 @@
1
1
  #include "ruby.h"
2
2
  #include "ruby/debug.h"
3
+ #include <ctype.h>
3
4
 
4
5
  static int isWindows;
5
6
 
@@ -1,2 +1,7 @@
1
+ #ifndef NORMALIZE_H_
2
+ #define NORMALIZE_H_
3
+
1
4
  void initialize_normalize(VALUE);
2
5
  VALUE normalize_path(VALUE);
6
+
7
+ #endif
@@ -2,6 +2,7 @@
2
2
  #include "ruby/debug.h"
3
3
  #include "monitor.h"
4
4
  #include "normalize.h"
5
+ #include "breakpoints.h"
5
6
 
6
7
  static VALUE m_Readapt;
7
8
 
@@ -10,5 +11,6 @@ void Init_readapt()
10
11
  m_Readapt = rb_define_module("Readapt");
11
12
 
12
13
  initialize_normalize(m_Readapt);
14
+ initialize_breakpoints(m_Readapt);
13
15
  initialize_monitor(m_Readapt);
14
16
  }
@@ -1,9 +1,10 @@
1
+ #ifndef THREADS_H_
2
+ #define THREADS_H_
3
+
1
4
  typedef struct thread_reference_struct {
2
5
  long id;
3
6
  int depth;
4
7
  int cursor;
5
- VALUE prev_file;
6
- int prev_line;
7
8
  ID control;
8
9
  } thread_reference_t;
9
10
 
@@ -16,3 +17,5 @@ VALUE thread_delete_reference(VALUE);
16
17
  thread_reference_t *thread_reference_pointer(VALUE);
17
18
  void thread_pause();
18
19
  void thread_reset();
20
+
21
+ #endif
@@ -1,9 +1,7 @@
1
1
  require 'backport'
2
2
 
3
- require "readapt/version"
3
+ require 'readapt/version'
4
4
  require 'readapt/location'
5
- require 'readapt/breakpoint'
6
- require 'readapt/breakpoints'
7
5
  require 'readapt/thread'
8
6
  require 'readapt/frame'
9
7
  require 'readapt/monitor'
@@ -67,7 +67,7 @@ module Readapt
67
67
  send_event('process', {
68
68
  name: @file
69
69
  })
70
- Monitor.start do |snapshot|
70
+ Monitor.start @file do |snapshot|
71
71
  debug snapshot
72
72
  end
73
73
  yield if block_given?
@@ -123,12 +123,6 @@ module Readapt
123
123
  threadId: snapshot.thread_id
124
124
  })
125
125
  snapshot.control = :continue
126
- elsif snapshot.event == :initialize
127
- if snapshot.file != @file
128
- snapshot.control = :wait
129
- else
130
- snapshot.control = :ready
131
- end
132
126
  elsif snapshot.event == :entry
133
127
  snapshot.control = :continue
134
128
  else
@@ -5,21 +5,16 @@ module Readapt
5
5
  class SetBreakpoints < Base
6
6
  def run
7
7
  path = Readapt.normalize_path(arguments['source']['path'])
8
- Monitor.breakpoints.clear path
9
- result = arguments['lines'].map do |l|
10
- # @todo Assuming breakpoints are verified
11
- Breakpoint.new(path, l, true)
12
- end
13
- Monitor.breakpoints.concat result
14
- set_body({
15
- breakpoints: result.map { |bp|
8
+ Breakpoints.set(path, arguments['lines'])
9
+ set_body(
10
+ breakpoints: arguments['lines'].map do |l|
16
11
  {
17
- verified: bp.verified,
12
+ verified: true, # @todo Verify
18
13
  source: arguments['source'],
19
- line: bp.line
14
+ line: l
20
15
  }
21
- }
22
- })
16
+ end
17
+ )
23
18
  end
24
19
  end
25
20
  end
@@ -11,21 +11,5 @@ module Readapt
11
11
  # Disable tracepoints.
12
12
  # @return [Boolean]
13
13
  module Monitor
14
- @@breakpoints = Breakpoints.new
15
-
16
- # @return [Breakpoints]
17
- def self.breakpoints
18
- @@breakpoints
19
- end
20
-
21
- def self.set_breakpoints bps
22
- @@breakpoints = bps
23
- end
24
-
25
- def self.update
26
- know_breakpoints
27
- end
28
-
29
- @@breakpoints.add_observer self
30
14
  end
31
15
  end
@@ -1,3 +1,3 @@
1
1
  module Readapt
2
- VERSION = "0.3.5"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: readapt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-16 00:00:00.000000000 Z
11
+ date: 2019-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport
@@ -116,7 +116,11 @@ files:
116
116
  - bin/console
117
117
  - bin/setup
118
118
  - exe/readapt
119
+ - ext/readapt/breakpoints.c
120
+ - ext/readapt/breakpoints.h
119
121
  - ext/readapt/extconf.rb
122
+ - ext/readapt/hash_table.c
123
+ - ext/readapt/hash_table.h
120
124
  - ext/readapt/monitor.c
121
125
  - ext/readapt/monitor.h
122
126
  - ext/readapt/normalize.c
@@ -126,8 +130,6 @@ files:
126
130
  - ext/readapt/threads.h
127
131
  - lib/readapt.rb
128
132
  - lib/readapt/adapter.rb
129
- - lib/readapt/breakpoint.rb
130
- - lib/readapt/breakpoints.rb
131
133
  - lib/readapt/debugger.rb
132
134
  - lib/readapt/finder.rb
133
135
  - lib/readapt/frame.rb
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Readapt
4
- class Breakpoint < Location
5
- attr_reader :verified
6
-
7
- def initialize file, line, verified = true
8
- super(file, line)
9
- @verified = verified
10
- end
11
-
12
- def enabled?
13
- @verified
14
- end
15
- end
16
- end
@@ -1,58 +0,0 @@
1
- require 'observer'
2
-
3
- module Readapt
4
- class Breakpoints
5
- include Observable
6
-
7
- def initialize
8
- @sources = {}
9
- @concatting = false
10
- end
11
-
12
- # @return [Array<String>]
13
- def sources
14
- @sources.keys
15
- end
16
-
17
- # @param breakpoint [Breakpoint]
18
- # @return [void]
19
- def add breakpoint
20
- @sources[breakpoint.file] ||= []
21
- @sources[breakpoint.file].push breakpoint
22
- changed
23
- notify_observers unless @concatting
24
- end
25
-
26
- # @param breakpoints [Array<Breakpoint>]
27
- # @return [void]
28
- def concat breakpoints
29
- @concatting = true
30
- breakpoints.each { |bp| add bp }
31
- @concatting = false
32
- notify_observers
33
- end
34
-
35
- # @param file [String]
36
- # @return [void]
37
- def clear file
38
- @sources.delete file
39
- changed
40
- notify_observers
41
- end
42
-
43
- # @param file [String]
44
- # @return [Array<Breakpoint>]
45
- def for file
46
- @sources[file] || []
47
- end
48
-
49
- # @return [Array<Breakpoint>]
50
- def all
51
- @sources.values.flatten
52
- end
53
-
54
- def empty?
55
- @sources.empty?
56
- end
57
- end
58
- end