/**
 * file_tracepoint_callback
 * Callback function for Tracer#file_tracepoint. It gets called on
 * RUBY_EVENT_CLASS, RUBY_EVENT_CALL, and RUBY_EVENT_B_CALL
 * events. It check if any breakpoints matches current file the VM program counter
 * is in, and turn on line event tracing for that thread. Otherwise turn off
 * line tracing if in wrong file. The first time it turns on line event tracing,
 * it also turns on Tracer#return_tracepoint to maintain line tracing
 * consistency when file execution interleaves.
 */
static void
file_tracepoint_callback(VALUE tracepoint, void *data)
{
    VALUE self = (VALUE) data;
    rb_trace_arg_t *tracepoint_arg = rb_tracearg_from_tracepoint(tracepoint);
    VALUE tracepoint_path = rb_tracearg_path(tracepoint_arg);
    int match_found;

    if (!RB_TYPE_P(tracepoint_path, T_STRING))
        return;

    // Ensure tracepoint_path is absolute path
    tracepoint_path = rb_file_expand_path(tracepoint_path, Qnil);

    if (!RTEST(tracepoint_path)) {
        return;
    }

    match_found = match_breakpoints_files(self, tracepoint_path);

    if (match_found) {
        enable_line_trace_for_thread(self);
        enable_return_trace_for_thread(self);
    }
    else {
        disable_line_trace_for_thread(Qnil);
    }

    return;
}
Beispiel #2
0
int
rb_feature_provided(const char *feature, const char **loading)
{
    const char *ext = strrchr(feature, '.');
    volatile VALUE fullpath = 0;

    if (*feature == '.' &&
	(feature[1] == '/' || strncmp(feature+1, "./", 2) == 0)) {
	fullpath = rb_file_expand_path(rb_str_new2(feature), Qnil);
	feature = RSTRING_PTR(fullpath);
    }
    if (ext && !strchr(ext, '/')) {
	if (IS_RBEXT(ext)) {
	    if (rb_feature_p(feature, ext, TRUE, FALSE, loading)) return TRUE;
	    return FALSE;
	}
	else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
	    if (rb_feature_p(feature, ext, FALSE, FALSE, loading)) return TRUE;
	    return FALSE;
	}
    }
    if (rb_feature_p(feature, 0, TRUE, FALSE, loading))
	return TRUE;
    return FALSE;
}
Beispiel #3
0
static VALUE
expand_include_path(VALUE path)
{
    char *p = RSTRING_PTR(path);
    if (!p)
	return path;
    if (*p == '.' && p[1] == '/')
	return path;
    return rb_file_expand_path(path, Qnil);
}
Beispiel #4
0
VALUE
rb_get_load_path(void)
{
    VALUE load_path = rb_vm_load_path();
    VALUE ary = rb_ary_new();
    for (long i = 0, count = RARRAY_LEN(load_path); i < count; i++) {
	rb_ary_push(ary, rb_file_expand_path(RARRAY_AT(load_path, i), Qnil));
    }
    return ary;
}
Beispiel #5
0
VALUE
rb_get_expanded_load_path(void)
{
    VALUE load_path = rb_get_load_path();
    VALUE ary;
    long i;

    ary = rb_ary_new2(RARRAY_LEN(load_path));
    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
	VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);
	rb_str_freeze(path);
	rb_ary_push(ary, path);
    }
    rb_obj_freeze(ary);
    return ary;
}
/**
 *  line_trace_callback
 *  Callback function for thread line event tracing. It checks Tracer#breakpoints_cache
 *  for any breakpoints trigger on current line called. Then trigger evaluation
 *  procedure if found matching breakpoints. It also skip breakpoints that are
 *  already marked completed.
 */
static void
line_trace_callback(rb_event_flag_t event, VALUE data, VALUE obj, ID mid, VALUE klass)
{
    VALUE self = data;
    VALUE trace_path;
    int c_trace_lineno;
    const char *c_trace_path;
    VALUE trace_binding;
    VALUE call_stack_bindings;
    ID callers_id;
    ID breakpoints_hit_id;
    VALUE matching_result;

    c_trace_path = rb_sourcefile();
    // Ensure C_trace_path is absolute path
    trace_path = rb_str_new_cstr(c_trace_path);
    trace_path = rb_file_expand_path(trace_path, Qnil);

    if(!RTEST(trace_path)) {
        return;
    }

    c_trace_path = rb_string_value_cstr(&trace_path);

    c_trace_lineno = rb_sourceline();
    matching_result = match_breakpoints(self, c_trace_path, c_trace_lineno);

    CONST_ID(callers_id, "callers");
    CONST_ID(breakpoints_hit_id, "breakpoints_hit");

    // If matching result isn't an array, it means we're in completely wrong file,
    // or not on the right line. Turn line tracing off if we're in wrong file.
    if (!RB_TYPE_P(matching_result, T_ARRAY)) {
        if (!RTEST(matching_result)) {
            disable_line_trace_for_thread(Qnil);
        }
        return;
    }

    trace_binding = rb_binding_new();
    call_stack_bindings = rb_funcall(trace_binding, callers_id, 0);

    rb_funcall(self, breakpoints_hit_id, 2, matching_result, call_stack_bindings);

    return;
}
Beispiel #7
0
int
rb_feature_provided(const char *feature, const char **loading)
{
    const char *ext = strrchr(feature, '.');
    volatile VALUE fullpath = 0;

    if (*feature == '.' &&
	(feature[1] == '/' || strncmp(feature+1, "./", 2) == 0)) {
	fullpath = rb_file_expand_path(rb_str_new2(feature), Qnil);
	feature = RSTRING_PTR(fullpath);
    }
    if (ext && !strchr(ext, '/')) {
	int type = guess_ext_type(ext);
	if (type) {
	    if (rb_feature_p(feature, ext, type, false, loading)) return true;
	    return false;
	}
    }
    if (rb_feature_p(feature, 0, TYPE_GUESS, false, loading))
	return true;
    return false;
}
Beispiel #8
0
static bool
search_required(VALUE name, VALUE *out, int *type)
{
    const char *name_cstr = RSTRING_PTR(name);
    if (*name_cstr == '/' || *name_cstr == '.' || *name_cstr == '~') {
	// Given name is an absolute path.
	name = rb_file_expand_path(name, Qnil);
	return check_path(RSTRING_PTR(name), out, type);	
    }

    // Given name is not an absolute path, we need to go through $:.
    VALUE load_path = rb_get_load_path();
    for (long i = 0, count = RARRAY_LEN(load_path); i < count; i++) {
	const char *path = RSTRING_PTR(RARRAY_AT(load_path, i));
	char buf[PATH_MAX];
	snprintf(buf, sizeof buf, "%s/%s", path, name_cstr);
	if (check_path(buf, out, type)) {
	    return true;
	}
    }

    return false;
}
Beispiel #9
0
Datei: load.c Projekt: 217/ruby
VALUE
rb_get_expanded_load_path(void)
{
    VALUE load_path = rb_get_load_path();
    VALUE ary;
    long i;

    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
	VALUE str = rb_check_string_type(RARRAY_PTR(load_path)[i]);
	if (NIL_P(str) || !rb_is_absolute_path(RSTRING_PTR(str)))
	    goto relative_path_found;
    }
    return load_path;

  relative_path_found:
    ary = rb_ary_new2(RARRAY_LEN(load_path));
    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
	VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);
	rb_str_freeze(path);
	rb_ary_push(ary, path);
    }
    rb_obj_freeze(ary);
    return ary;
}