From 145f7bc14ba87bb2d113f920e9526d347aee7809 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Tue, 26 Jan 2016 14:05:00 -0800 Subject: [PATCH] Support warning filters This adds a simple way to filter warnings from being displayed. You just set a $WARNING_FILTER with a regexp, and any warnings that match the regexp will not be displayed. I think this is a much simpler approach to filtering warnings than feature #11588, while allowing the same type of capability. This is backwards compatible, in that you can set $WARNING_FILTER in previous versions of ruby without problems. This should not cause any performance issues, as the regexp matching isn't done until the warning message is about to be displayed. It's possible to use something other than a global variable to store the warning filter, but a global variable was the easiest way to implement it, it has a global effect, and similar flags such as $VERBOSE are also global variables, so I think a global variable makes sense. --- error.c | 24 +++++++++++++++++------- test/ruby/test_module.rb | 10 ++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/error.c b/error.c index f88c19a..a0e99bd 100644 --- a/error.c +++ b/error.c @@ -179,13 +179,22 @@ rb_compile_error_append(const char *fmt, ...) } static void +rb_write_warning_str(VALUE str) +{ + VALUE filter = rb_gv_get("$WARNING_FILTER"); + if (RB_TYPE_P(filter, T_REGEXP) && !NIL_P(rb_reg_match(filter, str))) + return; + rb_write_error_str(str); +} + +static void compile_warn_print(const char *file, int line, const char *fmt, va_list args) { VALUE str; str = compile_snprintf(NULL, "warning: ", file, line, fmt, args); rb_str_cat2(str, "\n"); - rb_write_error_str(str); + rb_write_warning_str(str); } void @@ -243,7 +252,7 @@ rb_warn(const char *fmt, ...) va_start(args, fmt); mesg = warning_string(0, fmt, args); va_end(args); - rb_write_error_str(mesg); + rb_write_warning_str(mesg); } void @@ -257,7 +266,7 @@ rb_enc_warn(rb_encoding *enc, const char *fmt, ...) va_start(args, fmt); mesg = warning_string(enc, fmt, args); va_end(args); - rb_write_error_str(mesg); + rb_write_warning_str(mesg); } /* rb_warning() reports only in verbose mode */ @@ -272,7 +281,7 @@ rb_warning(const char *fmt, ...) va_start(args, fmt); mesg = warning_string(0, fmt, args); va_end(args); - rb_write_error_str(mesg); + rb_write_warning_str(mesg); } #if 0 @@ -287,7 +296,7 @@ rb_enc_warning(rb_encoding *enc, const char *fmt, ...) va_start(args, fmt); mesg = warning_string(enc, fmt, args); va_end(args); - rb_write_error_str(mesg); + rb_write_warning_str(mesg); } #endif @@ -2270,7 +2279,7 @@ rb_sys_warning(const char *fmt, ...) va_end(args); rb_str_set_len(mesg, RSTRING_LEN(mesg)-1); rb_str_catf(mesg, ": %s\n", strerror(errno_save)); - rb_write_error_str(mesg); + rb_write_warning_str(mesg); errno = errno_save; } @@ -2290,7 +2299,7 @@ rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...) va_end(args); rb_str_set_len(mesg, RSTRING_LEN(mesg)-1); rb_str_catf(mesg, ": %s\n", strerror(errno_save)); - rb_write_error_str(mesg); + rb_write_warning_str(mesg); errno = errno_save; } @@ -2364,6 +2373,7 @@ void Init_syserr(void) { rb_eNOERROR = set_syserr(0, "NOERROR"); + rb_gv_set("$WARNING_FILTER", Qnil); #define defined_error(name, num) set_syserr((num), (name)); #define undefined_error(name) set_syserr(0, (name)); #include "known_errors.inc" diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 5c07f7a..d00612d 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -1974,6 +1974,16 @@ def test_uninitialized_instance_variable end end + def test_uninitialized_instance_variable_warning_filter + a = AttrTest.new + $WARNING_FILTER = /instance variable @ivar not initialized/ + assert_warning '' do + assert_nil(a.ivar) + end + ensure + $WARNING_FILTER = nil + end + def test_uninitialized_attr a = AttrTest.new assert_warning '' do -- 2.6.4