Feature #12299 » 0001-Add-Exception-Warning-module-for-customized-warning-.patch
error.c | ||
---|---|---|
VALUE rb_eEAGAIN;
|
||
VALUE rb_eEWOULDBLOCK;
|
||
VALUE rb_eEINPROGRESS;
|
||
VALUE rb_mWarning;
|
||
static ID id_warn;
|
||
extern const char ruby_description[];
|
||
... | ... | |
}
|
||
static VALUE
|
||
rb_warning_s_warn(VALUE mod, VALUE str)
|
||
{
|
||
rb_write_error_str(str);
|
||
return Qnil;
|
||
}
|
||
static void
|
||
rb_write_warning_str(VALUE str)
|
||
{
|
||
rb_funcall(rb_mWarning, id_warn, 1, str);
|
||
}
|
||
static VALUE
|
||
warn_vsprintf(rb_encoding *enc, const char *file, int line, const char *fmt, va_list args)
|
||
{
|
||
VALUE str = rb_enc_str_new(0, 0, enc);
|
||
... | ... | |
va_start(args, fmt);
|
||
str = warn_vsprintf(NULL, file, line, fmt, args);
|
||
va_end(args);
|
||
rb_write_error_str(str);
|
||
rb_write_warning_str(str);
|
||
}
|
||
/* rb_compile_warning() reports only in verbose mode */
|
||
... | ... | |
va_start(args, fmt);
|
||
str = warn_vsprintf(NULL, file, line, fmt, args);
|
||
va_end(args);
|
||
rb_write_error_str(str);
|
||
rb_write_warning_str(str);
|
||
}
|
||
static VALUE
|
||
... | ... | |
va_start(args, fmt);
|
||
mesg = warning_string(0, fmt, args);
|
||
va_end(args);
|
||
rb_write_error_str(mesg);
|
||
rb_write_warning_str(mesg);
|
||
}
|
||
void
|
||
... | ... | |
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 */
|
||
... | ... | |
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
|
||
... | ... | |
va_start(args, fmt);
|
||
mesg = warning_string(enc, fmt, args);
|
||
va_end(args);
|
||
rb_write_error_str(mesg);
|
||
rb_write_warning_str(mesg);
|
||
}
|
||
#endif
|
||
... | ... | |
rb_mErrno = rb_define_module("Errno");
|
||
rb_mWarning = rb_define_module_under(rb_eException, "Warning");
|
||
rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, 1);
|
||
rb_extend_object(rb_mWarning, rb_mWarning);
|
||
rb_define_global_function("warn", rb_warn_m, -1);
|
||
id_new = rb_intern_const("new");
|
||
... | ... | |
id_Errno = rb_intern_const("Errno");
|
||
id_errno = rb_intern_const("errno");
|
||
id_i_path = rb_intern_const("@path");
|
||
id_warn = rb_intern_const("warn");
|
||
id_iseq = rb_make_internal_id();
|
||
}
|
||
... | ... | |
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;
|
||
}
|
||
... | ... | |
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;
|
||
}
|
||
lib/warning.rb | ||
---|---|---|
require 'monitor'
|
||
module Exception::Warning
|
||
module Processor
|
||
# Clear all current ignored warnings and warning processors.
|
||
def clear
|
||
synchronize do
|
||
@ignore.clear
|
||
@process.clear
|
||
end
|
||
end
|
||
|
||
# Ignore any warning messages matching the given regexp, if they
|
||
# start with the given path. Examples:
|
||
#
|
||
# # Ignore all uninitialized instance variable warnings
|
||
# Warning.ignore(/instance variable @\w+ not initialized/)
|
||
#
|
||
# # Ignore all uninitialized instance variable warnings in current file
|
||
# Warning.ignore(/instance variable @\w+ not initialized/, __FILE__)
|
||
def ignore(regexp, path='')
|
||
synchronize do
|
||
@ignore << [path, regexp]
|
||
end
|
||
nil
|
||
end
|
||
# Handle all warnings starting with the given path, instead of
|
||
# the default behavior of printing them to $stderr. Examples:
|
||
#
|
||
# # Write warning to LOGGER at level warning
|
||
# Warning.process do |warning|
|
||
# LOGGER.warning(warning)
|
||
# end
|
||
#
|
||
# # Write warnings in the current file to LOGGER at level error level
|
||
# Warning.process(__FILE__) do |warning|
|
||
# LOGGER.error(warning)
|
||
# end
|
||
def process(path='', &block)
|
||
synchronize do
|
||
@process << [path, block]
|
||
@process.sort_by!(&:first)
|
||
@process.reverse!
|
||
end
|
||
nil
|
||
end
|
||
# Handle ignored warnings and warning processors. If the warning is
|
||
# not ignored and there is no warning processor setup for the warning
|
||
# string, then use the default behavior of writing to $stderr.
|
||
def warn(str)
|
||
synchronize{@ignore.dup}.each do |path, regexp|
|
||
if str.start_with?(path) && str =~ regexp
|
||
return
|
||
end
|
||
end
|
||
synchronize{@process.dup}.each do |path, block|
|
||
if str.start_with?(path)
|
||
block.call(str)
|
||
return
|
||
end
|
||
end
|
||
super
|
||
end
|
||
end
|
||
@ignore = []
|
||
@process = []
|
||
extend MonitorMixin
|
||
extend Processor
|
||
end
|
test/ruby/test_exception.rb | ||
---|---|---|
end
|
||
end
|
||
end
|
||
def test_warning_ignore
|
||
obj = Object.new
|
||
assert_warning /instance variable @ivar not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar))
|
||
end
|
||
require 'warning'
|
||
assert_warning /instance variable @ivar not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar))
|
||
end
|
||
Exception::Warning.ignore(/instance variable @ivar not initialized/)
|
||
assert_warning '' do
|
||
assert_nil(obj.instance_variable_get(:@ivar))
|
||
end
|
||
assert_warning /instance variable @ivar2 not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar2))
|
||
end
|
||
Exception::Warning.ignore(/instance variable @ivar2 not initialized/, __FILE__)
|
||
assert_warning '' do
|
||
assert_nil(obj.instance_variable_get(:@ivar2))
|
||
end
|
||
assert_warning /instance variable @ivar3 not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar3))
|
||
end
|
||
Exception::Warning.ignore(/instance variable @ivar3 not initialized/, __FILE__+'a')
|
||
assert_warning /instance variable @ivar3 not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar3))
|
||
end
|
||
Exception::Warning.clear
|
||
assert_warning /instance variable @ivar not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar))
|
||
end
|
||
ensure
|
||
Exception::Warning.clear
|
||
end
|
||
def test_warning_process
|
||
obj = Object.new
|
||
warn = nil
|
||
require 'warning'
|
||
Exception::Warning.process(__FILE__+'a') do |warning|
|
||
warn = [0, warning]
|
||
end
|
||
assert_warning /instance variable @ivar not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar))
|
||
end
|
||
assert_nil(warn)
|
||
Exception::Warning.process(__FILE__) do |warning|
|
||
warn = [1, warning]
|
||
end
|
||
assert_warning '' do
|
||
assert_nil(obj.instance_variable_get(:@ivar2))
|
||
end
|
||
assert_equal(1, warn.first)
|
||
assert_match(/instance variable @ivar2 not initialized/, warn.last)
|
||
warn = nil
|
||
Exception::Warning.process(File.dirname(__FILE__)) do |warning|
|
||
warn = [2, warning]
|
||
end
|
||
assert_warning '' do
|
||
assert_nil(obj.instance_variable_get(:@ivar3))
|
||
end
|
||
assert_equal(1, warn.first)
|
||
assert_match(/instance variable @ivar3 not initialized/, warn.last)
|
||
warn = nil
|
||
Exception::Warning.process(__FILE__+':') do |warning|
|
||
warn = [3, warning]
|
||
end
|
||
assert_warning '' do
|
||
assert_nil(obj.instance_variable_get(:@ivar4))
|
||
end
|
||
assert_equal(3, warn.first)
|
||
assert_match(/instance variable @ivar4 not initialized/, warn.last)
|
||
warn = nil
|
||
Exception::Warning.clear
|
||
assert_warning /instance variable @ivar5 not initialized/ do
|
||
assert_nil(obj.instance_variable_get(:@ivar5))
|
||
end
|
||
assert_nil(warn)
|
||
Exception::Warning.process do |warning|
|
||
warn = [4, warning]
|
||
end
|
||
assert_warning '' do
|
||
assert_nil(obj.instance_variable_get(:@ivar6))
|
||
end
|
||
assert_equal(4, warn.first)
|
||
assert_match(/instance variable @ivar6 not initialized/, warn.last)
|
||
ensure
|
||
Exception::Warning.clear
|
||
end
|
||
end
|