static VALUE inspect_enumerator(VALUE obj, VALUE dummy, int recur) { struct enumerator *e; VALUE eobj, str, cname; TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, e); cname = rb_obj_class(obj); if (!e || e->obj == Qundef) { return rb_sprintf("#<%"PRIsVALUE": uninitialized>", rb_class_path(cname)); } if (recur) { str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname)); OBJ_TAINT(str); return str; } eobj = rb_attr_get(obj, id_receiver); if (NIL_P(eobj)) { eobj = e->obj; } /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */ str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE, rb_class_path(cname), eobj); append_method(obj, str, e->meth, e->args); rb_str_buf_cat2(str, ">"); return str; }
static VALUE lp_inspect(VALUE self) { VALUE str, cname = rb_obj_class(self); struct wrapped_object * ptr = lp_ptr(self); if (lp_is_unresolved_blk(ptr)) str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE" (unresolved)>", rb_class_path(cname), ptr->blk); else str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE">", rb_class_path(cname), ptr->obj); return str; }
static void remove_method(VALUE klass, ID mid) { st_data_t key, data; rb_method_entry_t *me = 0; VALUE self = klass; klass = RCLASS_ORIGIN(klass); rb_frozen_class_p(klass); if (mid == object_id || mid == id__send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problems", rb_id2name(mid)); } if (!st_lookup(RCLASS_M_TBL(klass), mid, &data) || !(me = (rb_method_entry_t *)data) || (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF) || UNDEFINED_REFINED_METHOD_P(me->def)) { rb_name_error(mid, "method `%"PRIsVALUE"' not defined in %"PRIsVALUE, rb_id2str(mid), rb_class_path(klass)); } key = (st_data_t)mid; st_delete(RCLASS_M_TBL(klass), &key, &data); rb_vm_check_redefinition_opt_method(me, klass); rb_clear_method_cache_by_class(klass); rb_unlink_method_entry(me); if (me->def->type == VM_METHOD_TYPE_REFINED) { rb_add_refined_method_entry(klass, mid); } CALL_METHOD_HOOK(self, removed, mid); }
static VALUE class2path(VALUE klass) { VALUE path; if (klass == rb_cNSObject) { path = rb_str_new2("Object"); } else if (klass == rb_cNSMutableString) { path = rb_str_new2("String"); } else { path = rb_class_path(klass); } const char *n = RSTRING_PTR(path); if (n[0] == '#') { rb_raise(rb_eTypeError, "can't dump anonymous %s %s", (TYPE(klass) == T_CLASS ? "class" : "module"), n); } if (rb_path2class(n) != rb_class_real(klass, true)) { rb_raise(rb_eTypeError, "%s can't be referred", n); } return path; }
static void showExc(VALUE exc) { VALUE bt = rb_funcall2(exc, rb_intern("backtrace"), 0, NULL); VALUE bt0 = rb_ary_entry(bt, 0); VALUE name = rb_class_path(rb_obj_class(exc)); VALUE ds = rb_sprintf("%" PRIsVALUE ": %" PRIsVALUE " (%" PRIsVALUE ")", bt0, exc, name); /* omit "useless" last entry (from ruby:1:in `eval') */ for (long i = 1, btlen = RARRAY_LEN(bt) - 1; i < btlen; ++i) rb_str_catf(ds, "\n\tfrom %" PRIsVALUE, rb_ary_entry(bt, i)); Debug() << StringValueCStr(ds); ID id_index = rb_intern("index"); /* an "offset" argument is not needed for the first time */ VALUE argv[2] = { rb_str_new_cstr(":") }; long filelen = NUM2LONG(rb_funcall2(bt0, id_index, 1, argv)); argv[1] = LONG2NUM(filelen + 1); VALUE tmp = rb_funcall2(bt0, id_index, ARRAY_SIZE(argv), argv); long linelen = NUM2LONG(tmp) - filelen - 1; VALUE file = rb_str_subseq(bt0, 0, filelen); VALUE line = rb_str_subseq(bt0, filelen + 1, linelen); VALUE ms = rb_sprintf("Script '%" PRIsVALUE "' line %" PRIsVALUE ": %" PRIsVALUE " occured.\n\n%" PRIsVALUE, file, line, name, exc); showMsg(StringValueCStr(ms)); }
// 尝试执行脚本 VALUE ThisApp::TryEval(const char* str){ static char buffer[1024]; VALUE rc = Qnil; VALUE err; __try{ rc = rb_eval_string(str); } __except (EXCEPTION_EXECUTE_HANDLER){} if (!NIL_P(err = rb_errinfo())){ // class VALUE kclass = rb_class_path(CLASS_OF(err)); // message VALUE message = rb_obj_as_string(err); // backtrace VALUE ary = rb_funcall(err, rb_intern("backtrace"), 0); VALUE brstr = rb_funcall(ary, rb_intern("to_s"), 0); // sprintf sprintf_s(buffer, "Error: %s\n%s\nbacktrace: %s\n", StringValuePtr(kclass), StringValuePtr(message), StringValuePtr(brstr)); MessageBoxA(nullptr, buffer, "Error", MB_OK); rb_set_errinfo(Qnil); } return rc; }
static void iroffer_ruby_errro(int error) { VALUE lasterr; VALUE inclass; VALUE message; VALUE ary; long c; if (error == 0) return; lasterr = rb_gv_get("$!"); /* NOTRANSLATE */ inclass = rb_class_path(CLASS_OF(lasterr)); message = rb_obj_as_string(lasterr); outerror(OUTERROR_TYPE_WARN_LOUD, "error ruby_script: class=%s, message=%s", RSTRING_PTR(inclass), RSTRING_PTR(message)); if (!NIL_P(rb_errinfo())) { ary = rb_funcall(rb_errinfo(), rb_intern("backtrace"), 0); for (c=0; c<RARRAY_LEN(ary); ++c) { outerror(OUTERROR_TYPE_WARN_LOUD, "backtrace from %s", RSTRING_PTR(RARRAY_PTR(ary)[c])); } } }
static void showExc(VALUE exc, const BacktraceData &btData) { VALUE bt = rb_funcall2(exc, rb_intern("backtrace"), 0, NULL); VALUE msg = rb_funcall2(exc, rb_intern("message"), 0, NULL); VALUE bt0 = rb_ary_entry(bt, 0); VALUE name = rb_class_path(rb_obj_class(exc)); VALUE ds = rb_sprintf("%" PRIsVALUE ": %" PRIsVALUE " (%" PRIsVALUE ")", bt0, exc, name); /* omit "useless" last entry (from ruby:1:in `eval') */ for (long i = 1, btlen = RARRAY_LEN(bt) - 1; i < btlen; ++i) rb_str_catf(ds, "\n\tfrom %" PRIsVALUE, rb_ary_entry(bt, i)); Debug() << StringValueCStr(ds); char *s = RSTRING_PTR(bt0); char line[16]; std::string file(512, '\0'); char *p = s + strlen(s); char *e; while (p != s) if (*--p == ':') break; e = p; while (p != s) if (*--p == ':') break; /* s p e * SectionXXX:YY: in 'blabla' */ *e = '\0'; strncpy(line, *p ? p+1 : p, sizeof(line)); line[sizeof(line)-1] = '\0'; *e = ':'; e = p; /* s e * SectionXXX:YY: in 'blabla' */ *e = '\0'; strncpy(&file[0], s, file.size()); *e = ':'; /* Shrink to fit */ file.resize(strlen(file.c_str())); file = btData.scriptNames.value(file, file); std::string ms(640, '\0'); snprintf(&ms[0], ms.size(), "Script '%s' line %s: %s occured.\n\n%s", file.c_str(), line, RSTRING_PTR(name), RSTRING_PTR(msg)); showMsg(ms); }
static void set_value(ValueStruct *value, VALUE obj) { VALUE class_path, str; if (NIL_P(obj)) { ValueIsNil(value); } else { ValueIsNonNil(value); switch (TYPE(obj)) { case T_TRUE: case T_FALSE: SetValueBool(value, RTEST(obj) ? TRUE : FALSE); break; case T_FIXNUM: SetValueInteger(value, FIX2INT(obj)); break; case T_BIGNUM: SetValueInteger(value, NUM2INT(obj)); break; case T_FLOAT: SetValueFloat(value, RFLOAT(obj)->value); break; case T_STRING: switch (ValueType(value)) { case GL_TYPE_BYTE: case GL_TYPE_BINARY: SetValueBinary(value, RSTRING(obj)->ptr, RSTRING(obj)->len); break; default: SetValueStringWithLength(value, RSTRING(obj)->ptr, RSTRING(obj)->len, codeset); break; } break; default: class_path = rb_class_path(CLASS_OF(obj)); if (strcasecmp(StringValuePtr(class_path), "BigDecimal") == 0) { str = rb_funcall(obj, rb_intern("to_s"), 1, rb_str_new2("F")); } else if (strcasecmp(StringValuePtr(class_path), "Time") == 0) { str = rb_funcall(obj, rb_intern("strftime"), 1, rb_str_new2("%Y%m%d%H%M%S")); dbgprintf("strftime [%s]",StringValuePtr(str)); } else { str = rb_funcall(obj, rb_intern("to_s"), 0); } SetValueString(value, StringValuePtr(str), codeset); break; } } }
static VALUE class2path(VALUE klass) { VALUE path = rb_class_path(klass); const char *n; n = must_not_be_anonymous((TYPE(klass) == T_CLASS ? "class" : "module"), path); if (rb_path_to_class(path) != rb_class_real(klass)) { rb_raise(rb_eTypeError, "%s can't be referred to", n); } return path; }
// ---------------------------------------------------------------------------- void RubyClassHandler::ShowRubyError(int error) // ---------------------------------------------------------------------------- { // Fetch the status error for rb_protected calls // Other non-protected calls may throw an exception to the // console/log and terminate the script. eg, wrong parameter count. #if not defined(LOGGING) return; #endif if(error == 0) return; wxString clog = wxEmptyString; wxString endl = _T("\n"); VALUE lasterr = rb_gv_get("$!"); // class VALUE klass = rb_class_path(CLASS_OF(lasterr)); clog << "class = " << RSTRING(klass)->ptr << endl; // message VALUE message = rb_obj_as_string(lasterr); clog << "message = " << RSTRING(message)->ptr << endl; // backtrace if(!NIL_P(ruby_errinfo)) { //-std::ostringstream o; wxString o = ""; VALUE ary = rb_funcall( ruby_errinfo, rb_intern("backtrace"), 0); int c; for (c=0; c<RARRAY(ary)->len; c++) { o << "\tfrom " << clog << "\tfrom " << RSTRING(RARRAY(ary)->ptr[c])->ptr << "\n"; } //-clog << "backtrace = " << o.str() << endl; clog << "backtrace = " << o << endl; } //-throw runtime_error("ruby_error"); #if defined(LOGGING) LOGIT( _T("Ruby Error:[%s]"), clog.c_str()); #endif ID method = rb_intern("puts"); if (MethodExists(rb_mKernel, _T("puts"))) rb_funcall(rb_mKernel, method, 1, rb_str_new2(clog.c_str() )); }
/* * call-seq: * module.dump(limit) => String * * Dump a module to a string. The module will be dumped along with its * instance methods, class variables, names of included modules, name of * superclass, its entire metaclass, and the name of the class. * * Note that on ruby 1.8 and newer the module is temporarily modified * while dumping in order to allow singleton classes to be dumped. To * prevent access to the modifed module, Thread.critical is temporarily * set, then restored to its original value once dumping is complete. * Note also that because YARV does not support Thread.critical, the * user must synchronize access to the class with a Mutex in order to * prevent accessing the modified class. */ static VALUE module_dump(VALUE self, VALUE limit) { VALUE flags, instance_methods, class_variables; VALUE included_modules, superclass, metaclass, arr, str, class_name; limit = INT2NUM(NUM2INT(limit) - 1); if(rb_safe_level() >= 4) { /* no access to potentially sensitive data from the sandbox */ rb_raise(rb_eSecurityError, "Insecure: can't dump module"); } flags = INT2NUM(RBASIC(self)->flags); instance_methods = instance_method_hash(self); class_variables = class_variable_hash(self); included_modules = included_modules_list(self); superclass = superclass_name(self); arr = rb_ary_new(); if(FL_TEST(self, FL_SINGLETON)) { metaclass = Qnil; class_name = Qnil; } else { metaclass = rb_singleton_class(self); class_name = rb_class_path(self); } rb_ary_push(arr, flags); rb_ary_push(arr, marshal_dump(instance_methods, limit)); rb_ary_push(arr, marshal_dump(class_variables, limit)); rb_ary_push(arr, included_modules); rb_ary_push(arr, superclass); rb_ary_push(arr, marshal_dump(metaclass, limit)); rb_ary_push(arr, class_name); str = marshal_dump(arr, limit); #if RUBY_VERSION_CODE > 180 { VALUE class_restorer = create_class_restorer(self); rb_iv_set(str, "__class_restorer__", class_restorer); set_class_restore_state(self); } #endif return str; }
// Convert a ruby exception into C++. void Exception::backtrace() throw() { _backtrace.clear(); /* const char* file = ruby_sourcefile; if(file == NULL) { file = "(Ruby VM)"; } msg << "File : " << file << "\n"; */ // Get the glocal exception object VALUE exception_instance = rb_gv_get("$!"); // Get the exception instance class VALUE klass = rb_class_path(CLASS_OF(exception_instance)); _backtrace += "Type : " + (std::string)RSTRING_PTR(klass) + (std::string)"\n"; // Store it for later reference _type = (std::string)RSTRING_PTR(klass); //> Now generate the error message // Store exception class name _backtrace += RSTRING_PTR(klass); // Message: call $!.to_s() to get string representation VALUE message = rb_obj_as_string(exception_instance); _backtrace += "Message : " + (std::string)RSTRING_PTR(message) + (std::string)"\n"; // Backtrace: p (*(RArray*)ary).as.ary if(!NIL_P(exception_instance)) { VALUE ary = rb_funcall(exception_instance, rb_intern("backtrace"), 0); int c; for (c=0; c<RARRAY_LEN(ary); c++) { // gdb: p *((RString*)(*(RArray*)ary).as.ary[0]) _backtrace += (std::string)"From : " + (std::string)RSTRING_PTR(RARRAY_PTR(ary)[c]) + (std::string)"\n"; } } }
void rb_set_class_path2(VALUE klass, VALUE under, const char *name, VALUE outer) { VALUE str; if (under == rb_cObject) { str = rb_str_new2(name); } else { str = rb_str_dup(rb_class_path(under)); rb_str_cat2(str, "::"); rb_str_cat2(str, name); } OBJ_FREEZE(str); rb_ivar_set(klass, id_classpath, str); }
static VALUE class2path(VALUE klass) { VALUE path = rb_class_path(klass); const char *n = RSTRING_PTR(path); if (n[0] == '#') { rb_raise(rb_eTypeError, "can't dump anonymous %s %s", (TYPE(klass) == T_CLASS ? "class" : "module"), n); } if (rb_path2class(n) != rb_class_real(klass)) { rb_raise(rb_eTypeError, "%s can't be referred", n); } return path; }
void rb_set_class_path_string(VALUE klass, VALUE under, VALUE name) { VALUE str; if (under == rb_cObject) { str = rb_str_new_frozen(name); } else { str = rb_str_dup(rb_class_path(under)); rb_str_cat2(str, "::"); rb_str_append(str, name); OBJ_FREEZE(str); } rb_ivar_set(klass, classpath, str); }
static VALUE ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) { EVP_CIPHER_CTX *ctx; unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; VALUE pass, init_v; if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ /* * oops. this code mistakes salt for IV. * We deprecated the arguments for this method, but we decided * keeping this behaviour for backward compatibility. */ VALUE cname = rb_class_path(rb_obj_class(self)); rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; " "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV", cname, cname, cname); StringValue(pass); GetCipher(self, ctx); if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); else{ StringValue(init_v); if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) { memset(iv, 0, EVP_MAX_IV_LENGTH); memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v)); } else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv)); } EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL); p_key = key; p_iv = iv; } else { GetCipher(self, ctx); } if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { ossl_raise(eCipherError, NULL); } return self; }
VALUE rb_profile_frame_classpath(VALUE frame) { VALUE klass = rb_iseq_klass(frame2iseq(frame)); if (klass && !NIL_P(klass)) { if (RB_TYPE_P(klass, T_ICLASS)) { klass = RBASIC(klass)->klass; } else if (FL_TEST(klass, FL_SINGLETON)) { klass = rb_ivar_get(klass, id__attached__); if (!RB_TYPE_P(klass, T_CLASS)) return rb_sprintf("#<%s:%p>", rb_class2name(rb_obj_class(klass)), (void*)klass); } return rb_class_path(klass); } else { return Qnil; } }
static void ruby_script_error() { VALUE errinfo, lasterr, array; int i; errinfo = rb_errinfo(); if(!NIL_P(errinfo)) { lasterr = rb_gv_get("$!"); VALUE tmp2 = rb_class_path(CLASS_OF(lasterr)); VALUE tmp = rb_obj_as_string(lasterr); ilog(L_ERROR, "RUBY ERROR: %s: %s", StringValueCStr(tmp2), StringValueCStr(tmp)); array = rb_funcall(errinfo, rb_intern("backtrace"), 0); for (i = 0; i < RARRAY_LEN(array); ++i) { tmp = rb_ary_entry(array, i); ilog(L_DEBUG, "RUBY BACKTRACE: %s", StringValueCStr(tmp)); } } }
/** * Print the Ruby Stack Trace in an ows:ExceptionReport XML Document * * @param m the conf maps containing the main.cfg settings * @see printExceptionReportResponse */ void ruby_trace_error(maps* m){ #if RUBY_VERSION_MINOR == 8 VALUE lasterr = rb_gv_get("$!"); #else VALUE lasterr = rb_errinfo(); VALUE ruby_errinfo = lasterr; #endif VALUE message = rb_obj_as_string(lasterr); VALUE lklass = rb_class_path(CLASS_OF(lasterr)); #if RUBY_VERSION_MINOR == 8 char *trace=(char*)malloc((strlen(RSTRING(lklass)->ptr)+strlen(RSTRING(message)->ptr)+3)*sizeof(char)); sprintf(trace,"%s: %s",RSTRING_PTR(lklass),RSTRING_PTR(message)); #else char *trace=(char*)malloc((strlen(RSTRING_PTR(lklass))+strlen(RSTRING_PTR(message))+3)*sizeof(char)); sprintf(trace,"%s: %s",RSTRING_PTR(lklass),RSTRING_PTR(message)); #endif if(!NIL_P(ruby_errinfo)) { VALUE ary = rb_funcall(ruby_errinfo, rb_intern("backtrace"), 0); int c; for (c=0; c<RARRAY_LEN(ary); c++) { int len=strlen(trace); char *tmp0=zStrdup(trace); #if RUBY_VERSION_MINOR == 8 trace=(char *) realloc(trace,(len+strlen(RSTRING(RARRAY(ary)->ptr[c])->ptr)+2)*sizeof(char)); sprintf(trace,"%s\n%s",tmp0,RSTRING(RARRAY(ary)->ptr[c])->ptr); #else trace=(char *) realloc(trace,(len+strlen(RSTRING_PTR(RARRAY_PTR(ary)[c]))+2)*sizeof(char)); sprintf(trace,"%s\n%s",tmp0,RSTRING_PTR(RARRAY_PTR(ary)[c])); #endif free(tmp0); } } map* err=createMap("text",trace); addToMap(err,"code","NoApplicableCode"); printExceptionReportResponse(m,err); }
static void exception_print(FILE *out, int cgi) { VALUE errat; VALUE eclass; VALUE einfo; if (NIL_P(ruby_errinfo)) return; errat = rb_funcall(ruby_errinfo, rb_intern("backtrace"), 0); if (!NIL_P(errat)) { VALUE mesg = RARRAY_PTR(errat)[0]; if (NIL_P(mesg)) { error_pos(out, cgi); } else { if (cgi) write_escaping_html(out, RSTRING_PTR(mesg), RSTRING_LEN(mesg)); else fwrite(RSTRING_PTR(mesg), 1, RSTRING_LEN(mesg), out); } } eclass = CLASS_OF(ruby_errinfo); einfo = rb_obj_as_string(ruby_errinfo); if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) { fprintf(out, ": unhandled exception\n"); } else { VALUE epath; epath = rb_class_path(eclass); if (RSTRING_LEN(einfo) == 0) { fprintf(out, ": "); if (cgi) write_escaping_html(out, RSTRING_PTR(epath), RSTRING_LEN(epath)); else fwrite(RSTRING_PTR(epath), 1, RSTRING_LEN(epath), out); if (cgi) fprintf(out, "<br>\n"); else fprintf(out, "\n"); } else { char *tail = 0; int len = RSTRING_LEN(einfo); if (RSTRING_PTR(epath)[0] == '#') epath = 0; if ((tail = strchr(RSTRING_PTR(einfo), '\n')) != NULL) { len = tail - RSTRING_PTR(einfo); tail++; /* skip newline */ } fprintf(out, ": "); if (cgi) write_escaping_html(out, RSTRING_PTR(einfo), len); else fwrite(RSTRING_PTR(einfo), 1, len, out); if (epath) { fprintf(out, " ("); if (cgi) write_escaping_html(out, RSTRING_PTR(epath), RSTRING_LEN(epath)); else fwrite(RSTRING_PTR(epath), 1, RSTRING_LEN(epath), out); if (cgi) fprintf(out, ")<br>\n"); else fprintf(out, ")\n"); } if (tail) { if (cgi) write_escaping_html(out, tail, RSTRING_LEN(einfo) - len - 1); else fwrite(tail, 1, RSTRING_LEN(einfo) - len - 1, out); if (cgi) fprintf(out, "<br>\n"); else fprintf(out, "\n"); } } } if (!NIL_P(errat)) { int i; struct RArray *ep = RARRAY(errat); #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) #define TRACE_HEAD 8 #define TRACE_TAIL 5 rb_ary_pop(errat); ep = RARRAY(errat); for (i=1; i<RARRAY_LEN(ep); i++) { if (TYPE(RARRAY_PTR(ep)[i]) == T_STRING) { if (cgi) { fprintf(out, "<div class=\"backtrace\">from "); write_escaping_html(out, RSTRING_PTR(RARRAY_PTR(ep)[i]), RSTRING_LEN(RARRAY_PTR(ep)[i])); } else { fprintf(out, " from "); fwrite(RSTRING_PTR(RARRAY_PTR(ep)[i]), 1, RSTRING_LEN(RARRAY_PTR(ep)[i]), out); } if (cgi) fprintf(out, "<br></div>\n"); else fprintf(out, "\n"); } if (i == TRACE_HEAD && RARRAY_LEN(ep) > TRACE_MAX) { char buff[BUFSIZ]; if (cgi) snprintf(buff, BUFSIZ, "<div class=\"backtrace\">... %ld levels...\n", RARRAY_LEN(ep) - TRACE_HEAD - TRACE_TAIL); else snprintf(buff, BUFSIZ, " ... %ld levels...<br></div>\n", RARRAY_LEN(ep) - TRACE_HEAD - TRACE_TAIL); if (cgi) write_escaping_html(out, buff, strlen(buff)); else fputs(buff, out); i = RARRAY_LEN(ep) - TRACE_TAIL; } } } }
static void error_print(int state) { #ifndef DYNAMIC_RUBY #if !(defined(RUBY_VERSION) && RUBY_VERSION >= 19) \ && !(defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19) RUBYEXTERN VALUE ruby_errinfo; #endif #endif VALUE eclass; VALUE einfo; char buff[BUFSIZ]; #define TAG_RETURN 0x1 #define TAG_BREAK 0x2 #define TAG_NEXT 0x3 #define TAG_RETRY 0x4 #define TAG_REDO 0x5 #define TAG_RAISE 0x6 #define TAG_THROW 0x7 #define TAG_FATAL 0x8 #define TAG_MASK 0xf switch (state) { case TAG_RETURN: EMSG(_("E267: unexpected return")); break; case TAG_NEXT: EMSG(_("E268: unexpected next")); break; case TAG_BREAK: EMSG(_("E269: unexpected break")); break; case TAG_REDO: EMSG(_("E270: unexpected redo")); break; case TAG_RETRY: EMSG(_("E271: retry outside of rescue clause")); break; case TAG_RAISE: case TAG_FATAL: #ifdef RUBY19_OR_LATER eclass = CLASS_OF(rb_errinfo()); einfo = rb_obj_as_string(rb_errinfo()); #else eclass = CLASS_OF(ruby_errinfo); einfo = rb_obj_as_string(ruby_errinfo); #endif if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) { EMSG(_("E272: unhandled exception")); } else { VALUE epath; char *p; epath = rb_class_path(eclass); vim_snprintf(buff, BUFSIZ, "%s: %s", RSTRING_PTR(epath), RSTRING_PTR(einfo)); p = strchr(buff, '\n'); if (p) *p = '\0'; EMSG(buff); } break; default: vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state); EMSG(buff); break; } }
/* Another Vim treat. */ void erb_report_error(struct session *ses, int error) { VALUE eclass; VALUE einfo; unsigned char buff[MAX_STR_LEN]; unsigned char *msg; /* XXX: Ew. These are from the Ruby internals. */ #define TAG_RETURN 0x1 #define TAG_BREAK 0x2 #define TAG_NEXT 0x3 #define TAG_RETRY 0x4 #define TAG_REDO 0x5 #define TAG_RAISE 0x6 #define TAG_THROW 0x7 #define TAG_FATAL 0x8 #define TAG_MASK 0xf switch (error) { case TAG_RETURN: msg = "unexpected return"; break; case TAG_NEXT: msg = "unexpected next"; break; case TAG_BREAK: msg = "unexpected break"; break; case TAG_REDO: msg = "unexpected redo"; break; case TAG_RETRY: msg = "retry outside of rescue clause"; break; case TAG_RAISE: case TAG_FATAL: eclass = CLASS_OF(ruby_errinfo); einfo = rb_obj_as_string(ruby_errinfo); if (eclass == rb_eRuntimeError && RSTRING(einfo)->len == 0) { msg = "unhandled exception"; } else { VALUE epath; unsigned char *p; epath = rb_class_path(eclass); snprintf(buff, MAX_STR_LEN, "%s: %s", RSTRING(epath)->ptr, RSTRING(einfo)->ptr); p = strchr(buff, '\n'); if (p) *p = '\0'; msg = buff; } break; default: snprintf(buff, MAX_STR_LEN, "unknown longjmp status %d", error); msg = buff; break; } alert_ruby_error(ses, msg); }
VALUE rb_class_name(VALUE klass) { return rb_class_path(rb_class_real(klass, false)); }
static VALUE class_spec_rb_class_path(VALUE self, VALUE klass) { return rb_class_path(klass); }
int main( int argc, char** argv ) { int state = 0; int rc = 0; int opt_mv = 0; crate_app ca; /** startup items from ruby's original main.c */ #ifdef _WIN32 NtInitialize(&argc, &argv); #endif #if defined(__MACOS__) && defined(__MWERKS__) argc = ccommand(&argv); #endif /* setup ruby */ ruby_init(); ruby_script( argv[0] ); ruby_init_loadpath(); /* strip out the crate specific arguments from argv using --crate- */ opt_mv = crate_init_from_options( &ca, argc, argv ); argc -= opt_mv; argv += opt_mv; /* printf("crate file : %s\n", ca.file_name); */ /* printf("crate class : %s\n", ca.class_name); */ /* printf("crate method: %s\n", ca.method_name); */ /* make ARGV available */ ruby_set_argv( argc, argv ); /* initialize all extensions */ Init_ext(); /* load up the amalgalite libs */ am_bootstrap_lift( cARB, Qnil ); /* remove the current LOAD_PATH */ rb_ary_clear( rb_gv_get( "$LOAD_PATH" ) ); /* invoke the class / method passing in ARGV and ENV */ rb_protect( crate_wrap_app, (VALUE)&ca, &state ); /* check the results */ if ( state ) { /* exception was raised, check the $! var */ VALUE lasterr = rb_gv_get("$!"); /* system exit was called so just propogate that up to our exit */ if ( rb_obj_is_instance_of( lasterr, rb_eSystemExit ) ) { rc = NUM2INT( rb_attr_get( lasterr, rb_intern("status") ) ); /*printf(" Caught SystemExit -> $? will be %d\n", rc ); */ } else { /* some other exception was raised so dump that out */ VALUE klass = rb_class_path( CLASS_OF( lasterr ) ); VALUE message = rb_obj_as_string( lasterr ); VALUE backtrace = rb_funcall( lasterr, rb_intern("backtrace"), 0 ); fprintf( stderr, "%s: %s\n", RSTRING( klass )->ptr, RSTRING( message )->ptr ); rb_iterate( rb_each, backtrace, dump_backtrace, Qnil ); rc = state; } } free( ca.file_name ); free( ca.class_name ); free( ca.method_name ); /* shut down ruby */ ruby_finalize(); /* exit the program */ exit( rc ); }