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);