Project

General

Profile

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

jeremyevans0 (Jeremy Evans), 04/18/2016 10:48 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

  
......
135 138
{
136 139
}
137 140

  
141
static VALUE
142
rb_warning_s_warn(VALUE mod, VALUE str)
143
{
144
    rb_write_error_str(str);
145
    return Qnil;
146
}
147

  
148
static void
149
rb_write_warning_str(VALUE str)
150
{
151
    rb_funcall(rb_mWarning, id_warn, 1, str);
152
}
153

  
138 154
static void
139 155
compile_warn_print(const char *file, int line, const char *fmt, va_list args)
140 156
{
......
142 158

  
143 159
    str = compile_snprintf(NULL, "warning: ", file, line, fmt, args);
144 160
    rb_str_cat2(str, "\n");
145
    rb_write_error_str(str);
161
    rb_write_warning_str(str);
146 162
}
147 163

  
148 164
void
......
200 216
    va_start(args, fmt);
201 217
    mesg = warning_string(0, fmt, args);
202 218
    va_end(args);
203
    rb_write_error_str(mesg);
219
    rb_write_warning_str(mesg);
204 220
}
205 221

  
206 222
void
......
214 230
    va_start(args, fmt);
215 231
    mesg = warning_string(enc, fmt, args);
216 232
    va_end(args);
217
    rb_write_error_str(mesg);
233
    rb_write_warning_str(mesg);
218 234
}
219 235

  
220 236
/* rb_warning() reports only in verbose mode */
......
229 245
    va_start(args, fmt);
230 246
    mesg = warning_string(0, fmt, args);
231 247
    va_end(args);
232
    rb_write_error_str(mesg);
248
    rb_write_warning_str(mesg);
233 249
}
234 250

  
235 251
#if 0
......
244 260
    va_start(args, fmt);
245 261
    mesg = warning_string(enc, fmt, args);
246 262
    va_end(args);
247
    rb_write_error_str(mesg);
263
    rb_write_warning_str(mesg);
248 264
}
249 265
#endif
250 266

  
......
2001 2017

  
2002 2018
    rb_mErrno = rb_define_module("Errno");
2003 2019

  
2020
    rb_mWarning = rb_define_module("Warning");
2021
    rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, 1);
2022
    rb_extend_object(rb_mWarning, rb_mWarning);
2023

  
2004 2024
    rb_define_global_function("warn", rb_warn_m, -1);
2005 2025

  
2006 2026
    id_new = rb_intern_const("new");
......
2015 2035
    id_Errno = rb_intern_const("Errno");
2016 2036
    id_errno = rb_intern_const("errno");
2017 2037
    id_i_path = rb_intern_const("@path");
2038
    id_warn = rb_intern_const("warn");
2018 2039
    id_iseq = rb_make_internal_id();
2019 2040
}
2020 2041

  
......
2238 2259
    va_end(args);
2239 2260
    rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
2240 2261
    rb_str_catf(mesg, ": %s\n", strerror(errno_save));
2241
    rb_write_error_str(mesg);
2262
    rb_write_warning_str(mesg);
2242 2263
    errno = errno_save;
2243 2264
}
2244 2265

  
......
2258 2279
    va_end(args);
2259 2280
    rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
2260 2281
    rb_str_catf(mesg, ": %s\n", strerror(errno_save));
2261
    rb_write_error_str(mesg);
2282
    rb_write_warning_str(mesg);
2262 2283
    errno = errno_save;
2263 2284
}
2264 2285

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

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

  
41
    # Handle ignored warnings and warning processors.  If the warning is
42
    # not ignored and there is no warning processor setup for the warning
43
    # string, then use the default behavior of writing to $stderr.
44
    def warn(str)
45
      @ignore.each do |path, regexp|
46
        if str.start_with?(path) && str =~ regexp
47
          return
48
        end
49
      end
50

  
51
      @process.each do |path, block|
52
        if str.start_with?(path)
53
          block.call(str)
54
          return
55
        end
56
      end
57

  
58
      super
59
    end
60
  end
61

  
62
  @ignore = []
63
  @process = []
64
  extend Processor
65
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
    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
    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
    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
    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
    Warning.clear
905
  end
906

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

  
911
    require 'warning'
912

  
913
    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
    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
    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
    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
    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
    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
    Warning.clear
973
  end
858 974
end
859
-