readapt 0.3.5 → 0.4.0

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.
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