From 75b25e798c6fb56ff2823d0976df0a25182da55b Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Tue, 15 Nov 2016 12:08:16 -0800 Subject: [PATCH] Change Kernel#warn to call Warning.warn This allows Warning.warn to filter/process warning messages generated by Kernel#warn. Currently, Warning.warn can only handle messages generated by the rb_warn/rb_warning C functions. The Kernel#warn API is different than the Warning.warn API, this tries to get similar behavior, but there are probably corner cases where the behavior is different. --- error.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/error.c b/error.c index e03a4ee..4a04e03 100644 --- a/error.c +++ b/error.c @@ -276,10 +276,12 @@ rb_enc_warning(rb_encoding *enc, const char *fmt, ...) * call-seq: * warn(msg, ...) -> nil * - * Displays each of the given messages followed by a record separator on - * STDERR unless warnings have been disabled (for example with the - * -W0 flag). - * + * If warnings have been disabled (for example with the + * -W0 flag), does nothing. Otherwise, + * converts each of the messages to strings, appends a newline + * character to the string if the string does not end in a newline, + * and calls Warning.warn with the string. + * * warn("warning 1", "warning 2") * * produces: @@ -292,7 +294,19 @@ static VALUE rb_warn_m(int argc, VALUE *argv, VALUE exc) { if (!NIL_P(ruby_verbose) && argc > 0) { - rb_io_puts(argc, argv, rb_stderr); + int i; + VALUE str; + long len; + const char *ptr; + for(i = 0; i < argc; i++) { + str = rb_obj_as_string(argv[i]); + len = RSTRING_LEN(str); + ptr = RSTRING_PTR(str); + if (len == 0 || ptr[len-1] != '\n') { + str = rb_str_cat(str, "\n", 1); + } + rb_write_warning_str(str); + } } return Qnil; } -- 2.10.1