ruby-debug-base 0.10.0-mswin32 → 0.10.4-mswin32

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION ADDED
@@ -0,0 +1,3 @@
1
+ # This file was created automatically from data in ext/ruby_debug.c via:
2
+ # rake :make_version_file.
3
+ 0.10.4
data/ext/breakpoint.c ADDED
@@ -0,0 +1,582 @@
1
+ #include "ruby_debug.h"
2
+
3
+ VALUE rdebug_breakpoints = Qnil;
4
+ VALUE rdebug_catchpoints;
5
+
6
+ static VALUE cBreakpoint;
7
+ static ID idEval;
8
+
9
+ static VALUE
10
+ eval_expression(VALUE args)
11
+ {
12
+ return rb_funcall2(rb_mKernel, idEval, 2, RARRAY(args)->ptr);
13
+ }
14
+
15
+ int
16
+ check_breakpoint_hit_condition(VALUE breakpoint)
17
+ {
18
+ debug_breakpoint_t *debug_breakpoint;
19
+
20
+ if(breakpoint == Qnil)
21
+ return 0;
22
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
23
+
24
+ debug_breakpoint->hit_count++;
25
+ if (!Qtrue == debug_breakpoint->enabled) return 0;
26
+ switch(debug_breakpoint->hit_condition)
27
+ {
28
+ case HIT_COND_NONE:
29
+ return 1;
30
+ case HIT_COND_GE:
31
+ {
32
+ if(debug_breakpoint->hit_count >= debug_breakpoint->hit_value)
33
+ return 1;
34
+ break;
35
+ }
36
+ case HIT_COND_EQ:
37
+ {
38
+ if(debug_breakpoint->hit_count == debug_breakpoint->hit_value)
39
+ return 1;
40
+ break;
41
+ }
42
+ case HIT_COND_MOD:
43
+ {
44
+ if(debug_breakpoint->hit_count % debug_breakpoint->hit_value == 0)
45
+ return 1;
46
+ break;
47
+ }
48
+ }
49
+ return 0;
50
+ }
51
+
52
+ static int
53
+ check_breakpoint_by_pos(VALUE breakpoint, char *file, int line)
54
+ {
55
+ debug_breakpoint_t *debug_breakpoint;
56
+
57
+ if(breakpoint == Qnil)
58
+ return 0;
59
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
60
+ if (!Qtrue == debug_breakpoint->enabled) return 0;
61
+ if(debug_breakpoint->type != BP_POS_TYPE)
62
+ return 0;
63
+ if(debug_breakpoint->pos.line != line)
64
+ return 0;
65
+ if(filename_cmp(debug_breakpoint->source, file))
66
+ return 1;
67
+ return 0;
68
+ }
69
+
70
+ int
71
+ check_breakpoint_by_method(VALUE breakpoint, VALUE klass, ID mid, VALUE self)
72
+ {
73
+ debug_breakpoint_t *debug_breakpoint;
74
+
75
+ if(breakpoint == Qnil)
76
+ return 0;
77
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
78
+ if (!Qtrue == debug_breakpoint->enabled) return 0;
79
+ if(debug_breakpoint->type != BP_METHOD_TYPE)
80
+ return 0;
81
+ if(debug_breakpoint->pos.mid != mid)
82
+ return 0;
83
+ if(classname_cmp(debug_breakpoint->source, klass))
84
+ return 1;
85
+ if ((rb_type(self) == T_CLASS) &&
86
+ classname_cmp(debug_breakpoint->source, self))
87
+ return 1;
88
+ return 0;
89
+ }
90
+
91
+ VALUE
92
+ check_breakpoints_by_pos(debug_context_t *debug_context, char *file, int line)
93
+ {
94
+ VALUE breakpoint;
95
+ int i;
96
+
97
+ if(!CTX_FL_TEST(debug_context, CTX_FL_ENABLE_BKPT))
98
+ return Qnil;
99
+
100
+ if(check_breakpoint_by_pos(debug_context->breakpoint, file, line))
101
+ return debug_context->breakpoint;
102
+
103
+ if(RARRAY(rdebug_breakpoints)->len == 0)
104
+ return Qnil;
105
+ for(i = 0; i < RARRAY(rdebug_breakpoints)->len; i++)
106
+ {
107
+ breakpoint = rb_ary_entry(rdebug_breakpoints, i);
108
+ if(check_breakpoint_by_pos(breakpoint, file, line))
109
+ return breakpoint;
110
+ }
111
+ return Qnil;
112
+ }
113
+
114
+ VALUE
115
+ check_breakpoints_by_method(debug_context_t *debug_context, VALUE klass, ID mid, VALUE self)
116
+ {
117
+ VALUE breakpoint;
118
+ int i;
119
+
120
+ if(!CTX_FL_TEST(debug_context, CTX_FL_ENABLE_BKPT))
121
+ return Qnil;
122
+
123
+ if(check_breakpoint_by_method(debug_context->breakpoint, klass, mid, self))
124
+ return debug_context->breakpoint;
125
+
126
+ if(RARRAY(rdebug_breakpoints)->len == 0)
127
+ return Qnil;
128
+ for(i = 0; i < RARRAY(rdebug_breakpoints)->len; i++)
129
+ {
130
+ breakpoint = rb_ary_entry(rdebug_breakpoints, i);
131
+ if(check_breakpoint_by_method(breakpoint, klass, mid, self))
132
+ return breakpoint;
133
+ }
134
+ return Qnil;
135
+ }
136
+
137
+ int
138
+ check_breakpoint_expression(VALUE breakpoint, VALUE binding)
139
+ {
140
+ debug_breakpoint_t *debug_breakpoint;
141
+ VALUE args, expr_result;
142
+
143
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
144
+ if(NIL_P(debug_breakpoint->expr))
145
+ return 1;
146
+
147
+ args = rb_ary_new3(2, debug_breakpoint->expr, binding);
148
+ expr_result = rb_protect(eval_expression, args, 0);
149
+ return RTEST(expr_result);
150
+ }
151
+
152
+ static void
153
+ breakpoint_mark(void *data)
154
+ {
155
+ debug_breakpoint_t *breakpoint;
156
+ breakpoint = (debug_breakpoint_t *)data;
157
+ rb_gc_mark(breakpoint->source);
158
+ rb_gc_mark(breakpoint->expr);
159
+ }
160
+
161
+ VALUE
162
+ create_breakpoint_from_args(int argc, VALUE *argv, int id)
163
+ {
164
+ VALUE source, pos, expr;
165
+ debug_breakpoint_t *breakpoint;
166
+ int type;
167
+
168
+ if(rb_scan_args(argc, argv, "21", &source, &pos, &expr) == 2)
169
+ {
170
+ expr = Qnil;
171
+ }
172
+ type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
173
+ if(type == BP_POS_TYPE)
174
+ source = StringValue(source);
175
+ else
176
+ pos = StringValue(pos);
177
+ breakpoint = ALLOC(debug_breakpoint_t);
178
+ breakpoint->id = id;
179
+ breakpoint->source = source;
180
+ breakpoint->type = type;
181
+ if(type == BP_POS_TYPE)
182
+ breakpoint->pos.line = FIX2INT(pos);
183
+ else
184
+ breakpoint->pos.mid = rb_intern(RSTRING(pos)->ptr);
185
+ breakpoint->enabled = Qtrue;
186
+ breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
187
+ breakpoint->hit_count = 0;
188
+ breakpoint->hit_value = 0;
189
+ breakpoint->hit_condition = HIT_COND_NONE;
190
+ return Data_Wrap_Struct(cBreakpoint, breakpoint_mark, xfree, breakpoint);
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * Debugger.remove_breakpoint(id) -> breakpoint
196
+ *
197
+ * Removes breakpoint by its id.
198
+ * <i>id</i> is an identificator of a breakpoint.
199
+ */
200
+ VALUE
201
+ rdebug_remove_breakpoint(VALUE self, VALUE id_value)
202
+ {
203
+ int i;
204
+ int id;
205
+ VALUE breakpoint;
206
+ debug_breakpoint_t *debug_breakpoint;
207
+
208
+ id = FIX2INT(id_value);
209
+
210
+ for( i = 0; i < RARRAY(rdebug_breakpoints)->len; i += 1 )
211
+ {
212
+ breakpoint = rb_ary_entry(rdebug_breakpoints, i);
213
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
214
+ if(debug_breakpoint->id == id)
215
+ {
216
+ rb_ary_delete_at(rdebug_breakpoints, i);
217
+ return breakpoint;
218
+ }
219
+ }
220
+ return Qnil;
221
+ }
222
+
223
+ /*
224
+ * call-seq:
225
+ * Debugger.catchpoints -> hash
226
+ *
227
+ * Returns a current catchpoints, which is a hash exception names that will
228
+ * trigger a debugger when raised. The values are the number of times taht
229
+ * catchpoint was hit, initially 0.
230
+ */
231
+ VALUE
232
+ debug_catchpoints(VALUE self)
233
+ {
234
+ debug_check_started();
235
+
236
+ return rdebug_catchpoints;
237
+ }
238
+
239
+ /*
240
+ * call-seq:
241
+ * Debugger.catchpoint(string) -> string
242
+ *
243
+ * Sets catchpoint. Returns the string passed.
244
+ */
245
+ VALUE
246
+ rdebug_add_catchpoint(VALUE self, VALUE value)
247
+ {
248
+ debug_check_started();
249
+
250
+ if (TYPE(value) != T_STRING) {
251
+ rb_raise(rb_eTypeError, "value of a catchpoint must be String");
252
+ }
253
+ rb_hash_aset(rdebug_catchpoints, rb_str_dup(value), INT2FIX(0));
254
+ return value;
255
+ }
256
+
257
+ /*
258
+ * call-seq:
259
+ * context.breakpoint -> Breakpoint
260
+ *
261
+ * Returns a context-specific temporary Breakpoint object.
262
+ */
263
+ VALUE
264
+ context_breakpoint(VALUE self)
265
+ {
266
+ debug_context_t *debug_context;
267
+
268
+ debug_check_started();
269
+
270
+ Data_Get_Struct(self, debug_context_t, debug_context);
271
+ return debug_context->breakpoint;
272
+ }
273
+
274
+ /*
275
+ * call-seq:
276
+ * context.set_breakpoint(source, pos, condition = nil) -> breakpoint
277
+ *
278
+ * Sets a context-specific temporary breakpoint, which can be used to implement
279
+ * 'Run to Cursor' debugger function. When this breakpoint is reached, it will be
280
+ * cleared out.
281
+ *
282
+ * <i>source</i> is a name of a file or a class.
283
+ * <i>pos</i> is a line number or a method name if <i>source</i> is a class name.
284
+ * <i>condition</i> is a string which is evaluated to +true+ when this breakpoint
285
+ * is activated.
286
+ */
287
+ VALUE
288
+ context_set_breakpoint(int argc, VALUE *argv, VALUE self)
289
+ {
290
+ VALUE result;
291
+ debug_context_t *debug_context;
292
+
293
+ debug_check_started();
294
+
295
+ Data_Get_Struct(self, debug_context_t, debug_context);
296
+ result = create_breakpoint_from_args(argc, argv, 0);
297
+ debug_context->breakpoint = result;
298
+ return result;
299
+ }
300
+
301
+ /*
302
+ * call-seq:
303
+ * breakpoint.enabled?
304
+ *
305
+ * Returns whether breakpoint is enabled or not.
306
+ */
307
+ static VALUE
308
+ breakpoint_enabled(VALUE self)
309
+ {
310
+ debug_breakpoint_t *breakpoint;
311
+
312
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
313
+ return breakpoint->enabled;
314
+ }
315
+
316
+ /*
317
+ * call-seq:
318
+ * breakpoint.enabled = bool
319
+ *
320
+ * Enables or disables breakpoint.
321
+ */
322
+ static VALUE
323
+ breakpoint_set_enabled(VALUE self, VALUE bool)
324
+ {
325
+ debug_breakpoint_t *breakpoint;
326
+
327
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
328
+ return breakpoint->enabled = bool;
329
+ }
330
+
331
+ /*
332
+ * call-seq:
333
+ * breakpoint.source -> string
334
+ *
335
+ * Returns a source of the breakpoint.
336
+ */
337
+ static VALUE
338
+ breakpoint_source(VALUE self)
339
+ {
340
+ debug_breakpoint_t *breakpoint;
341
+
342
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
343
+ return breakpoint->source;
344
+ }
345
+
346
+ /*
347
+ * call-seq:
348
+ * breakpoint.source = string
349
+ *
350
+ * Sets the source of the breakpoint.
351
+ */
352
+ static VALUE
353
+ breakpoint_set_source(VALUE self, VALUE value)
354
+ {
355
+ debug_breakpoint_t *breakpoint;
356
+
357
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
358
+ breakpoint->source = StringValue(value);
359
+ return value;
360
+ }
361
+
362
+ /*
363
+ * call-seq:
364
+ * breakpoint.pos -> string or int
365
+ *
366
+ * Returns the position of this breakpoint.
367
+ */
368
+ static VALUE
369
+ breakpoint_pos(VALUE self)
370
+ {
371
+ debug_breakpoint_t *breakpoint;
372
+
373
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
374
+ if(breakpoint->type == BP_METHOD_TYPE)
375
+ return rb_str_new2(rb_id2name(breakpoint->pos.mid));
376
+ else
377
+ return INT2FIX(breakpoint->pos.line);
378
+ }
379
+
380
+ /*
381
+ * call-seq:
382
+ * breakpoint.pos = string or int
383
+ *
384
+ * Sets the position of this breakpoint.
385
+ */
386
+ static VALUE
387
+ breakpoint_set_pos(VALUE self, VALUE value)
388
+ {
389
+ debug_breakpoint_t *breakpoint;
390
+
391
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
392
+ if(breakpoint->type == BP_METHOD_TYPE)
393
+ {
394
+ breakpoint->pos.mid = rb_to_id(StringValue(value));
395
+ }
396
+ else
397
+ breakpoint->pos.line = FIX2INT(value);
398
+ return value;
399
+ }
400
+
401
+ /*
402
+ * call-seq:
403
+ * breakpoint.expr -> string
404
+ *
405
+ * Returns a codition expression when this breakpoint should be activated.
406
+ */
407
+ static VALUE
408
+ breakpoint_expr(VALUE self)
409
+ {
410
+ debug_breakpoint_t *breakpoint;
411
+
412
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
413
+ return breakpoint->expr;
414
+ }
415
+
416
+ /*
417
+ * call-seq:
418
+ * breakpoint.expr = string | nil
419
+ *
420
+ * Sets the codition expression when this breakpoint should be activated.
421
+ */
422
+ static VALUE
423
+ breakpoint_set_expr(VALUE self, VALUE expr)
424
+ {
425
+ debug_breakpoint_t *breakpoint;
426
+
427
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
428
+ breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
429
+ return expr;
430
+ }
431
+
432
+ /*
433
+ * call-seq:
434
+ * breakpoint.id -> int
435
+ *
436
+ * Returns id of the breakpoint.
437
+ */
438
+ static VALUE
439
+ breakpoint_id(VALUE self)
440
+ {
441
+ debug_breakpoint_t *breakpoint;
442
+
443
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
444
+ return INT2FIX(breakpoint->id);
445
+ }
446
+
447
+ /*
448
+ * call-seq:
449
+ * breakpoint.hit_count -> int
450
+ *
451
+ * Returns the hit count of the breakpoint.
452
+ */
453
+ static VALUE
454
+ breakpoint_hit_count(VALUE self)
455
+ {
456
+ debug_breakpoint_t *breakpoint;
457
+
458
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
459
+ return INT2FIX(breakpoint->hit_count);
460
+ }
461
+
462
+ /*
463
+ * call-seq:
464
+ * breakpoint.hit_value -> int
465
+ *
466
+ * Returns the hit value of the breakpoint.
467
+ */
468
+ static VALUE
469
+ breakpoint_hit_value(VALUE self)
470
+ {
471
+ debug_breakpoint_t *breakpoint;
472
+
473
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
474
+ return INT2FIX(breakpoint->hit_value);
475
+ }
476
+
477
+ /*
478
+ * call-seq:
479
+ * breakpoint.hit_value = int
480
+ *
481
+ * Sets the hit value of the breakpoint.
482
+ */
483
+ static VALUE
484
+ breakpoint_set_hit_value(VALUE self, VALUE value)
485
+ {
486
+ debug_breakpoint_t *breakpoint;
487
+
488
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
489
+ breakpoint->hit_value = FIX2INT(value);
490
+ return value;
491
+ }
492
+
493
+ /*
494
+ * call-seq:
495
+ * breakpoint.hit_condition -> symbol
496
+ *
497
+ * Returns the hit condition of the breakpoint:
498
+ *
499
+ * +nil+ if it is an unconditional breakpoint, or
500
+ * :greater_or_equal, :equal, :modulo
501
+ */
502
+ static VALUE
503
+ breakpoint_hit_condition(VALUE self)
504
+ {
505
+ debug_breakpoint_t *breakpoint;
506
+
507
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
508
+ switch(breakpoint->hit_condition)
509
+ {
510
+ case HIT_COND_GE:
511
+ return ID2SYM(rb_intern("greater_or_equal"));
512
+ case HIT_COND_EQ:
513
+ return ID2SYM(rb_intern("equal"));
514
+ case HIT_COND_MOD:
515
+ return ID2SYM(rb_intern("modulo"));
516
+ case HIT_COND_NONE:
517
+ default:
518
+ return Qnil;
519
+ }
520
+ }
521
+
522
+ /*
523
+ * call-seq:
524
+ * breakpoint.hit_condition = symbol
525
+ *
526
+ * Sets the hit condition of the breakpoint which must be one of the following values:
527
+ *
528
+ * +nil+ if it is an unconditional breakpoint, or
529
+ * :greater_or_equal(:ge), :equal(:eq), :modulo(:mod)
530
+ */
531
+ static VALUE
532
+ breakpoint_set_hit_condition(VALUE self, VALUE value)
533
+ {
534
+ debug_breakpoint_t *breakpoint;
535
+ ID id_value;
536
+
537
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
538
+ id_value = rb_to_id(value);
539
+
540
+ if(rb_intern("greater_or_equal") == id_value || rb_intern("ge") == id_value)
541
+ breakpoint->hit_condition = HIT_COND_GE;
542
+ else if(rb_intern("equal") == id_value || rb_intern("eq") == id_value)
543
+ breakpoint->hit_condition = HIT_COND_EQ;
544
+ else if(rb_intern("modulo") == id_value || rb_intern("mod") == id_value)
545
+ breakpoint->hit_condition = HIT_COND_MOD;
546
+ else
547
+ rb_raise(rb_eArgError, "Invalid condition parameter");
548
+ return value;
549
+ }
550
+
551
+ /*
552
+ * Document-class: Breakpoint
553
+ *
554
+ * == Summary
555
+ *
556
+ * This class represents a breakpoint. It defines position of the breakpoint and
557
+ * condition when this breakpoint should be triggered.
558
+ */
559
+ void
560
+ Init_breakpoint()
561
+ {
562
+ cBreakpoint = rb_define_class_under(mDebugger, "Breakpoint", rb_cObject);
563
+ rb_define_method(cBreakpoint, "enabled=", breakpoint_set_enabled, 1);
564
+ rb_define_method(cBreakpoint, "enabled?", breakpoint_enabled, 0);
565
+ rb_define_method(cBreakpoint, "expr", breakpoint_expr, 0);
566
+ rb_define_method(cBreakpoint, "expr=", breakpoint_set_expr, 1);
567
+ rb_define_method(cBreakpoint, "hit_condition", breakpoint_hit_condition, 0);
568
+ rb_define_method(cBreakpoint, "hit_condition=", breakpoint_set_hit_condition, 1);
569
+ rb_define_method(cBreakpoint, "hit_count", breakpoint_hit_count, 0);
570
+ rb_define_method(cBreakpoint, "hit_value", breakpoint_hit_value, 0);
571
+ rb_define_method(cBreakpoint, "hit_value=", breakpoint_set_hit_value, 1);
572
+ rb_define_method(cBreakpoint, "id", breakpoint_id, 0);
573
+ rb_define_method(cBreakpoint, "pos", breakpoint_pos, 0);
574
+ rb_define_method(cBreakpoint, "pos=", breakpoint_set_pos, 1);
575
+ rb_define_method(cBreakpoint, "source", breakpoint_source, 0);
576
+ rb_define_method(cBreakpoint, "source=", breakpoint_set_source, 1);
577
+ idEval = rb_intern("eval");
578
+ rdebug_catchpoints = rb_hash_new();
579
+
580
+ }
581
+
582
+