diff --git a/ChangeLog b/ChangeLog index e6fcef0201..b5c5a8dade 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Tue May 13 14:48:07 2003 Yukihiro Matsumoto + + * eval.c (error_pos): use $deferr for output instead of stderr + directly. + + * eval.c (error_print,error_handle,rb_longjmp,rb_thread_schedule): + ditto. + +Mon May 12 18:08:21 2003 Yukihiro Matsumoto + + * io.c (Init_IO): new variable $deferr which is default output + port of error messages. + + * io.c (rb_warn_m): new method "warn". [new] + + * error.c (warn_print): use $deferr. + + * error.c (rb_bug): ditto. + + * error.c (err_append): ditto. + Sun May 11 13:50:12 2003 Tanaka Akira * lib/pp.rb: refine to_s test. diff --git a/error.c b/error.c index e0c91f6746..ce7800d07c 100644 --- a/error.c +++ b/error.c @@ -106,9 +106,8 @@ warn_print(fmt, args) char buf[BUFSIZ]; err_snprintf(buf, BUFSIZ, fmt, args); - fputs(buf, stderr); - fputs("\n", stderr); - fflush(stderr); + rb_write_deferr(buf); + rb_write_deferr("\n"); } void @@ -170,7 +169,9 @@ rb_bug(fmt, va_alist) va_init_list(args, fmt); warn_print(buf, args); va_end(args); - fprintf(stderr, "ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM); + snprintf(buf, BUFSIZ, "ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM); + rb_write_deferr(buf); + rb_write_deferr("\n"); abort(); } @@ -1124,8 +1125,7 @@ err_append(s) } } else { - fputs(s, stderr); - fputs("\n", stderr); - fflush(stderr); + rb_write_deferr(s); + rb_write_deferr("\n"); } } diff --git a/eval.c b/eval.c index 4a079203a7..df4bfce42a 100644 --- a/eval.c +++ b/eval.c @@ -972,20 +972,41 @@ ruby_set_current_source() } } +static void +#ifdef HAVE_STDARG_PROTOTYPES +warn_printf(const char *fmt, ...) +#else +warn_printf(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + char buf[BUFSIZ]; + va_list args; + + va_init_list(args, fmt); + vsnprintf(buf, BUFSIZ, fmt, args); + va_end(args); + rb_write_deferr(buf); +} + +#define warn_print(x) rb_write_deferr(x) +#define warn_print2(x,l) rb_write_deferr2(x,l) + static void error_pos() { ruby_set_current_source(); if (ruby_sourcefile) { if (ruby_frame->last_func) { - fprintf(stderr, "%s:%d:in `%s'", ruby_sourcefile, ruby_sourceline, - rb_id2name(ruby_frame->last_func)); + warn_printf("%s:%d:in `%s'", ruby_sourcefile, ruby_sourceline, + rb_id2name(ruby_frame->last_func)); } else if (ruby_sourceline == 0) { - fprintf(stderr, "%s", ruby_sourcefile); + warn_printf("%s", ruby_sourcefile); } else { - fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline); + warn_printf("%s:%d", ruby_sourcefile, ruby_sourceline); } } } @@ -1026,9 +1047,9 @@ error_print() if (NIL_P(errat)){ ruby_set_current_source(); if (ruby_sourcefile) - fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline); + warn_printf("%s:%d", ruby_sourcefile, ruby_sourceline); else - fprintf(stderr, "%d", ruby_sourceline); + warn_printf("%d", ruby_sourceline); } else if (RARRAY(errat)->len == 0) { error_pos(); @@ -1038,7 +1059,7 @@ error_print() if (NIL_P(mesg)) error_pos(); else { - fwrite(RSTRING(mesg)->ptr, 1, RSTRING(mesg)->len, stderr); + warn_print2(RSTRING(mesg)->ptr, RSTRING(mesg)->len); } } @@ -1055,16 +1076,15 @@ error_print() } POP_TAG(); if (eclass == rb_eRuntimeError && elen == 0) { - fprintf(stderr, ": unhandled exception\n"); + warn_print(": unhandled exception\n"); } else { VALUE epath; epath = rb_class_path(eclass); if (elen == 0) { - fprintf(stderr, ": "); - fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr); - putc('\n', stderr); + warn_print(": "); + warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len); } else { char *tail = 0; @@ -1075,16 +1095,15 @@ error_print() len = tail - einfo; tail++; /* skip newline */ } - fprintf(stderr, ": "); - fwrite(einfo, 1, len, stderr); + warn_print(": "); + warn_print2(einfo, len); if (epath) { - fprintf(stderr, " ("); - fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr); - fprintf(stderr, ")\n"); + warn_print(" ("); + warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len); + warn_print(")\n"); } if (tail) { - fwrite(tail, 1, elen-len-1, stderr); - putc('\n', stderr); + warn_print2(tail, elen-len-1); } } } @@ -1100,16 +1119,15 @@ error_print() ep = RARRAY(errat); for (i=1; ilen; i++) { if (TYPE(ep->ptr[i]) == T_STRING) { - fprintf(stderr, "\tfrom %s\n", RSTRING(ep->ptr[i])->ptr); + warn_printf("\tfrom %s\n", RSTRING(ep->ptr[i])->ptr); } if (i == TRACE_HEAD && ep->len > TRACE_MAX) { - fprintf(stderr, "\t ... %ld levels...\n", + warn_printf("\t ... %ld levels...\n", ep->len - TRACE_HEAD - TRACE_TAIL); i = ep->len - TRACE_TAIL; } } } - fflush(stderr); } #if defined(__APPLE__) @@ -1206,38 +1224,38 @@ error_handle(ex) case TAG_RETURN: error_pos(); - fprintf(stderr, ": unexpected return\n"); + warn_print(": unexpected return\n"); ex = 1; break; case TAG_NEXT: error_pos(); - fprintf(stderr, ": unexpected next\n"); + warn_print(": unexpected next\n"); ex = 1; break; case TAG_BREAK: error_pos(); - fprintf(stderr, ": unexpected break\n"); + warn_print(": unexpected break\n"); ex = 1; break; case TAG_REDO: error_pos(); - fprintf(stderr, ": unexpected redo\n"); + warn_print(": unexpected redo\n"); ex = 1; break; case TAG_RETRY: error_pos(); - fprintf(stderr, ": retry outside of rescue clause\n"); + warn_print(": retry outside of rescue clause\n"); ex = 1; break; case TAG_THROW: if (prot_tag && prot_tag->frame && prot_tag->frame->node) { NODE *tag = prot_tag->frame->node; - fprintf(stderr, "%s:%d: uncaught throw\n", + warn_printf("%s:%d: uncaught throw\n", tag->nd_file, nd_line(tag)); } else { error_pos(); - fprintf(stderr, ": unexpected throw\n"); + warn_printf(": unexpected throw\n"); } ex = 1; break; @@ -3762,7 +3780,7 @@ rb_f_abort(argc, argv) rb_scan_args(argc, argv, "1", &mesg); StringValue(argv[0]); - rb_io_puts(argc, argv, rb_stderr); + rb_io_puts(argc, argv, rb_deferr); terminate_process(1, RSTRING(argv[0])->ptr, RSTRING(argv[0])->len); } return Qnil; /* not reached */ @@ -3806,11 +3824,10 @@ rb_longjmp(tag, mesg) VALUE e = ruby_errinfo; StringValue(e); - fprintf(stderr, "Exception `%s' at %s:%d - %s\n", - rb_obj_classname(ruby_errinfo), - ruby_sourcefile, ruby_sourceline, - RSTRING(e)->ptr); - fflush(stderr); + warn_printf("Exception `%s' at %s:%d - %s\n", + rb_obj_classname(ruby_errinfo), + ruby_sourcefile, ruby_sourceline, + RSTRING(e)->ptr); } rb_trap_restore_mask(); @@ -8372,21 +8389,20 @@ rb_thread_schedule() TRAP_END; } FOREACH_THREAD_FROM(curr, th) { - fprintf(stderr, "deadlock 0x%lx: %s:", - th->thread, thread_status_name(th->status)); - if (th->wait_for & WAIT_FD) fprintf(stderr, "F(%d)", th->fd); - if (th->wait_for & WAIT_SELECT) fprintf(stderr, "S"); - if (th->wait_for & WAIT_TIME) fprintf(stderr, "T(%f)", th->delay); + warn_printf("deadlock 0x%lx: %s:", + th->thread, thread_status_name(th->status)); + if (th->wait_for & WAIT_FD) warn_printf("F(%d)", th->fd); + if (th->wait_for & WAIT_SELECT) warn_printf("S"); + if (th->wait_for & WAIT_TIME) warn_printf("T(%f)", th->delay); if (th->wait_for & WAIT_JOIN) - fprintf(stderr, "J(0x%lx)", th->join ? th->join->thread : 0); - if (th->wait_for & WAIT_PID) fprintf(stderr, "P"); - if (!th->wait_for) fprintf(stderr, "-"); - fprintf(stderr, " %s - %s:%d\n", - th==main_thread ? "(main)" : "", - th->node->nd_file, nd_line(th->node)); + warn_printf("J(0x%lx)", th->join ? th->join->thread : 0); + if (th->wait_for & WAIT_PID) warn_printf("P"); + if (!th->wait_for) warn_printf("-"); + warn_printf(" %s - %s:%d\n", + th==main_thread ? "(main)" : "", + th->node->nd_file, nd_line(th->node)); } END_FOREACH_FROM(curr, th); - fflush(stderr); next = main_thread; rb_thread_ready(next); next->status = THREAD_TO_KILL; diff --git a/intern.h b/intern.h index 9b4c86ce9a..6776216c40 100644 --- a/intern.h +++ b/intern.h @@ -264,6 +264,8 @@ VALUE rb_io_print _((int, VALUE*, VALUE)); VALUE rb_io_puts _((int, VALUE*, VALUE)); VALUE rb_file_open _((const char*, const char*)); VALUE rb_gets _((void)); +void rb_write_deferr _((const char*)); +void rb_write_deferr2 _((const char*, long)); /* marshal.c */ VALUE rb_marshal_dump _((VALUE, VALUE)); VALUE rb_marshal_load _((VALUE)); diff --git a/io.c b/io.c index f44a78944c..1b2a9d51b2 100644 --- a/io.c +++ b/io.c @@ -94,7 +94,7 @@ VALUE rb_cIO; VALUE rb_eEOFError; VALUE rb_eIOError; -VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout; +VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout, rb_deferr; static VALUE orig_stdin, orig_stdout, orig_stderr; static int saved_fd[3] = {0, 1, 2}; @@ -2714,6 +2714,30 @@ rb_obj_display(argc, argv, self) return Qnil; } +void +rb_write_deferr2(mesg, len) + const char *mesg; + long len; +{ + rb_io_write(rb_deferr, rb_str_new(mesg, len)); +} + +void +rb_write_deferr(mesg) + const char *mesg; +{ + rb_write_deferr2(mesg, strlen(mesg)); +} + +static VALUE +rb_warn_m(self, mesg) + VALUE self, mesg; +{ + rb_io_write(rb_deferr, mesg); + rb_io_write(rb_deferr, rb_default_rs); + return mesg; +} + static void must_respond_to(mid, val, id) ID mid; @@ -2728,12 +2752,13 @@ must_respond_to(mid, val, id) } static void -rb_io_defset(val, id) +rb_io_defset(val, id, variable) VALUE val; ID id; + VALUE *variable; { must_respond_to(id_write, val, id); - rb_defout = val; + *variable = val; } static void @@ -4044,6 +4069,8 @@ Init_IO() rb_defout = rb_stdout; rb_define_hooked_variable("$>", &rb_defout, 0, rb_io_defset); rb_define_hooked_variable("$defout", &rb_defout, 0, rb_io_defset); + rb_deferr = rb_stderr; + rb_define_hooked_variable("$deferr", &rb_deferr, 0, rb_io_defset); rb_define_global_const("STDIN", rb_stdin); rb_define_global_const("STDOUT", rb_stdout); @@ -4125,4 +4152,6 @@ Init_IO() #ifdef O_SYNC rb_file_const("SYNC", INT2FIX(O_SYNC)); #endif + + rb_define_global_function("warn", rb_warn_m, 1); } diff --git a/ruby.h b/ruby.h index 53b92bc8cc..1a96004caf 100644 --- a/ruby.h +++ b/ruby.h @@ -608,7 +608,9 @@ RUBY_EXTERN VALUE rb_eNameError; RUBY_EXTERN VALUE rb_eSyntaxError; RUBY_EXTERN VALUE rb_eLoadError; -RUBY_EXTERN VALUE rb_defout, rb_stdin, rb_stdout, rb_stderr, ruby_errinfo; +RUBY_EXTERN VALUE rb_defout, rb_deferr; +RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr; +RUBY_EXTERN VALUE ruby_errinfo; static inline VALUE #if defined(HAVE_PROTOTYPES)