Project

General

Profile

Feature #12299 ยป 0001-Add-Exception-Warning-module-for-customized-warning-.patch

jeremyevans0 (Jeremy Evans), 06/20/2016 05:47 PM

View differences:

error.c
42 42
VALUE rb_eEAGAIN;
43 43
VALUE rb_eEWOULDBLOCK;
44 44
VALUE rb_eEINPROGRESS;
45
VALUE rb_mWarning;
46

  
47
static ID id_warn;
45 48

  
46 49
extern const char ruby_description[];
47 50

  
......
147 150
}
148 151

  
149 152
static VALUE
153
rb_warning_s_warn(VALUE mod, VALUE str)
154
{
155
    rb_write_error_str(str);
156
    return Qnil;
157
}
158

  
159
static void
160
rb_write_warning_str(VALUE str)
161
{
162
    rb_funcall(rb_mWarning, id_warn, 1, str);
163
}
164

  
165
static VALUE
150 166
warn_vsprintf(rb_encoding *enc, const char *file, int line, const char *fmt, va_list args)
151 167
{
152 168
    VALUE str = rb_enc_str_new(0, 0, enc);
......
166 182
    va_start(args, fmt);
167 183
    str = warn_vsprintf(NULL, file, line, fmt, args);
168 184
    va_end(args);
169
    rb_write_error_str(str);
185
    rb_write_warning_str(str);
170 186
}
171 187

  
172 188
/* rb_compile_warning() reports only in verbose mode */
......
181 197
    va_start(args, fmt);
182 198
    str = warn_vsprintf(NULL, file, line, fmt, args);
183 199
    va_end(args);
184
    rb_write_error_str(str);
200
    rb_write_warning_str(str);
185 201
}
186 202

  
187 203
static VALUE
......
206 222
    va_start(args, fmt);
207 223
    mesg = warning_string(0, fmt, args);
208 224
    va_end(args);
209
    rb_write_error_str(mesg);
225
    rb_write_warning_str(mesg);
210 226
}
211 227

  
212 228
void
......
220 236
    va_start(args, fmt);
221 237
    mesg = warning_string(enc, fmt, args);
222 238
    va_end(args);
223
    rb_write_error_str(mesg);
239
    rb_write_warning_str(mesg);
224 240
}
225 241

  
226 242
/* rb_warning() reports only in verbose mode */
......
235 251
    va_start(args, fmt);
236 252
    mesg = warning_string(0, fmt, args);
237 253
    va_end(args);
238
    rb_write_error_str(mesg);
254
    rb_write_warning_str(mesg);
239 255
}
240 256

  
241 257
#if 0
......
250 266
    va_start(args, fmt);
251 267
    mesg = warning_string(enc, fmt, args);
252 268
    va_end(args);
253
    rb_write_error_str(mesg);
269
    rb_write_warning_str(mesg);
254 270
}
255 271
#endif
256 272

  
......
2026 2042

  
2027 2043
    rb_mErrno = rb_define_module("Errno");
2028 2044

  
2045
    rb_mWarning = rb_define_module_under(rb_eException, "Warning");
2046
    rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, 1);
2047
    rb_extend_object(rb_mWarning, rb_mWarning);
2048

  
2029 2049
    rb_define_global_function("warn", rb_warn_m, -1);
2030 2050

  
2031 2051
    id_new = rb_intern_const("new");
......
2040 2060
    id_Errno = rb_intern_const("Errno");
2041 2061
    id_errno = rb_intern_const("errno");
2042 2062
    id_i_path = rb_intern_const("@path");
2063
    id_warn = rb_intern_const("warn");
2043 2064
    id_iseq = rb_make_internal_id();
2044 2065
}
2045 2066

  
......
2263 2284
    va_end(args);
2264 2285
    rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
2265 2286
    rb_str_catf(mesg, ": %s\n", strerror(errno_save));
2266
    rb_write_error_str(mesg);
2287
    rb_write_warning_str(mesg);
2267 2288
    errno = errno_save;
2268 2289
}
2269 2290

  
......
2283 2304
    va_end(args);
2284 2305
    rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
2285 2306
    rb_str_catf(mesg, ": %s\n", strerror(errno_save));
2286
    rb_write_error_str(mesg);
2307
    rb_write_warning_str(mesg);
2287 2308
    errno = errno_save;
2288 2309
}
2289 2310

  
lib/warning.rb
1
require 'monitor'
2

  
3
module Exception::Warning
4
  module Processor
5
    # Clear all current ignored warnings and warning processors.
6
    def clear
7
      synchronize do
8
        @ignore.clear
9
        @process.clear
10
      end
11
    end
12
    
13
    # Ignore any warning messages matching the given regexp, if they
14
    # start with the given path. Examples:
15
    #
16
    #   # Ignore all uninitialized instance variable warnings
17
    #   Warning.ignore(/instance variable @\w+ not initialized/)
18
    #
19
    #   # Ignore all uninitialized instance variable warnings in current file
20
    #   Warning.ignore(/instance variable @\w+ not initialized/, __FILE__)
21
    def ignore(regexp, path='')
22
      synchronize do 
23
        @ignore << [path, regexp]
24
      end
25
      nil
26
    end
27

  
28
    # Handle all warnings starting with the given path, instead of
29
    # the default behavior of printing them to $stderr. Examples:
30
    #
