ruby-debug-base19x 0.11.25.jb3

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/Rakefile ADDED
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env rake
2
+ # -*- Ruby -*-
3
+ require 'rubygems'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/testtask'
7
+ #require 'rake/extensiontask'
8
+
9
+ #Rake::ExtensionTask.new('ruby_debug')
10
+
11
+ SO_NAME = "ruby_debug.so"
12
+
13
+ # ------- Default Package ----------
14
+ RUBY_DEBUG_VERSION = open("ext/ruby_debug/ruby_debug.c") do |f|
15
+ f.grep(/^#define DEBUG_VERSION/).first[/"(.+)"/,1]
16
+ end
17
+
18
+ COMMON_FILES = FileList[
19
+ 'AUTHORS',
20
+ 'CHANGES',
21
+ 'LICENSE',
22
+ 'README',
23
+ 'Rakefile',
24
+ ]
25
+
26
+ BASE_TEST_FILE_LIST = %w(
27
+ test/base/base.rb
28
+ test/base/binding.rb
29
+ test/base/catchpoint.rb)
30
+ BASE_FILES = COMMON_FILES + FileList[
31
+ 'ext/ruby_debug/breakpoint.c',
32
+ 'ext/ruby_debug/extconf.rb',
33
+ 'ext/ruby_debug/ruby_debug.c',
34
+ 'ext/ruby_debug/ruby_debug.h',
35
+ 'ext/win32/*',
36
+ 'lib/**/*',
37
+ BASE_TEST_FILE_LIST,
38
+ ]
39
+
40
+ # Base GEM Specification
41
+ base_spec = Gem::Specification.new do |spec|
42
+ spec.name = "ruby-debug-base19x"
43
+
44
+ spec.homepage = "http://rubyforge.org/projects/ruby-debug/"
45
+ spec.summary = "Fast Ruby debugger - core component"
46
+ spec.description = <<-EOF
47
+ ruby-debug is a fast implementation of the standard Ruby debugger debug.rb.
48
+ It is implemented by utilizing a new Ruby C API hook. The core component
49
+ provides support that front-ends can build on. It provides breakpoint
50
+ handling, bindings for stack frames among other things.
51
+ EOF
52
+
53
+ spec.version = RUBY_DEBUG_VERSION
54
+
55
+ spec.author = "Kent Sibilev, Mark Moseley"
56
+ spec.email = "ksibilev@yahoo.com"
57
+ spec.platform = Gem::Platform::RUBY
58
+ spec.require_path = "lib"
59
+ spec.extensions = ["ext/ruby_debug/extconf.rb"]
60
+ spec.files = BASE_FILES.to_a
61
+
62
+ spec.required_ruby_version = '>= 1.8.2'
63
+ spec.date = Time.now
64
+ spec.rubyforge_project = 'ruby-debug19'
65
+ spec.add_dependency('columnize', [">= 0.3.1"])
66
+ spec.add_dependency('ruby_core_source', [">= 0.1.4"])
67
+ spec.add_dependency('linecache19', [">= 0.5.11"])
68
+
69
+ spec.test_files = FileList[BASE_TEST_FILE_LIST]
70
+
71
+ # rdoc
72
+ spec.has_rdoc = true
73
+ spec.extra_rdoc_files = ['README', 'ext/ruby_debug/ruby_debug.c']
74
+ end
75
+
76
+
77
+ # Rake task to build the default package
78
+ Rake::GemPackageTask.new(base_spec) do |pkg|
79
+ pkg.need_tar = true
80
+ end
81
+
82
+ task :default => [:package]
83
+
84
+ # Windows specification
85
+ win_spec = base_spec.clone
86
+ win_spec.extensions = []
87
+ ## win_spec.platform = Gem::Platform::WIN32 # deprecated
88
+ win_spec.platform = 'mswin32'
89
+ win_spec.files += ["lib/#{SO_NAME}"]
90
+
91
+ desc "Create Windows Gem"
92
+ task :win32_gem do
93
+ # Copy the win32 extension the top level directory
94
+ current_dir = File.expand_path(File.dirname(__FILE__))
95
+ source = File.join(current_dir, "ext", "win32", SO_NAME)
96
+ target = File.join(current_dir, "lib", SO_NAME)
97
+ cp(source, target)
98
+
99
+ # Create the gem, then move it to pkg.
100
+ Gem::Builder.new(win_spec).build
101
+ gem_file = "#{win_spec.name}-#{win_spec.version}-#{win_spec.platform}.gem"
102
+ mv(gem_file, "pkg/#{gem_file}")
103
+
104
+ # Remove win extension from top level directory.
105
+ rm(target)
106
+ end
107
+
108
+ desc "Publish ruby-debug to RubyForge."
109
+ task :publish do
110
+ require 'rake/contrib/sshpublisher'
111
+
112
+ # Get ruby-debug path.
113
+ ruby_debug_path = File.expand_path(File.dirname(__FILE__))
114
+
115
+ Rake::SshDirPublisher.new("kent@rubyforge.org",
116
+ "/var/www/gforge-projects/ruby-debug", ruby_debug_path)
117
+ end
118
+
119
+ desc "Remove built files"
120
+ task :clean do
121
+ cd "ext" do
122
+ if File.exists?("Makefile")
123
+ sh "make clean"
124
+ rm "Makefile"
125
+ end
126
+ derived_files = Dir.glob(".o") + Dir.glob("*.so")
127
+ rm derived_files unless derived_files.empty?
128
+ end
129
+ end
130
+
@@ -0,0 +1,586 @@
1
+ #include <ruby.h>
2
+ #include <stdio.h>
3
+ #include <vm_core.h>
4
+ #include <iseq.h>
5
+ #include "ruby_debug.h"
6
+
7
+ VALUE rdebug_breakpoints = Qnil;
8
+ VALUE rdebug_catchpoints;
9
+
10
+ static VALUE cBreakpoint;
11
+ static ID idEval;
12
+
13
+ static VALUE
14
+ eval_expression(VALUE args)
15
+ {
16
+ return rb_funcall2(rb_mKernel, idEval, 2, RARRAY_PTR(args));
17
+ }
18
+
19
+ int
20
+ check_breakpoint_hit_condition(VALUE breakpoint)
21
+ {
22
+ debug_breakpoint_t *debug_breakpoint;
23
+
24
+ if(breakpoint == Qnil)
25
+ return 0;
26
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
27
+
28
+ debug_breakpoint->hit_count++;
29
+ if (!Qtrue == debug_breakpoint->enabled) return 0;
30
+ switch(debug_breakpoint->hit_condition)
31
+ {
32
+ case HIT_COND_NONE:
33
+ return 1;
34
+ case HIT_COND_GE:
35
+ {
36
+ if(debug_breakpoint->hit_count >= debug_breakpoint->hit_value)
37
+ return 1;
38
+ break;
39
+ }
40
+ case HIT_COND_EQ:
41
+ {
42
+ if(debug_breakpoint->hit_count == debug_breakpoint->hit_value)
43
+ return 1;
44
+ break;
45
+ }
46
+ case HIT_COND_MOD:
47
+ {
48
+ if(debug_breakpoint->hit_count % debug_breakpoint->hit_value == 0)
49
+ return 1;
50
+ break;
51
+ }
52
+ }
53
+ return 0;
54
+ }
55
+
56
+ static int
57
+ check_breakpoint_by_pos(VALUE breakpoint, char *file, int line)
58
+ {
59
+ debug_breakpoint_t *debug_breakpoint;
60
+
61
+ if(breakpoint == Qnil)
62
+ return 0;
63
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
64
+ if (!Qtrue == debug_breakpoint->enabled) return 0;
65
+ if(debug_breakpoint->type != BP_POS_TYPE)
66
+ return 0;
67
+ if(debug_breakpoint->pos.line != line)
68
+ return 0;
69
+ if(filename_cmp(debug_breakpoint->source, file))
70
+ return 1;
71
+ return 0;
72
+ }
73
+
74
+ int
75
+ check_breakpoint_by_method(VALUE breakpoint, VALUE klass, ID mid, VALUE self)
76
+ {
77
+ debug_breakpoint_t *debug_breakpoint;
78
+
79
+ if(breakpoint == Qnil)
80
+ return 0;
81
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
82
+ if (!Qtrue == debug_breakpoint->enabled) return 0;
83
+ if(debug_breakpoint->type != BP_METHOD_TYPE)
84
+ return 0;
85
+ if(debug_breakpoint->pos.mid != mid)
86
+ return 0;
87
+ if(classname_cmp(debug_breakpoint->source, klass))
88
+ return 1;
89
+ if ((rb_type(self) == T_CLASS) &&
90
+ classname_cmp(debug_breakpoint->source, self))
91
+ return 1;
92
+ return 0;
93
+ }
94
+
95
+ VALUE
96
+ check_breakpoints_by_pos(debug_context_t *debug_context, char *file, int line)
97
+ {
98
+ VALUE breakpoint;
99
+ int i;
100
+
101
+ if(!CTX_FL_TEST(debug_context, CTX_FL_ENABLE_BKPT))
102
+ return Qnil;
103
+
104
+ if(check_breakpoint_by_pos(debug_context->breakpoint, file, line))
105
+ return debug_context->breakpoint;
106
+
107
+ if(RARRAY_LEN(rdebug_breakpoints) == 0)
108
+ return Qnil;
109
+ for(i = 0; i < RARRAY_LEN(rdebug_breakpoints); i++)
110
+ {
111
+ breakpoint = rb_ary_entry(rdebug_breakpoints, i);
112
+ if(check_breakpoint_by_pos(breakpoint, file, line))
113
+ return breakpoint;
114
+ }
115
+ return Qnil;
116
+ }
117
+
118
+ VALUE
119
+ check_breakpoints_by_method(debug_context_t *debug_context, VALUE klass, ID mid, VALUE self)
120
+ {
121
+ VALUE breakpoint;
122
+ int i;
123
+
124
+ if(!CTX_FL_TEST(debug_context, CTX_FL_ENABLE_BKPT))
125
+ return Qnil;
126
+
127
+ if(check_breakpoint_by_method(debug_context->breakpoint, klass, mid, self))
128
+ return debug_context->breakpoint;
129
+
130
+ if(RARRAY_LEN(rdebug_breakpoints) == 0)
131
+ return Qnil;
132
+ for(i = 0; i < RARRAY_LEN(rdebug_breakpoints); i++)
133
+ {
134
+ breakpoint = rb_ary_entry(rdebug_breakpoints, i);
135
+ if(check_breakpoint_by_method(breakpoint, klass, mid, self))
136
+ return breakpoint;
137
+ }
138
+ return Qnil;
139
+ }
140
+
141
+ int
142
+ check_breakpoint_expression(VALUE breakpoint, VALUE binding)
143
+ {
144
+ debug_breakpoint_t *debug_breakpoint;
145
+ VALUE args, expr_result;
146
+
147
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
148
+ if(NIL_P(debug_breakpoint->expr))
149
+ return 1;
150
+
151
+ args = rb_ary_new3(2, debug_breakpoint->expr, binding);
152
+ expr_result = rb_protect(eval_expression, args, 0);
153
+ return RTEST(expr_result);
154
+ }
155
+
156
+ static void
157
+ breakpoint_mark(void *data)
158
+ {
159
+ debug_breakpoint_t *breakpoint;
160
+ breakpoint = (debug_breakpoint_t *)data;
161
+ rb_gc_mark(breakpoint->source);
162
+ rb_gc_mark(breakpoint->expr);
163
+ }
164
+
165
+ VALUE
166
+ create_breakpoint_from_args(int argc, VALUE *argv, int id)
167
+ {
168
+ VALUE source, pos, expr;
169
+ debug_breakpoint_t *breakpoint;
170
+ int type;
171
+
172
+ if(rb_scan_args(argc, argv, "21", &source, &pos, &expr) == 2)
173
+ {
174
+ expr = Qnil;
175
+ }
176
+ type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
177
+ if(type == BP_POS_TYPE)
178
+ source = StringValue(source);
179
+ else
180
+ pos = StringValue(pos);
181
+ breakpoint = ALLOC(debug_breakpoint_t);
182
+ breakpoint->id = id;
183
+ breakpoint->source = source;
184
+ breakpoint->type = type;
185
+ if(type == BP_POS_TYPE)
186
+ breakpoint->pos.line = FIX2INT(pos);
187
+ else
188
+ breakpoint->pos.mid = rb_intern(RSTRING_PTR(pos));
189
+ breakpoint->enabled = Qtrue;
190
+ breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
191
+ breakpoint->hit_count = 0;
192
+ breakpoint->hit_value = 0;
193
+ breakpoint->hit_condition = HIT_COND_NONE;
194
+ return Data_Wrap_Struct(cBreakpoint, breakpoint_mark, xfree, breakpoint);
195
+ }
196
+
197
+ /*
198
+ * call-seq:
199
+ * Debugger.remove_breakpoint(id) -> breakpoint
200
+ *
201
+ * Removes breakpoint by its id.
202
+ * <i>id</i> is an identificator of a breakpoint.
203
+ */
204
+ VALUE
205
+ rdebug_remove_breakpoint(VALUE self, VALUE id_value)
206
+ {
207
+ int i;
208
+ int id;
209
+ VALUE breakpoint;
210
+ debug_breakpoint_t *debug_breakpoint;
211
+
212
+ id = FIX2INT(id_value);
213
+
214
+ for( i = 0; i < RARRAY_LEN(rdebug_breakpoints); i += 1 )
215
+ {
216
+ breakpoint = rb_ary_entry(rdebug_breakpoints, i);
217
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
218
+ if(debug_breakpoint->id == id)
219
+ {
220
+ rb_ary_delete_at(rdebug_breakpoints, i);
221
+ return breakpoint;
222
+ }
223
+ }
224
+ return Qnil;
225
+ }
226
+
227
+ /*
228
+ * call-seq:
229
+ * Debugger.catchpoints -> hash
230
+ *
231
+ * Returns a current catchpoints, which is a hash exception names that will
232
+ * trigger a debugger when raised. The values are the number of times taht
233
+ * catchpoint was hit, initially 0.
234
+ */
235
+ VALUE
236
+ debug_catchpoints(VALUE self)
237
+ {
238
+ debug_check_started();
239
+
240
+ return rdebug_catchpoints;
241
+ }
242
+
243
+ /*
244
+ * call-seq:
245
+ * Debugger.catchpoint(string) -> string
246
+ *
247
+ * Sets catchpoint. Returns the string passed.
248
+ */
249
+ VALUE
250
+ rdebug_add_catchpoint(VALUE self, VALUE value)
251
+ {
252
+ debug_check_started();
253
+
254
+ if (TYPE(value) != T_STRING) {
255
+ rb_raise(rb_eTypeError, "value of a catchpoint must be String");
256
+ }
257
+ rb_hash_aset(rdebug_catchpoints, rb_str_dup(value), INT2FIX(0));
258
+ return value;
259
+ }
260
+
261
+ /*
262
+ * call-seq:
263
+ * context.breakpoint -> breakpoint
264
+ *
265
+ * Returns a context-specific temporary Breakpoint object.
266
+ */
267
+ VALUE
268
+ context_breakpoint(VALUE self)
269
+ {
270
+ debug_context_t *debug_context;
271
+
272
+ debug_check_started();
273
+
274
+ Data_Get_Struct(self, debug_context_t, debug_context);
275
+ return debug_context->breakpoint;
276
+ }
277
+
278
+ /*
279
+ * call-seq:
280
+ * context.set_breakpoint(source, pos, condition = nil) -> breakpoint
281
+ *
282
+ * Sets a context-specific temporary breakpoint, which can be used to implement
283
+ * 'Run to Cursor' debugger function. When this breakpoint is reached, it will be
284
+ * cleared out.
285
+ *
286
+ * <i>source</i> is a name of a file or a class.
287
+ * <i>pos</i> is a line number or a method name if <i>source</i> is a class name.
288
+ * <i>condition</i> is a string which is evaluated to +true+ when this breakpoint
289
+ * is activated.
290
+ */
291
+ VALUE
292
+ context_set_breakpoint(int argc, VALUE *argv, VALUE self)
293
+ {
294
+ VALUE result;
295
+ debug_context_t *debug_context;
296
+
297
+ debug_check_started();
298
+
299
+ Data_Get_Struct(self, debug_context_t, debug_context);
300
+ result = create_breakpoint_from_args(argc, argv, 0);
301
+ debug_context->breakpoint = result;
302
+ return result;
303
+ }
304
+
305
+ /*
306
+ * call-seq:
307
+ * breakpoint.enabled?
308
+ *
309
+ * Returns whether breakpoint is enabled or not.
310
+ */
311
+ static VALUE
312
+ breakpoint_enabled(VALUE self)
313
+ {
314
+ debug_breakpoint_t *breakpoint;
315
+
316
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
317
+ return breakpoint->enabled;
318
+ }
319
+
320
+ /*
321
+ * call-seq:
322
+ * breakpoint.enabled = bool
323
+ *
324
+ * Enables or disables breakpoint.
325
+ */
326
+ static VALUE
327
+ breakpoint_set_enabled(VALUE self, VALUE bool)
328
+ {
329
+ debug_breakpoint_t *breakpoint;
330
+
331
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
332
+ return breakpoint->enabled = bool;
333
+ }
334
+
335
+ /*
336
+ * call-seq:
337
+ * breakpoint.source -> string
338
+ *
339
+ * Returns a source of the breakpoint.
340
+ */
341
+ static VALUE
342
+ breakpoint_source(VALUE self)
343
+ {
344
+ debug_breakpoint_t *breakpoint;
345
+
346
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
347
+ return breakpoint->source;
348
+ }
349
+
350
+ /*
351
+ * call-seq:
352
+ * breakpoint.source = string
353
+ *
354
+ * Sets the source of the breakpoint.
355
+ */
356
+ static VALUE
357
+ breakpoint_set_source(VALUE self, VALUE value)
358
+ {
359
+ debug_breakpoint_t *breakpoint;
360
+
361
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
362
+ breakpoint->source = StringValue(value);
363
+ return value;
364
+ }
365
+
366
+ /*
367
+ * call-seq:
368
+ * breakpoint.pos -> string or int
369
+ *
370
+ * Returns the position of this breakpoint.
371
+ */
372
+ static VALUE
373
+ breakpoint_pos(VALUE self)
374
+ {
375
+ debug_breakpoint_t *breakpoint;
376
+
377
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
378
+ if(breakpoint->type == BP_METHOD_TYPE)
379
+ return rb_str_new2(rb_id2name(breakpoint->pos.mid));
380
+ else
381
+ return INT2FIX(breakpoint->pos.line);
382
+ }
383
+
384
+ /*
385
+ * call-seq:
386
+ * breakpoint.pos = string or int
387
+ *
388
+ * Sets the position of this breakpoint.
389
+ */
390
+ static VALUE
391
+ breakpoint_set_pos(VALUE self, VALUE value)
392
+ {
393
+ debug_breakpoint_t *breakpoint;
394
+
395
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
396
+ if(breakpoint->type == BP_METHOD_TYPE)
397
+ {
398
+ breakpoint->pos.mid = rb_to_id(StringValue(value));
399
+ }
400
+ else
401
+ breakpoint->pos.line = FIX2INT(value);
402
+ return value;
403
+ }
404
+
405
+ /*
406
+ * call-seq:
407
+ * breakpoint.expr -> string
408
+ *
409
+ * Returns a codition expression when this breakpoint should be activated.
410
+ */
411
+ static VALUE
412
+ breakpoint_expr(VALUE self)
413
+ {
414
+ debug_breakpoint_t *breakpoint;
415
+
416
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
417
+ return breakpoint->expr;
418
+ }
419
+
420
+ /*
421
+ * call-seq:
422
+ * breakpoint.expr = string | nil
423
+ *
424
+ * Sets the codition expression when this breakpoint should be activated.
425
+ */
426
+ static VALUE
427
+ breakpoint_set_expr(VALUE self, VALUE expr)
428
+ {
429
+ debug_breakpoint_t *breakpoint;
430
+
431
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
432
+ breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
433
+ return expr;
434
+ }
435
+
436
+ /*
437
+ * call-seq:
438
+ * breakpoint.id -> int
439
+ *
440
+ * Returns id of the breakpoint.
441
+ */
442
+ static VALUE
443
+ breakpoint_id(VALUE self)
444
+ {
445
+ debug_breakpoint_t *breakpoint;
446
+
447
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
448
+ return INT2FIX(breakpoint->id);
449
+ }
450
+
451
+ /*
452
+ * call-seq:
453
+ * breakpoint.hit_count -> int
454
+ *
455
+ * Returns the hit count of the breakpoint.
456
+ */
457
+ static VALUE
458
+ breakpoint_hit_count(VALUE self)
459
+ {
460
+ debug_breakpoint_t *breakpoint;
461
+
462
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
463
+ return INT2FIX(breakpoint->hit_count);
464
+ }
465
+
466
+ /*
467
+ * call-seq:
468
+ * breakpoint.hit_value -> int
469
+ *
470
+ * Returns the hit value of the breakpoint.
471
+ */
472
+ static VALUE
473
+ breakpoint_hit_value(VALUE self)
474
+ {
475
+ debug_breakpoint_t *breakpoint;
476
+
477
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
478
+ return INT2FIX(breakpoint->hit_value);
479
+ }
480
+
481
+ /*
482
+ * call-seq:
483
+ * breakpoint.hit_value = int
484
+ *
485
+ * Sets the hit value of the breakpoint.
486
+ */
487
+ static VALUE
488
+ breakpoint_set_hit_value(VALUE self, VALUE value)
489
+ {
490
+ debug_breakpoint_t *breakpoint;
491
+
492
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
493
+ breakpoint->hit_value = FIX2INT(value);
494
+ return value;
495
+ }
496
+
497
+ /*
498
+ * call-seq:
499
+ * breakpoint.hit_condition -> symbol
500
+ *
501
+ * Returns the hit condition of the breakpoint:
502
+ *
503
+ * +nil+ if it is an unconditional breakpoint, or
504
+ * :greater_or_equal, :equal, :modulo
505
+ */
506
+ static VALUE
507
+ breakpoint_hit_condition(VALUE self)
508
+ {
509
+ debug_breakpoint_t *breakpoint;
510
+
511
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
512
+ switch(breakpoint->hit_condition)
513
+ {
514
+ case HIT_COND_GE:
515
+ return ID2SYM(rb_intern("greater_or_equal"));
516
+ case HIT_COND_EQ:
517
+ return ID2SYM(rb_intern("equal"));
518
+ case HIT_COND_MOD:
519
+ return ID2SYM(rb_intern("modulo"));
520
+ case HIT_COND_NONE:
521
+ default:
522
+ return Qnil;
523
+ }
524
+ }
525
+
526
+ /*
527
+ * call-seq:
528
+ * breakpoint.hit_condition = symbol
529
+ *
530
+ * Sets the hit condition of the breakpoint which must be one of the following values:
531
+ *
532
+ * +nil+ if it is an unconditional breakpoint, or
533
+ * :greater_or_equal(:ge), :equal(:eq), :modulo(:mod)
534
+ */
535
+ static VALUE
536
+ breakpoint_set_hit_condition(VALUE self, VALUE value)
537
+ {
538
+ debug_breakpoint_t *breakpoint;
539
+ ID id_value;
540
+
541
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
542
+ id_value = rb_to_id(value);
543
+
544
+ if(rb_intern("greater_or_equal") == id_value || rb_intern("ge") == id_value)
545
+ breakpoint->hit_condition = HIT_COND_GE;
546
+ else if(rb_intern("equal") == id_value || rb_intern("eq") == id_value)
547
+ breakpoint->hit_condition = HIT_COND_EQ;
548
+ else if(rb_intern("modulo") == id_value || rb_intern("mod") == id_value)
549
+ breakpoint->hit_condition = HIT_COND_MOD;
550
+ else
551
+ rb_raise(rb_eArgError, "Invalid condition parameter");
552
+ return value;
553
+ }
554
+
555
+ /*
556
+ * Document-class: Breakpoint
557
+ *
558
+ * == Summary
559
+ *
560
+ * This class represents a breakpoint. It defines position of the breakpoint and
561
+ * condition when this breakpoint should be triggered.
562
+ */
563
+ void
564
+ Init_breakpoint()
565
+ {
566
+ cBreakpoint = rb_define_class_under(mDebugger, "Breakpoint", rb_cObject);
567
+ rb_define_method(cBreakpoint, "enabled=", breakpoint_set_enabled, 1);
568
+ rb_define_method(cBreakpoint, "enabled?", breakpoint_enabled, 0);
569
+ rb_define_method(cBreakpoint, "expr", breakpoint_expr, 0);
570
+ rb_define_method(cBreakpoint, "expr=", breakpoint_set_expr, 1);
571
+ rb_define_method(cBreakpoint, "hit_condition", breakpoint_hit_condition, 0);
572
+ rb_define_method(cBreakpoint, "hit_condition=", breakpoint_set_hit_condition, 1);
573
+ rb_define_method(cBreakpoint, "hit_count", breakpoint_hit_count, 0);
574
+ rb_define_method(cBreakpoint, "hit_value", breakpoint_hit_value, 0);
575
+ rb_define_method(cBreakpoint, "hit_value=", breakpoint_set_hit_value, 1);
576
+ rb_define_method(cBreakpoint, "id", breakpoint_id, 0);
577
+ rb_define_method(cBreakpoint, "pos", breakpoint_pos, 0);
578
+ rb_define_method(cBreakpoint, "pos=", breakpoint_set_pos, 1);
579
+ rb_define_method(cBreakpoint, "source", breakpoint_source, 0);
580
+ rb_define_method(cBreakpoint, "source=", breakpoint_set_source, 1);
581
+ idEval = rb_intern("eval");
582
+ rdebug_catchpoints = rb_hash_new();
583
+
584
+ }
585
+
586
+