7 warn_printf(const char *fmt
, ...)
12 va_init_list(args
, fmt
);
13 vsnprintf(buf
, BUFSIZ
, fmt
, args
);
18 #define warn_print(x) rb_write_error(x)
19 #define warn_print2(x,l) rb_write_error2(x,l)
24 const char *sourcefile
= rb_sourcefile();
25 int sourceline
= rb_sourceline();
28 if (sourceline
== 0) {
29 warn_printf("%s", sourcefile
);
31 else if (rb_frame_callee()) {
32 warn_printf("%s:%d:in `%s'", sourcefile
, sourceline
,
33 rb_id2name(rb_frame_callee()));
36 warn_printf("%s:%d", sourcefile
, sourceline
);
41 VALUE
rb_check_backtrace(VALUE
);
44 get_backtrace(VALUE info
)
48 info
= rb_funcall(info
, rb_intern("backtrace"), 0);
51 return rb_check_backtrace(info
);
55 rb_get_backtrace(VALUE info
)
57 return get_backtrace(info
);
61 set_backtrace(VALUE info
, VALUE bt
)
63 rb_funcall(info
, rb_intern("set_backtrace"), 1, bt
);
69 VALUE errat
= Qnil
; /* OK */
70 VALUE errinfo
= GET_THREAD()->errinfo
;
71 volatile VALUE eclass
, e
;
79 if (EXEC_TAG() == 0) {
80 errat
= get_backtrace(errinfo
);
88 const char *file
= rb_sourcefile();
89 int line
= rb_sourceline();
91 warn_printf("%s:%d", file
, line
);
93 warn_printf("%d", line
);
95 else if (RARRAY_LEN(errat
) == 0) {
99 VALUE mesg
= RARRAY_PTR(errat
)[0];
104 warn_print2(RSTRING_PTR(mesg
), RSTRING_LEN(mesg
));
108 eclass
= CLASS_OF(errinfo
);
109 if (EXEC_TAG() == 0) {
110 e
= rb_funcall(errinfo
, rb_intern("message"), 0, 0);
112 einfo
= RSTRING_PTR(e
);
113 elen
= RSTRING_LEN(e
);
121 if (eclass
== rb_eRuntimeError
&& elen
== 0) {
122 warn_print(": unhandled exception\n");
127 epath
= rb_class_name(eclass
);
130 warn_print2(RSTRING_PTR(epath
), RSTRING_LEN(epath
));
137 if (RSTRING_PTR(epath
)[0] == '#')
139 if ((tail
= memchr(einfo
, '\n', elen
)) != 0) {
141 tail
++; /* skip newline */
144 warn_print2(einfo
, len
);
147 warn_print2(RSTRING_PTR(epath
), RSTRING_LEN(epath
));
151 warn_print2(tail
, elen
- len
- 1);
152 if (einfo
[elen
-1] != '\n') warn_print2("\n", 1);
159 long len
= RARRAY_LEN(errat
);
160 VALUE
*ptr
= RARRAY_PTR(errat
);
161 int skip
= eclass
== rb_eSysStackError
;
163 #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
167 for (i
= 1; i
< len
; i
++) {
168 if (TYPE(ptr
[i
]) == T_STRING
) {
169 warn_printf("\tfrom %s\n", RSTRING_PTR(ptr
[i
]));
171 if (skip
&& i
== TRACE_HEAD
&& len
> TRACE_MAX
) {
172 warn_printf("\t ... %ld levels...\n",
173 len
- TRACE_HEAD
- TRACE_TAIL
);
174 i
= len
- TRACE_TAIL
;
183 ruby_error_print(void)
189 rb_print_undef(VALUE klass
, ID id
, int scope
)
195 case NOEX_PUBLIC
: v
= ""; break;
196 case NOEX_PRIVATE
: v
= " private"; break;
197 case NOEX_PROTECTED
: v
= " protected"; break;
199 rb_name_error(id
, "undefined%s method `%s' for %s `%s'", v
,
201 (TYPE(klass
) == T_MODULE
) ? "module" : "class",
202 rb_class2name(klass
));
206 sysexit_status(VALUE err
)
208 VALUE st
= rb_iv_get(err
, "status");
215 int status
= EXIT_FAILURE
;
216 rb_thread_t
*th
= GET_THREAD();
218 if (rb_thread_set_raised(th
))
220 switch (ex
& TAG_MASK
) {
222 status
= EXIT_SUCCESS
;
227 warn_print(": unexpected return\n");
231 warn_print(": unexpected next\n");
235 warn_print(": unexpected break\n");
239 warn_print(": unexpected redo\n");
243 warn_print(": retry outside of rescue clause\n");
248 warn_printf(": unexpected throw\n");
251 VALUE errinfo
= GET_THREAD()->errinfo
;
252 if (rb_obj_is_kind_of(errinfo
, rb_eSystemExit
)) {
253 status
= sysexit_status(errinfo
);
255 else if (rb_obj_is_instance_of(errinfo
, rb_eSignal
)) {
256 /* no message when exiting by signal */
267 rb_bug("Unknown longjmp status %d", ex
);
270 rb_thread_reset_raised(th
);