static VALUE exc_equal(VALUE exc, VALUE obj) { VALUE mesg, backtrace; if (exc == obj) return Qtrue; if (rb_obj_class(exc) != rb_obj_class(obj)) { int status = 0; obj = rb_protect(try_convert_to_exception, obj, &status); if (status || obj == Qundef) { rb_set_errinfo(Qnil); return Qfalse; } if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse; mesg = rb_check_funcall(obj, id_message, 0, 0); if (mesg == Qundef) return Qfalse; backtrace = rb_check_funcall(obj, id_backtrace, 0, 0); if (backtrace == Qundef) return Qfalse; } else { mesg = rb_attr_get(obj, id_mesg); backtrace = exc_backtrace(obj); } if (!rb_equal(rb_attr_get(exc, id_mesg), mesg)) return Qfalse; if (!rb_equal(exc_backtrace(exc), backtrace)) return Qfalse; return Qtrue; }
static VALUE exc_equal(VALUE exc, VALUE obj) { VALUE mesg, backtrace; ID id_mesg; if (exc == obj) return Qtrue; CONST_ID(id_mesg, "mesg"); if (rb_obj_class(exc) != rb_obj_class(obj)) { ID id_message, id_backtrace; CONST_ID(id_message, "message"); CONST_ID(id_backtrace, "backtrace"); mesg = rb_check_funcall(obj, id_message, 0, 0); if (mesg == Qundef) return Qfalse; backtrace = rb_check_funcall(obj, id_backtrace, 0, 0); if (backtrace == Qundef) return Qfalse; } else { mesg = rb_attr_get(obj, id_mesg); backtrace = exc_backtrace(obj); } if (!rb_equal(rb_attr_get(exc, id_mesg), mesg)) return Qfalse; if (!rb_equal(exc_backtrace(exc), backtrace)) return Qfalse; return Qtrue; }
static int sr_eof_callback(void *user) { VALUE callback_obj = *(VALUE *)user; VALUE result = rb_check_funcall(callback_obj, s_eof_qm_funcid, 0, NULL); if (result == Qundef && (result = rb_check_funcall(callback_obj, s_eof_qm_funcid, 0, NULL)) == Qundef) { rb_warn("IO object did not respond to eof or eof?, assuming not at EOF"); result = Qfalse; } return RTEST(result); }
static void sr_skip_callback(void *user, unsigned size) { VALUE callback_obj = *(VALUE *)user; VALUE sr_size = UINT2NUM(size); /* If skip doesn't exist, call read and discard the result */ if (rb_check_funcall(callback_obj, s_skip_funcid, 1, &sr_size) != Qundef || rb_check_funcall(callback_obj, s_read_funcid, 1, &sr_size) != Qundef) { return; } rb_warn("IO object did not respond to either skip or read"); }
static VALUE fenix_coerce_to_path(VALUE obj) { VALUE tmp; ID to_path; rb_encoding *enc; int level = rb_safe_level(); if (insecure_obj_p(obj, level)) { rb_insecure_operation(); } CONST_ID(to_path, "to_path"); tmp = rb_check_funcall(obj, to_path, 0, 0); if (tmp == Qundef) tmp = obj; StringValue(tmp); tmp = file_path_convert(tmp); if (obj != tmp && insecure_obj_p(tmp, level)) { rb_insecure_operation(); } enc = rb_enc_get(tmp); if (!rb_enc_asciicompat(enc)) { tmp = rb_str_inspect(tmp); rb_raise(rb_eEncCompatError, "path name must be ASCII-compatible (%s): %s", rb_enc_name(enc), RSTRING_PTR(tmp)); } return rb_str_new4(tmp); }
static VALUE try_convert_to_exception(VALUE obj) { ID id_exception; CONST_ID(id_exception, "exception"); return rb_check_funcall(obj, id_exception, 0, 0); }
static VALUE enumerator_rewind(VALUE obj) { struct enumerator *e = enumerator_ptr(obj); rb_check_funcall(e->obj, id_rewind, 0, 0); e->fib = 0; e->dst = Qnil; e->lookahead = Qundef; e->feedvalue = Qundef; e->stop_exc = Qfalse; return obj; }
static void set_backtrace(VALUE info, VALUE bt) { ID set_backtrace = rb_intern("set_backtrace"); if (rb_backtrace_p(bt)) { if (rb_method_basic_definition_p(CLASS_OF(info), set_backtrace)) { rb_exc_set_backtrace(info, bt); return; } else { bt = rb_backtrace_to_str_ary(bt); } } rb_check_funcall(info, set_backtrace, 1, &bt); }
void rb_threadptr_error_print(rb_thread_t *volatile th, volatile VALUE errinfo) { volatile VALUE errat = Qundef; volatile int raised_flag = th->raised_flag; volatile VALUE eclass = Qundef, emesg = Qundef; if (NIL_P(errinfo)) return; rb_thread_raised_clear(th); TH_PUSH_TAG(th); if (TH_EXEC_TAG() == 0) { errat = rb_get_backtrace(errinfo); } else if (errat == Qundef) { errat = Qnil; } else if (eclass == Qundef || emesg != Qundef) { goto error; } if ((eclass = CLASS_OF(errinfo)) != Qundef) { VALUE e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0); if (e != Qundef) { if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e); emesg = e; } } if (rb_stderr_tty_p()) { if (0) warn_print("Traceback (most recent call last):\n"); print_backtrace(eclass, errat, TRUE); print_errinfo(eclass, errat, emesg); } else { print_errinfo(eclass, errat, emesg); print_backtrace(eclass, errat, FALSE); } error: TH_POP_TAG(); th->errinfo = errinfo; rb_thread_raised_set(th, raised_flag); }
/* * Create a Pathname object from the given String (or String-like object). * If +path+ contains a NULL character (<tt>\0</tt>), an ArgumentError is raised. */ static VALUE path_initialize(VALUE self, VALUE arg) { VALUE str; if (RB_TYPE_P(arg, T_STRING)) { str = arg; } else { str = rb_check_funcall(arg, id_to_path, 0, NULL); if (str == Qundef) str = arg; StringValue(str); } if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) rb_raise(rb_eArgError, "pathname contains null byte"); str = rb_obj_dup(str); set_strpath(self, str); OBJ_INFECT(self, str); return self; }
static int sr_read_callback(void *user, char *data, int size) { VALUE callback_obj = *(VALUE *)user; VALUE sr_size = INT2NUM(size); VALUE sr_data = rb_check_funcall(callback_obj, s_read_funcid, 1, &sr_size); if (sr_data != Qundef && RTEST(sr_data)) { const char *string_data = StringValuePtr(sr_data); int string_length = RSTRING_LENINT(sr_data); memcpy(data, string_data, string_length); return string_length; } rb_warn("IO object did not respond to read, returning 0 bytes read"); /* stb_image should fail on its own if it doesn't get the data it wants here, so just return 0 */ return 0; }
void rb_threadptr_error_print(rb_thread_t *th, VALUE errinfo) { volatile VALUE errat = Qundef; int raised_flag = th->raised_flag; volatile VALUE eclass = Qundef, e = Qundef; const char *volatile einfo; volatile long elen; VALUE mesg; if (NIL_P(errinfo)) return; rb_thread_raised_clear(th); TH_PUSH_TAG(th); if (TH_EXEC_TAG() == 0) { errat = rb_get_backtrace(errinfo); } else if (errat == Qundef) { errat = Qnil; } else if (eclass == Qundef || e != Qundef) { goto error; } else { goto no_message; } if (NIL_P(errat) || RARRAY_LEN(errat) == 0 || NIL_P(mesg = RARRAY_AREF(errat, 0))) { error_pos(); } else { warn_print_str(mesg); warn_print(": "); } eclass = CLASS_OF(errinfo); if (eclass != Qundef && (e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0)) != Qundef && (RB_TYPE_P(e, T_STRING) || !NIL_P(e = rb_check_string_type(e)))) { einfo = RSTRING_PTR(e); elen = RSTRING_LEN(e); } else { no_message: einfo = ""; elen = 0; } if (eclass == rb_eRuntimeError && elen == 0) { warn_print("unhandled exception\n"); } else { VALUE epath; epath = rb_class_name(eclass); if (elen == 0) { warn_print_str(epath); warn_print("\n"); } else { const char *tail = 0; long len = elen; if (RSTRING_PTR(epath)[0] == '#') epath = 0; if ((tail = memchr(einfo, '\n', elen)) != 0) { len = tail - einfo; tail++; /* skip newline */ } warn_print_str(tail ? rb_str_subseq(e, 0, len) : e); if (epath) { warn_print(" ("); warn_print_str(epath); warn_print(")\n"); } if (tail) { warn_print_str(rb_str_subseq(e, tail - einfo, elen - len - 1)); } if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1); } } if (!NIL_P(errat)) { long i; long len = RARRAY_LEN(errat); int skip = eclass == rb_eSysStackError; #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) #define TRACE_HEAD 8 #define TRACE_TAIL 5 for (i = 1; i < len; i++) { VALUE line = RARRAY_AREF(errat, i); if (RB_TYPE_P(line, T_STRING)) { warn_print_str(rb_sprintf("\tfrom %"PRIsVALUE"\n", line)); } if (skip && i == TRACE_HEAD && len > TRACE_MAX) { warn_print_str(rb_sprintf("\t ... %ld levels...\n", len - TRACE_HEAD - TRACE_TAIL)); i = len - TRACE_TAIL; } } } error: TH_POP_TAG(); th->errinfo = errinfo; rb_thread_raised_set(th, raised_flag); }
static VALUE try_convert_to_exception(VALUE obj) { return rb_check_funcall(obj, idException, 0, 0); }
/* Lazy Enumerator methods */ static VALUE enum_size(VALUE self) { VALUE r = rb_check_funcall(self, id_size, 0, 0); return (r == Qundef) ? Qnil : r; }
static VALUE invcmp_recursive(VALUE x, VALUE y, int recursive) { if (recursive) return Qnil; return rb_check_funcall(y, cmp, 1, &x); }
static int is_integer_p(VALUE v) { VALUE is_int = rb_check_funcall(v, id_integer_p, 0, 0); return RTEST(is_int) && is_int != Qundef; }