ext/ruby_debug.c in ruby-debug-0.5.2-mswin32 vs ext/ruby_debug.c in ruby-debug-0.5.3
- old
+ new
@@ -2,11 +2,11 @@
#include <ruby.h>
#include <node.h>
#include <rubysig.h>
#include <st.h>
-#define DEBUG_VERSION "0.5.2"
+#define DEBUG_VERSION "0.5.3"
#define CTX_FL_MOVED (1<<1)
#define CTX_FL_SUSPEND (1<<2)
#define CTX_FL_TRACING (1<<3)
#define CTX_FL_SKIPPED (1<<4)
@@ -41,10 +41,11 @@
VALUE binding;
ID id;
} debug_frame_t;
typedef struct {
+ int id;
VALUE source;
VALUE pos;
VALUE expr;
} debug_breakpoint_t;
@@ -79,10 +80,11 @@
static ID idClear;
static ID idIndex;
static int start_count = 0;
static int thnum_max = 0;
+static int bkp_count = 0;
static int last_debugged_thnum = -1;
static VALUE create_binding(VALUE);
static VALUE debug_stop(VALUE);
@@ -625,11 +627,10 @@
int i;
if(post_mortem == Qtrue && self)
{
binding = create_binding(self);
- rb_ivar_set(ruby_errinfo, rb_intern("@__debug_binding"), binding);
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_file"), file);
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_line"), line);
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_binding"), binding);
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_frames"), rb_obj_dup(debug_context->frames));
}
@@ -782,19 +783,50 @@
expr = Qnil;
}
breakpoint = ALLOC(debug_breakpoint_t);
breakpoint->source = StringValue(source);
+ breakpoint->id = ++bkp_count;
breakpoint->pos = pos;
breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
result = Data_Wrap_Struct(cBreakpoint, breakpoint_mark, xfree, breakpoint);
rb_ary_push(breakpoints, result);
return result;
}
/*
* call-seq:
+ * Debugger.remove_breakpoint(id) -> breakpoint
+ *
+ * Removes breakpoint by its id.
+ * <i>id</i> is an identificator of a breakpoint.
+ */
+static VALUE
+debug_remove_breakpoint(VALUE self, VALUE id_value)
+{
+ int i;
+ int id;
+ VALUE breakpoint;
+ debug_breakpoint_t *debug_breakpoint;
+
+ id = FIX2INT(id_value);
+
+ for( i = 0; i < RARRAY(breakpoints)->len; i += 1 )
+ {
+ breakpoint = rb_ary_entry(breakpoints, i);
+ Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
+ if(debug_breakpoint->id == id)
+ {
+ rb_ary_delete_at(breakpoints, i);
+ return breakpoint;
+ }
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
* Debugger.breakpoints -> array
*
* Returns an array of breakpoints.
*/
static VALUE
@@ -1502,10 +1534,25 @@
Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
return breakpoint->expr;
}
/*
+ * call-seq:
+ * breakpoint.id -> int
+ *
+ * Returns id of the breakpoint.
+ */
+static VALUE
+breakpoint_id(VALUE self)
+{
+ debug_breakpoint_t *breakpoint;
+
+ Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
+ return INT2FIX(breakpoint->id);
+}
+
+/*
* Document-class: Context
*
* == Summary
*
* Debugger keeps a single instance of this class for each Ruby thread.
@@ -1560,10 +1607,11 @@
{
cBreakpoint = rb_define_class_under(mDebugger, "Breakpoint", rb_cObject);
rb_define_method(cBreakpoint, "source", breakpoint_source, 0);
rb_define_method(cBreakpoint, "pos", breakpoint_pos, 0);
rb_define_method(cBreakpoint, "expr", breakpoint_expr, 0);
+ rb_define_method(cBreakpoint, "id", breakpoint_id, 0);
}
/*
* Document-class: Debugger
*
@@ -1583,9 +1631,10 @@
rb_define_module_function(mDebugger, "start", debug_start, 0);
rb_define_module_function(mDebugger, "stop", debug_stop, 0);
rb_define_module_function(mDebugger, "started?", debug_is_started, 0);
rb_define_module_function(mDebugger, "breakpoints", debug_breakpoints, 0);
rb_define_module_function(mDebugger, "add_breakpoint", debug_add_breakpoint, -1);
+ rb_define_module_function(mDebugger, "remove_breakpoint", debug_remove_breakpoint, 1);
rb_define_module_function(mDebugger, "catchpoint", debug_catchpoint, 0);
rb_define_module_function(mDebugger, "catchpoint=", debug_set_catchpoint, 1);
rb_define_module_function(mDebugger, "last_context", debug_last_interrupted, 0);
rb_define_module_function(mDebugger, "contexts", debug_contexts, 0);
rb_define_module_function(mDebugger, "current_context", debug_current_context, 0);