31
    #   # Write warning to LOGGER at level warning
32
    #   Warning.process do |warning|
33
    #     LOGGER.warning(warning)
34
    #   end
35
    #
36
    #   # Write warnings in the current file to LOGGER at level error level
37
    #   Warning.process(__FILE__) do |warning|
38
    #     LOGGER.error(warning)
39
    #   end
40
    def process(path='', &block)
41
      synchronize do
42
        @process << [path, block]
43
        @process.sort_by!(&:first)
44
        @process.reverse!
45
      end
46
      nil
47
    end
48

  
49
    # Handle ignored warnings and warning processors.  If the warning is
50
    # not ignored and there is no warning processor setup for the warning
51
    # string, then use the default behavior of writing to $stderr.
52
    def warn(str)
53
      synchronize{@ignore.dup}.each do |path, regexp|
54
        if str.start_with?(path) && str =~ regexp
55
          return
56
        end
57
      end
58

  
59
      synchronize{@process.dup}.each do |path, block|
60
        if str.start_with?(path)
61
          block.call(str)
62
          return
63
        end
64
      end
65

  
66
      super
67
    end
68
  end
69

  
70
  @ignore = []
71
  @process = []
72

  
73
  extend MonitorMixin
74
  extend Processor
75
end
test/ruby/test_exception.rb
855 855
      end
856 856
    end
857 857
  end
858

  
859
  def test_warning_ignore
860
    obj = Object.new
861

  
862
    assert_warning /instance variable @ivar not initialized/ do
863
      assert_nil(obj.instance_variable_get(:@ivar))
864
    end
865

  
866
    require 'warning'
867

  
868
    assert_warning /instance variable @ivar not initialized/ do
869
      assert_nil(obj.instance_variable_get(:@ivar))
870
    end
871

  
872
    Exception::Warning.ignore(/instance variable @ivar not initialized/)
873

  
874
    assert_warning '' do
875
      assert_nil(obj.instance_variable_get(:@ivar))
876
    end
877

  
878
    assert_warning /instance variable @ivar2 not initialized/ do
879
      assert_nil(obj.instance_variable_get(:@ivar2))
880
    end
881

  
882
    Exception::Warning.ignore(/instance variable @ivar2 not initialized/, __FILE__)
883

  
884
    assert_warning '' do
885
      assert_nil(obj.instance_variable_get(:@ivar2))
886
    end
887

  
888
    assert_warning /instance variable @ivar3 not initialized/ do
889
      assert_nil(obj.instance_variable_get(:@ivar3))
890
    end
891

  
892
    Exception::Warning.ignore(/instance variable @ivar3 not initialized/, __FILE__+'a')
893

  
894
    assert_warning /instance variable @ivar3 not initialized/ do
895
      assert_nil(obj.instance_variable_get(:@ivar3))
896
    end
897

  
898
    Exception::Warning.clear
899

  
900
    assert_warning /instance variable @ivar not initialized/ do
901
      assert_nil(obj.instance_variable_get(:@ivar))
902
    end
903
  ensure
904
    Exception::Warning.clear
905
  end
906

  
907
  def test_warning_process
908
    obj = Object.new
909
    warn = nil
910

  
911
    require 'warning'
912

  
913
    Exception::Warning.process(__FILE__+'a') do |warning|
914
      warn = [0, warning]
915
    end
916

  
917
    assert_warning /instance variable @ivar not initialized/ do
918
      assert_nil(obj.instance_variable_get(:@ivar))
919
    end
920
    assert_nil(warn)
921

  
922
    Exception::Warning.process(__FILE__) do |warning|
923
      warn = [1, warning]
924
    end
925

  
926
    assert_warning '' do
927
      assert_nil(obj.instance_variable_get(:@ivar2))
928
    end
929
    assert_equal(1, warn.first)
930
    assert_match(/instance variable @ivar2 not initialized/, warn.last)
931
    warn = nil
932

  
933
    Exception::Warning.process(File.dirname(__FILE__)) do |warning|
934
      warn = [2, warning]
935
    end
936

  
937
    assert_warning '' do
938
      assert_nil(obj.instance_variable_get(:@ivar3))
939
    end
940
    assert_equal(1, warn.first)
941
    assert_match(/instance variable @ivar3 not initialized/, warn.last)
942
    warn = nil
943

  
944
    Exception::Warning.process(__FILE__+':') do |warning|
945
      warn = [3, warning]
946
    end
947

  
948
    assert_warning '' do
949
      assert_nil(obj.instance_variable_get(:@ivar4))
950
    end
951
    assert_equal(3, warn.first)
952
    assert_match(/instance variable @ivar4 not initialized/, warn.last)
953
    warn = nil
954

  
955
    Exception::Warning.clear
956

  
957
    assert_warning /instance variable @ivar5 not initialized/ do
958
      assert_nil(obj.instance_variable_get(:@ivar5))
959
    end
960
    assert_nil(warn)
961

  
962
    Exception::Warning.process do |warning|
963
      warn = [4, warning]
964
    end
965

  
966
    assert_warning '' do
967
      assert_nil(obj.instance_variable_get(:@ivar6))
968
    end
969
    assert_equal(4, warn.first)
970
    assert_match(/instance variable @ivar6 not initialized/, warn.last)
971
  ensure
972
    Exception::Warning.clear
973
  end
858 974
end
859
-