byebug 0.0.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.
- data/.gitignore +10 -0
- data/.travis.yml +8 -0
- data/AUTHORS +10 -0
- data/CHANGELOG.md +2 -0
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +5 -0
- data/Rakefile +28 -0
- data/bin/byebug +395 -0
- data/byebug.gemspec +29 -0
- data/doc/hanoi.rb +35 -0
- data/doc/primes.rb +28 -0
- data/doc/rdebug-emacs.texi +1030 -0
- data/doc/test-tri2.rb +18 -0
- data/doc/tri3.rb +8 -0
- data/doc/triangle.rb +12 -0
- data/ext/byebug/breakpoint.c +476 -0
- data/ext/byebug/byebug.c +512 -0
- data/ext/byebug/byebug.h +131 -0
- data/ext/byebug/context.c +424 -0
- data/ext/byebug/extconf.rb +21 -0
- data/ext/byebug/locker.c +53 -0
- data/lib/byebug.rb +404 -0
- data/lib/byebug/command.rb +232 -0
- data/lib/byebug/commands/breakpoints.rb +153 -0
- data/lib/byebug/commands/catchpoint.rb +56 -0
- data/lib/byebug/commands/condition.rb +49 -0
- data/lib/byebug/commands/continue.rb +38 -0
- data/lib/byebug/commands/control.rb +110 -0
- data/lib/byebug/commands/display.rb +122 -0
- data/lib/byebug/commands/edit.rb +48 -0
- data/lib/byebug/commands/enable.rb +202 -0
- data/lib/byebug/commands/eval.rb +176 -0
- data/lib/byebug/commands/finish.rb +43 -0
- data/lib/byebug/commands/frame.rb +303 -0
- data/lib/byebug/commands/help.rb +56 -0
- data/lib/byebug/commands/info.rb +462 -0
- data/lib/byebug/commands/irb.rb +123 -0
- data/lib/byebug/commands/jump.rb +66 -0
- data/lib/byebug/commands/kill.rb +51 -0
- data/lib/byebug/commands/list.rb +94 -0
- data/lib/byebug/commands/method.rb +84 -0
- data/lib/byebug/commands/quit.rb +39 -0
- data/lib/byebug/commands/reload.rb +40 -0
- data/lib/byebug/commands/save.rb +90 -0
- data/lib/byebug/commands/set.rb +210 -0
- data/lib/byebug/commands/show.rb +246 -0
- data/lib/byebug/commands/skip.rb +35 -0
- data/lib/byebug/commands/source.rb +36 -0
- data/lib/byebug/commands/stepping.rb +83 -0
- data/lib/byebug/commands/threads.rb +189 -0
- data/lib/byebug/commands/tmate.rb +36 -0
- data/lib/byebug/commands/trace.rb +56 -0
- data/lib/byebug/commands/variables.rb +199 -0
- data/lib/byebug/context.rb +58 -0
- data/lib/byebug/helper.rb +69 -0
- data/lib/byebug/interface.rb +223 -0
- data/lib/byebug/processor.rb +468 -0
- data/lib/byebug/version.rb +3 -0
- data/man/rdebug.1 +241 -0
- data/test/breakpoints_test.rb +357 -0
- data/test/conditions_test.rb +77 -0
- data/test/continue_test.rb +44 -0
- data/test/display_test.rb +141 -0
- data/test/edit_test.rb +56 -0
- data/test/eval_test.rb +92 -0
- data/test/examples/breakpoint1.rb +15 -0
- data/test/examples/breakpoint2.rb +7 -0
- data/test/examples/conditions.rb +4 -0
- data/test/examples/continue.rb +4 -0
- data/test/examples/display.rb +5 -0
- data/test/examples/edit.rb +3 -0
- data/test/examples/edit2.rb +3 -0
- data/test/examples/eval.rb +4 -0
- data/test/examples/finish.rb +20 -0
- data/test/examples/frame.rb +20 -0
- data/test/examples/frame_threads.rb +31 -0
- data/test/examples/help.rb +2 -0
- data/test/examples/info.rb +38 -0
- data/test/examples/info2.rb +3 -0
- data/test/examples/info_threads.rb +48 -0
- data/test/examples/irb.rb +6 -0
- data/test/examples/jump.rb +14 -0
- data/test/examples/kill.rb +2 -0
- data/test/examples/list.rb +12 -0
- data/test/examples/method.rb +15 -0
- data/test/examples/post_mortem.rb +19 -0
- data/test/examples/quit.rb +2 -0
- data/test/examples/reload.rb +6 -0
- data/test/examples/restart.rb +6 -0
- data/test/examples/save.rb +3 -0
- data/test/examples/set.rb +3 -0
- data/test/examples/set_annotate.rb +12 -0
- data/test/examples/settings.rb +1 -0
- data/test/examples/show.rb +2 -0
- data/test/examples/source.rb +3 -0
- data/test/examples/stepping.rb +21 -0
- data/test/examples/thread.rb +32 -0
- data/test/examples/tmate.rb +10 -0
- data/test/examples/trace.rb +7 -0
- data/test/examples/trace_threads.rb +20 -0
- data/test/examples/variables.rb +26 -0
- data/test/finish_test.rb +48 -0
- data/test/frame_test.rb +143 -0
- data/test/help_test.rb +50 -0
- data/test/info_test.rb +313 -0
- data/test/irb_test.rb +81 -0
- data/test/jump_test.rb +70 -0
- data/test/kill_test.rb +48 -0
- data/test/list_test.rb +145 -0
- data/test/method_test.rb +70 -0
- data/test/post_mortem_test.rb +27 -0
- data/test/quit_test.rb +56 -0
- data/test/reload_test.rb +44 -0
- data/test/restart_test.rb +164 -0
- data/test/save_test.rb +92 -0
- data/test/set_test.rb +177 -0
- data/test/show_test.rb +293 -0
- data/test/source_test.rb +45 -0
- data/test/stepping_test.rb +130 -0
- data/test/support/breakpoint.rb +13 -0
- data/test/support/context.rb +14 -0
- data/test/support/matchers.rb +67 -0
- data/test/support/mocha_extensions.rb +72 -0
- data/test/support/processor.rb +7 -0
- data/test/support/test_dsl.rb +206 -0
- data/test/support/test_interface.rb +68 -0
- data/test/test_helper.rb +10 -0
- data/test/tmate_test.rb +44 -0
- data/test/trace_test.rb +159 -0
- data/test/variables_test.rb +119 -0
- metadata +265 -0
data/doc/test-tri2.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "test/unit"
|
3
|
+
require "tri2.rb"
|
4
|
+
require "rubygems"
|
5
|
+
require "ruby-debug"
|
6
|
+
Byebug.start
|
7
|
+
|
8
|
+
class TestTri < Test::Unit::TestCase
|
9
|
+
def test_basic
|
10
|
+
byebug
|
11
|
+
solutions = []
|
12
|
+
0.upto(5) do |i|
|
13
|
+
solutions << triangle(i)
|
14
|
+
end
|
15
|
+
assert_equal([0, 1, 3, 6, 10, 15], solutions,
|
16
|
+
"Testing the first 5 triangle numbers")
|
17
|
+
end
|
18
|
+
end
|
data/doc/tri3.rb
ADDED
data/doc/triangle.rb
ADDED
@@ -0,0 +1,476 @@
|
|
1
|
+
#include <byebug.h>
|
2
|
+
|
3
|
+
#ifdef _WIN32
|
4
|
+
#include <ctype.h>
|
5
|
+
#endif
|
6
|
+
|
7
|
+
#if defined DOSISH
|
8
|
+
#define isdirsep(x) ((x) == '/' || (x) == '\\')
|
9
|
+
#else
|
10
|
+
#define isdirsep(x) ((x) == '/')
|
11
|
+
#endif
|
12
|
+
|
13
|
+
static VALUE cBreakpoint;
|
14
|
+
static int breakpoint_max;
|
15
|
+
|
16
|
+
static ID idEval;
|
17
|
+
|
18
|
+
static VALUE
|
19
|
+
eval_expression(VALUE args)
|
20
|
+
{
|
21
|
+
return rb_funcall2(rb_mKernel, idEval, 2, RARRAY_PTR(args));
|
22
|
+
}
|
23
|
+
|
24
|
+
extern VALUE
|
25
|
+
catchpoint_hit_count(VALUE catchpoints, VALUE exception, VALUE *exception_name)
|
26
|
+
{
|
27
|
+
VALUE ancestors;
|
28
|
+
VALUE expn_class;
|
29
|
+
VALUE aclass;
|
30
|
+
VALUE mod_name;
|
31
|
+
VALUE hit_count;
|
32
|
+
int i;
|
33
|
+
|
34
|
+
if (catchpoints == Qnil /*|| st_get_num_entries(RHASH_TBL(rdebug_catchpoints)) == 0)*/)
|
35
|
+
return Qnil;
|
36
|
+
expn_class = rb_obj_class(exception);
|
37
|
+
ancestors = rb_mod_ancestors(expn_class);
|
38
|
+
for(i = 0; i < RARRAY_LEN(ancestors); i++)
|
39
|
+
{
|
40
|
+
aclass = rb_ary_entry(ancestors, i);
|
41
|
+
mod_name = rb_mod_name(aclass);
|
42
|
+
hit_count = rb_hash_aref(catchpoints, mod_name);
|
43
|
+
if(hit_count != Qnil)
|
44
|
+
{
|
45
|
+
*exception_name = mod_name;
|
46
|
+
return hit_count;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
return Qnil;
|
50
|
+
}
|
51
|
+
|
52
|
+
static VALUE
|
53
|
+
Breakpoint_hit_count(VALUE self)
|
54
|
+
{
|
55
|
+
breakpoint_t *breakpoint;
|
56
|
+
|
57
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
58
|
+
return INT2FIX(breakpoint->hit_count);
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
static VALUE
|
63
|
+
Breakpoint_hit_value(VALUE self)
|
64
|
+
{
|
65
|
+
breakpoint_t *breakpoint;
|
66
|
+
|
67
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
68
|
+
return INT2FIX(breakpoint->hit_value);
|
69
|
+
}
|
70
|
+
|
71
|
+
static VALUE
|
72
|
+
Breakpoint_set_hit_value(VALUE self, VALUE value)
|
73
|
+
{
|
74
|
+
breakpoint_t *breakpoint;
|
75
|
+
|
76
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
77
|
+
breakpoint->hit_value = FIX2INT(value);
|
78
|
+
return value;
|
79
|
+
}
|
80
|
+
|
81
|
+
static VALUE
|
82
|
+
Breakpoint_hit_condition(VALUE self)
|
83
|
+
{
|
84
|
+
breakpoint_t *breakpoint;
|
85
|
+
|
86
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
87
|
+
switch(breakpoint->hit_condition)
|
88
|
+
{
|
89
|
+
case HIT_COND_GE:
|
90
|
+
return ID2SYM(rb_intern("greater_or_equal"));
|
91
|
+
case HIT_COND_EQ:
|
92
|
+
return ID2SYM(rb_intern("equal"));
|
93
|
+
case HIT_COND_MOD:
|
94
|
+
return ID2SYM(rb_intern("modulo"));
|
95
|
+
case HIT_COND_NONE:
|
96
|
+
default:
|
97
|
+
return Qnil;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
static VALUE
|
102
|
+
Breakpoint_set_hit_condition(VALUE self, VALUE value)
|
103
|
+
{
|
104
|
+
breakpoint_t *breakpoint;
|
105
|
+
ID id_value;
|
106
|
+
|
107
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
108
|
+
id_value = rb_to_id(value);
|
109
|
+
|
110
|
+
if(rb_intern("greater_or_equal") == id_value || rb_intern("ge") == id_value)
|
111
|
+
breakpoint->hit_condition = HIT_COND_GE;
|
112
|
+
else if(rb_intern("equal") == id_value || rb_intern("eq") == id_value)
|
113
|
+
breakpoint->hit_condition = HIT_COND_EQ;
|
114
|
+
else if(rb_intern("modulo") == id_value || rb_intern("mod") == id_value)
|
115
|
+
breakpoint->hit_condition = HIT_COND_MOD;
|
116
|
+
else
|
117
|
+
rb_raise(rb_eArgError, "Invalid condition parameter");
|
118
|
+
return value;
|
119
|
+
}
|
120
|
+
|
121
|
+
static void
|
122
|
+
Breakpoint_mark(breakpoint_t *breakpoint)
|
123
|
+
{
|
124
|
+
rb_gc_mark(breakpoint->source);
|
125
|
+
rb_gc_mark(breakpoint->expr);
|
126
|
+
}
|
127
|
+
|
128
|
+
static VALUE
|
129
|
+
Breakpoint_create(VALUE klass)
|
130
|
+
{
|
131
|
+
breakpoint_t *breakpoint;
|
132
|
+
|
133
|
+
breakpoint = ALLOC(breakpoint_t);
|
134
|
+
return Data_Wrap_Struct(klass, Breakpoint_mark, xfree, breakpoint);
|
135
|
+
}
|
136
|
+
|
137
|
+
static VALUE
|
138
|
+
Breakpoint_initialize(VALUE self, VALUE source, VALUE pos, VALUE expr)
|
139
|
+
{
|
140
|
+
breakpoint_t *breakpoint;
|
141
|
+
|
142
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
143
|
+
|
144
|
+
breakpoint->type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
|
145
|
+
if(breakpoint->type == BP_POS_TYPE)
|
146
|
+
breakpoint->pos.line = FIX2INT(pos);
|
147
|
+
else
|
148
|
+
breakpoint->pos.mid = SYM2ID(pos);
|
149
|
+
|
150
|
+
breakpoint->id = ++breakpoint_max;
|
151
|
+
breakpoint->source = StringValue(source);
|
152
|
+
breakpoint->enabled = Qtrue;
|
153
|
+
breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr);
|
154
|
+
breakpoint->hit_count = 0;
|
155
|
+
breakpoint->hit_value = 0;
|
156
|
+
|
157
|
+
return Qnil;
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE
|
161
|
+
Breakpoint_remove(VALUE self, VALUE breakpoints, VALUE id_value)
|
162
|
+
{
|
163
|
+
int i;
|
164
|
+
int id;
|
165
|
+
VALUE breakpoint_object;
|
166
|
+
breakpoint_t *breakpoint;
|
167
|
+
|
168
|
+
if (breakpoints == Qnil) return Qnil;
|
169
|
+
|
170
|
+
id = FIX2INT(id_value);
|
171
|
+
|
172
|
+
for(i = 0; i < RARRAY_LEN(breakpoints); i++)
|
173
|
+
{
|
174
|
+
breakpoint_object = rb_ary_entry(breakpoints, i);
|
175
|
+
Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
|
176
|
+
if(breakpoint->id == id)
|
177
|
+
{
|
178
|
+
rb_ary_delete_at(breakpoints, i);
|
179
|
+
return breakpoint_object;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
return Qnil;
|
183
|
+
}
|
184
|
+
|
185
|
+
static VALUE
|
186
|
+
Breakpoint_id(VALUE self)
|
187
|
+
{
|
188
|
+
breakpoint_t *breakpoint;
|
189
|
+
|
190
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
191
|
+
return INT2FIX(breakpoint->id);
|
192
|
+
}
|
193
|
+
|
194
|
+
static VALUE
|
195
|
+
Breakpoint_source(VALUE self)
|
196
|
+
{
|
197
|
+
breakpoint_t *breakpoint;
|
198
|
+
|
199
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
200
|
+
return breakpoint->source;
|
201
|
+
}
|
202
|
+
|
203
|
+
static VALUE
|
204
|
+
Breakpoint_pos(VALUE self)
|
205
|
+
{
|
206
|
+
breakpoint_t *breakpoint;
|
207
|
+
|
208
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
209
|
+
if(breakpoint->type == BP_METHOD_TYPE)
|
210
|
+
return rb_str_new2(rb_id2name(breakpoint->pos.mid));
|
211
|
+
else
|
212
|
+
return INT2FIX(breakpoint->pos.line);
|
213
|
+
}
|
214
|
+
|
215
|
+
|
216
|
+
static VALUE
|
217
|
+
Breakpoint_expr(VALUE self)
|
218
|
+
{
|
219
|
+
breakpoint_t *breakpoint;
|
220
|
+
|
221
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
222
|
+
return breakpoint->expr;
|
223
|
+
}
|
224
|
+
|
225
|
+
static VALUE
|
226
|
+
Breakpoint_set_expr(VALUE self, VALUE expr)
|
227
|
+
{
|
228
|
+
breakpoint_t *breakpoint;
|
229
|
+
|
230
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
231
|
+
breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
|
232
|
+
return expr;
|
233
|
+
}
|
234
|
+
|
235
|
+
static VALUE
|
236
|
+
Breakpoint_enabled(VALUE self)
|
237
|
+
{
|
238
|
+
breakpoint_t *breakpoint;
|
239
|
+
|
240
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
241
|
+
return breakpoint->enabled;
|
242
|
+
}
|
243
|
+
|
244
|
+
static VALUE
|
245
|
+
Breakpoint_set_enabled(VALUE self, VALUE bool)
|
246
|
+
{
|
247
|
+
breakpoint_t *breakpoint;
|
248
|
+
|
249
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
250
|
+
return breakpoint->enabled = bool;
|
251
|
+
}
|
252
|
+
|
253
|
+
int
|
254
|
+
filename_cmp_impl(VALUE source, char *file)
|
255
|
+
{
|
256
|
+
char *source_ptr, *file_ptr;
|
257
|
+
long s_len, f_len, min_len;
|
258
|
+
long s,f;
|
259
|
+
int dirsep_flag = 0;
|
260
|
+
|
261
|
+
s_len = RSTRING_LEN(source);
|
262
|
+
f_len = strlen(file);
|
263
|
+
min_len = s_len < f_len ? s_len : f_len;
|
264
|
+
|
265
|
+
source_ptr = RSTRING_PTR(source);
|
266
|
+
file_ptr = file;
|
267
|
+
|
268
|
+
for( s = s_len - 1, f = f_len - 1; s >= s_len - min_len && f >= f_len - min_len; s--, f-- )
|
269
|
+
{
|
270
|
+
if((source_ptr[s] == '.' || file_ptr[f] == '.') && dirsep_flag)
|
271
|
+
return 1;
|
272
|
+
if(isdirsep(source_ptr[s]) && isdirsep(file_ptr[f]))
|
273
|
+
dirsep_flag = 1;
|
274
|
+
#ifdef DOSISH_DRIVE_LETTER
|
275
|
+
else if (s == 0)
|
276
|
+
return(toupper(source_ptr[s]) == toupper(file_ptr[f]));
|
277
|
+
#endif
|
278
|
+
else if(source_ptr[s] != file_ptr[f])
|
279
|
+
return 0;
|
280
|
+
}
|
281
|
+
return 1;
|
282
|
+
}
|
283
|
+
|
284
|
+
int
|
285
|
+
filename_cmp(VALUE source, char *file)
|
286
|
+
{
|
287
|
+
#ifdef _WIN32
|
288
|
+
return filename_cmp_impl(source, file);
|
289
|
+
#else
|
290
|
+
#ifdef PATH_MAX
|
291
|
+
char path[PATH_MAX + 1];
|
292
|
+
path[PATH_MAX] = 0;
|
293
|
+
return filename_cmp_impl(source, realpath(file, path) != NULL ? path : file);
|
294
|
+
#else
|
295
|
+
char *path;
|
296
|
+
int result;
|
297
|
+
path = realpath(file, NULL);
|
298
|
+
result = filename_cmp_impl(source, path == NULL ? file : path);
|
299
|
+
free(path);
|
300
|
+
return result;
|
301
|
+
#endif
|
302
|
+
#endif
|
303
|
+
}
|
304
|
+
|
305
|
+
/* XXX: Activate */
|
306
|
+
/*
|
307
|
+
static int
|
308
|
+
check_breakpoint_hit_condition(VALUE breakpoint_object)
|
309
|
+
{
|
310
|
+
breakpoint_t *breakpoint;
|
311
|
+
|
312
|
+
if (breakpoint == Qnil)
|
313
|
+
return 0;
|
314
|
+
|
315
|
+
Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
|
316
|
+
breakpoint->hit_count++;
|
317
|
+
|
318
|
+
if (Qtrue != breakpoint->enabled)
|
319
|
+
return 0;
|
320
|
+
switch (breakpoint->hit_condition)
|
321
|
+
{
|
322
|
+
case HIT_COND_NONE:
|
323
|
+
return 1;
|
324
|
+
case HIT_COND_GE:
|
325
|
+
{
|
326
|
+
if (breakpoint->hit_count >= breakpoint->hit_value)
|
327
|
+
return 1;
|
328
|
+
break;
|
329
|
+
}
|
330
|
+
case HIT_COND_EQ:
|
331
|
+
{
|
332
|
+
if (breakpoint->hit_count == breakpoint->hit_value)
|
333
|
+
return 1;
|
334
|
+
break;
|
335
|
+
}
|
336
|
+
case HIT_COND_MOD:
|
337
|
+
{
|
338
|
+
if (breakpoint->hit_count % breakpoint->hit_value == 0)
|
339
|
+
return 1;
|
340
|
+
break;
|
341
|
+
}
|
342
|
+
}
|
343
|
+
return 0;
|
344
|
+
}
|
345
|
+
*/
|
346
|
+
|
347
|
+
static int
|
348
|
+
check_breakpoint_by_pos(VALUE breakpoint_object, char *file, int line)
|
349
|
+
{
|
350
|
+
breakpoint_t *breakpoint;
|
351
|
+
|
352
|
+
if(breakpoint_object == Qnil)
|
353
|
+
return 0;
|
354
|
+
Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
|
355
|
+
if (Qtrue != breakpoint->enabled)
|
356
|
+
return 0;
|
357
|
+
if(breakpoint->type != BP_POS_TYPE)
|
358
|
+
return 0;
|
359
|
+
if(breakpoint->pos.line != line)
|
360
|
+
return 0;
|
361
|
+
if(filename_cmp(breakpoint->source, file))
|
362
|
+
return 1;
|
363
|
+
return 0;
|
364
|
+
}
|
365
|
+
|
366
|
+
static int
|
367
|
+
check_breakpoint_by_method(VALUE breakpoint_object, VALUE klass, ID mid,
|
368
|
+
VALUE self)
|
369
|
+
{
|
370
|
+
breakpoint_t *breakpoint;
|
371
|
+
|
372
|
+
if (breakpoint_object == Qnil)
|
373
|
+
return 0;
|
374
|
+
Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
|
375
|
+
if (!Qtrue == breakpoint->enabled)
|
376
|
+
return 0;
|
377
|
+
if (breakpoint->type != BP_METHOD_TYPE)
|
378
|
+
return 0;
|
379
|
+
if (breakpoint->pos.mid != mid)
|
380
|
+
return 0;
|
381
|
+
if (classname_cmp(breakpoint->source, klass))
|
382
|
+
return 1;
|
383
|
+
if ((rb_type(self) == T_CLASS) &&
|
384
|
+
classname_cmp(breakpoint->source, self))
|
385
|
+
return 1;
|
386
|
+
return 0;
|
387
|
+
}
|
388
|
+
|
389
|
+
static int
|
390
|
+
check_breakpoint_by_expr(VALUE breakpoint_object, VALUE binding)
|
391
|
+
{
|
392
|
+
breakpoint_t *breakpoint;
|
393
|
+
VALUE args, expr_result;
|
394
|
+
|
395
|
+
if (breakpoint_object == Qnil)
|
396
|
+
return 0;
|
397
|
+
Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
|
398
|
+
if (Qtrue != breakpoint->enabled)
|
399
|
+
return 0;
|
400
|
+
if (NIL_P(breakpoint->expr))
|
401
|
+
return 1;
|
402
|
+
args = rb_ary_new3(2, breakpoint->expr, binding);
|
403
|
+
expr_result = rb_protect(eval_expression, args, 0);
|
404
|
+
return RTEST(expr_result);
|
405
|
+
}
|
406
|
+
|
407
|
+
//static VALUE
|
408
|
+
//Breakpoint_find(VALUE self, VALUE breakpoints, VALUE source, VALUE pos, VALUE binding)
|
409
|
+
//{
|
410
|
+
// return breakpoint_find(breakpoints, source, pos, binding);
|
411
|
+
//}
|
412
|
+
|
413
|
+
extern VALUE
|
414
|
+
find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos,
|
415
|
+
VALUE binding)
|
416
|
+
{
|
417
|
+
VALUE breakpoint_object;
|
418
|
+
char *file;
|
419
|
+
int line;
|
420
|
+
int i;
|
421
|
+
|
422
|
+
file = RSTRING_PTR(source);
|
423
|
+
line = FIX2INT(pos);
|
424
|
+
for(i = 0; i < RARRAY_LEN(breakpoints); i++)
|
425
|
+
{
|
426
|
+
breakpoint_object = rb_ary_entry(breakpoints, i);
|
427
|
+
if ( check_breakpoint_by_pos(breakpoint_object, file, line) &&
|
428
|
+
check_breakpoint_by_expr(breakpoint_object, binding) )
|
429
|
+
{
|
430
|
+
return breakpoint_object;
|
431
|
+
}
|
432
|
+
}
|
433
|
+
return Qnil;
|
434
|
+
}
|
435
|
+
|
436
|
+
extern VALUE
|
437
|
+
find_breakpoint_by_method(VALUE breakpoints, VALUE klass, ID mid, VALUE binding,
|
438
|
+
VALUE self)
|
439
|
+
{
|
440
|
+
VALUE breakpoint_object;
|
441
|
+
int i;
|
442
|
+
|
443
|
+
for(i = 0; i < RARRAY_LEN(breakpoints); i++)
|
444
|
+
{
|
445
|
+
breakpoint_object = rb_ary_entry(breakpoints, i);
|
446
|
+
if ( check_breakpoint_by_method(breakpoint_object, klass, mid, self) &&
|
447
|
+
check_breakpoint_by_expr(breakpoint_object, binding) )
|
448
|
+
return breakpoint_object;
|
449
|
+
}
|
450
|
+
return Qnil;
|
451
|
+
}
|
452
|
+
|
453
|
+
extern void
|
454
|
+
Init_breakpoint(VALUE mByebug)
|
455
|
+
{
|
456
|
+
breakpoint_max = 0;
|
457
|
+
cBreakpoint = rb_define_class_under(mByebug, "Breakpoint", rb_cObject);
|
458
|
+
/* rb_define_singleton_method(cBreakpoint, "find", Breakpoint_find, 4); */
|
459
|
+
rb_define_singleton_method(cBreakpoint, "remove", Breakpoint_remove, 2);
|
460
|
+
rb_define_method(cBreakpoint, "initialize", Breakpoint_initialize, 3);
|
461
|
+
rb_define_method(cBreakpoint, "id", Breakpoint_id, 0);
|
462
|
+
rb_define_method(cBreakpoint, "source", Breakpoint_source, 0);
|
463
|
+
rb_define_method(cBreakpoint, "pos", Breakpoint_pos, 0);
|
464
|
+
rb_define_method(cBreakpoint, "expr", Breakpoint_expr, 0);
|
465
|
+
rb_define_method(cBreakpoint, "expr=", Breakpoint_set_expr, 1);
|
466
|
+
rb_define_method(cBreakpoint, "hit_count", Breakpoint_hit_count, 0);
|
467
|
+
rb_define_method(cBreakpoint, "hit_condition", Breakpoint_hit_condition, 0);
|
468
|
+
rb_define_method(cBreakpoint, "hit_condition=", Breakpoint_set_hit_condition, 1);
|
469
|
+
rb_define_method(cBreakpoint, "enabled?", Breakpoint_enabled, 0);
|
470
|
+
rb_define_method(cBreakpoint, "enabled=", Breakpoint_set_enabled, 1);
|
471
|
+
rb_define_method(cBreakpoint, "hit_value", Breakpoint_hit_value, 0);
|
472
|
+
rb_define_method(cBreakpoint, "hit_value=", Breakpoint_set_hit_value, 1);
|
473
|
+
rb_define_alloc_func(cBreakpoint, Breakpoint_create);
|
474
|
+
|
475
|
+
idEval = rb_intern("eval");
|
476
|
+
}
|