Skip to content

Commit

Permalink
Add uplevel keyword to Kernel#warn and use it
Browse files Browse the repository at this point in the history
If uplevel keyword is given, the warning message is prepended
with caller file and line information and the string "warning: ".
The use of the uplevel keyword makes Kernel#warn format output
similar to how rb_warn formats output.

This patch modifies net/ftp and net/imap to use Kernel#warn
instead of $stderr.puts or $stderr.printf, since they are used
for printing warnings.

This makes lib/cgi/core and tempfile use $stderr.puts instead of
warn for debug logging, since they are used for debug printing
and not for warning.

This does not modify bundler, rubygems, or rdoc, as those are
maintained outside of ruby and probably wish to remain backwards
compatible with older ruby versions.

rb_warn_m code is originally from nobu, but I've changed it
so that it only includes the path and lineno from uplevel
(not the method), and also prepends the string "warning: ",
to make it more similar to rb_warn.

From: Jeremy Evans [email protected]
Signed-off-by: Urabe Shyouhei [email protected]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
shyouhei committed Dec 12, 2017
1 parent 0d77188 commit f2a9139
Show file tree
Hide file tree
Showing 32 changed files with 92 additions and 63 deletions.
35 changes: 32 additions & 3 deletions error.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,39 @@ warning_write(int argc, VALUE *argv, VALUE buf)
static VALUE
rb_warn_m(int argc, VALUE *argv, VALUE exc)
{
if (!NIL_P(ruby_verbose) && argc > 0) {
VALUE opts, uplevel = Qnil;

if (!NIL_P(ruby_verbose) && argc > 0 &&
(argc = rb_scan_args(argc, argv, "*:", NULL, &opts)) > 0) {
VALUE str = argv[0];
if (argc > 1 || !end_with_asciichar(str, '\n')) {
str = rb_str_tmp_new(0);
if (!NIL_P(opts)) {
static ID kwds[1];
if (!kwds[0]) {
CONST_ID(kwds[0], "uplevel");
}
rb_get_kwargs(opts, kwds, 0, 1, &uplevel);
if (uplevel == Qundef) {
uplevel = Qnil;
}
else if (!NIL_P(uplevel)) {
uplevel = LONG2NUM((long)NUM2ULONG(uplevel) + 1);
uplevel = rb_vm_thread_backtrace_locations(1, &uplevel, GET_THREAD()->self);
if (!NIL_P(uplevel)) {
uplevel = rb_ary_entry(uplevel, 0);
}
}
}
if (argc > 1 || !NIL_P(uplevel) || !end_with_asciichar(str, '\n')) {
if (NIL_P(uplevel)) {
str = rb_str_tmp_new(0);
}
else {
VALUE path;
path = rb_funcall(uplevel, rb_intern("path"), 0);
str = rb_sprintf("%s:%li: warning: ",
rb_string_value_ptr(&path),
NUM2LONG(rb_funcall(uplevel, rb_intern("lineno"), 0)));
}
RBASIC_SET_CLASS(str, rb_cWarningBuffer);
rb_io_puts(argc, argv, str);
RBASIC_SET_CLASS(str, rb_cString);
Expand Down
2 changes: 1 addition & 1 deletion lib/cgi/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def nph? #:nodoc:
def _header_for_modruby(buf) #:nodoc:
request = Apache::request
buf.scan(/([^:]+): (.+)#{EOL}/o) do |name, value|
warn sprintf("name:%s value:%s\n", name, value) if $DEBUG
$stderr.puts sprintf("name:%s value:%s\n", name, value) if $DEBUG
case name
when 'Set-Cookie'
request.headers_out.add(name, value)
Expand Down
2 changes: 1 addition & 1 deletion lib/cmath.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ module CMath
atanh
].each do |meth|
define_method(meth + '!') do |*args, &block|
warn("CMath##{meth}! is deprecated; use CMath##{meth} or Math##{meth}") if $VERBOSE
warn("CMath##{meth}! is deprecated; use CMath##{meth} or Math##{meth}", uplevel: 1) if $VERBOSE
RealMath.send(meth, *args, &block)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/delegate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def respond_to_missing?(m, include_private)
target = self.__getobj__ {r = false}
r &&= target.respond_to?(m, include_private)
if r && include_private && !target.respond_to?(m, false)
warn "#{caller(3, 1)[0]}: delegator does not forward private method \##{m}"
warn "delegator does not forward private method \##{m}", uplevel: 3
return false
end
r
Expand Down
2 changes: 1 addition & 1 deletion lib/drb/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ def accept # :nodoc:
end
self.class.new(uri, ssl, @config, true)
rescue OpenSSL::SSL::SSLError
warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
warn("#{$!.message} (#{$!.class})", uplevel: 0) if @config[:verbose]
retry
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/forwardable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def self._delegator_method(obj, accessor, method, ali)
method_call = "#{<<-"begin;"}\n#{<<-"end;".chomp}"
begin;
unless defined? _.#{method}
::Kernel.warn "\#{caller_locations(1)[0]}: "#{mesg.dump}"\#{_.class}"'##{method}'
::Kernel.warn #{mesg.dump}"\#{_.class}"'##{method}', uplevel: 1
_#{method_call}
else
_.#{method}(*args, &block)
Expand Down
4 changes: 2 additions & 2 deletions lib/ipaddr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def ipv4_mapped?

# Returns true if the ipaddr is an IPv4-compatible IPv6 address.
def ipv4_compat?
warn "#{caller(1, 1)[0]}: warning: IPAddr\##{__callee__} is obsolete" if $VERBOSE
warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
_ipv4_compat?
end

Expand All @@ -336,7 +336,7 @@ def ipv4_mapped
# Returns a new ipaddr built by converting the native IPv4 address
# into an IPv4-compatible IPv6 address.
def ipv4_compat
warn "#{caller(1, 1)[0]}: warning: IPAddr\##{__callee__} is obsolete" if $VERBOSE
warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
if !ipv4?
raise InvalidAddressError, "not an IPv4 address"
end
Expand Down
2 changes: 1 addition & 1 deletion lib/irb/init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def IRB.load_modules
begin
require m
rescue LoadError => err
warn err.backtrace[0] << ":#{err.class}: #{err}"
warn ":#{err.class}: #{err}", uplevel: 0
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/irb/locale.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def initialize(locale = nil)
if @encoding_name
begin load 'irb/encoding_aliases.rb'; rescue LoadError; end
if @encoding = @@legacy_encoding_alias_map[@encoding_name]
warn "%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]
warn(("%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]), uplevel: 1)
end
@encoding = Encoding.find(@encoding_name) rescue nil
end
Expand Down
16 changes: 8 additions & 8 deletions lib/matrix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ def determinant_bareiss
# deprecated; use Matrix#determinant
#
def determinant_e
warn "#{caller(1, 1)[0]}: warning: Matrix#determinant_e is deprecated; use #determinant"
warn "Matrix#determinant_e is deprecated; use #determinant", uplevel: 1
determinant
end
alias det_e determinant_e
Expand Down Expand Up @@ -1242,7 +1242,7 @@ def rank
# deprecated; use Matrix#rank
#
def rank_e
warn "#{caller(1, 1)[0]}: warning: Matrix#rank_e is deprecated; use #rank"
warn "Matrix#rank_e is deprecated; use #rank", uplevel: 1
rank
end

Expand Down Expand Up @@ -1435,17 +1435,17 @@ def to_a
end

def elements_to_f
warn "#{caller(1, 1)[0]}: warning: Matrix#elements_to_f is deprecated, use map(&:to_f)"
warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1
map(&:to_f)
end

def elements_to_i
warn "#{caller(1, 1)[0]}: warning: Matrix#elements_to_i is deprecated, use map(&:to_i)"
warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1
map(&:to_i)
end

def elements_to_r
warn "#{caller(1, 1)[0]}: warning: Matrix#elements_to_r is deprecated, use map(&:to_r)"
warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1
map(&:to_r)
end

Expand Down Expand Up @@ -2098,17 +2098,17 @@ def to_matrix
end

def elements_to_f
warn "#{caller(1, 1)[0]}: warning: Vector#elements_to_f is deprecated"
warn "Vector#elements_to_f is deprecated", uplevel: 1
map(&:to_f)
end

def elements_to_i
warn "#{caller(1, 1)[0]}: warning: Vector#elements_to_i is deprecated"
warn "Vector#elements_to_i is deprecated", uplevel: 1
map(&:to_i)
end

def elements_to_r
warn "#{caller(1, 1)[0]}: warning: Vector#elements_to_r is deprecated"
warn "Vector#elements_to_r is deprecated", uplevel: 1
map(&:to_r)
end

Expand Down
4 changes: 2 additions & 2 deletions lib/net/ftp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,13 @@ def with_binary(newmode) # :nodoc:

# Obsolete
def return_code # :nodoc:
$stderr.puts("warning: Net::FTP#return_code is obsolete and do nothing")
warn("Net::FTP#return_code is obsolete and do nothing", uplevel: 1)
return "\n"
end

# Obsolete
def return_code=(s) # :nodoc:
$stderr.puts("warning: Net::FTP#return_code= is obsolete and do nothing")
warn("Net::FTP#return_code= is obsolete and do nothing", uplevel: 1)
end

# Constructs a socket with +host+ and +port+.
Expand Down
2 changes: 1 addition & 1 deletion lib/net/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ def inspect
# http.start { .... }
#
def set_debug_output(output)
warn 'Net::HTTP#set_debug_output called after HTTP started' if started?
warn 'Net::HTTP#set_debug_output called after HTTP started', uplevel: 1 if started?
@debug_output = output
end

Expand Down
4 changes: 2 additions & 2 deletions lib/net/http/generic_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def response_body_permitted?
end

def body_exist?
warn "Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?" if $VERBOSE
warn "Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?", uplevel: 1 if $VERBOSE
response_body_permitted?
end

Expand Down Expand Up @@ -299,7 +299,7 @@ def flush_buffer(out, buf, chunked_p)

def supply_default_content_type
return if content_type()
warn 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
warn 'net/http: Content-Type did not set; using application/x-www-form-urlencoded', uplevel: 1 if $VERBOSE
set_content_type 'application/x-www-form-urlencoded'
end

Expand Down
4 changes: 2 additions & 2 deletions lib/net/http/header.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ def initialize_http_header(initheader)
@header = {}
return unless initheader
initheader.each do |key, value|
warn "net/http: warning: duplicated HTTP header: #{key}" if key?(key) and $VERBOSE
warn "net/http: duplicated HTTP header: #{key}", uplevel: 1 if key?(key) and $VERBOSE
if value.nil?
warn "net/http: warning: nil HTTP header: #{key}" if $VERBOSE
warn "net/http: nil HTTP header: #{key}", uplevel: 1 if $VERBOSE
else
@header[key.downcase] = [value.strip]
end
Expand Down
6 changes: 3 additions & 3 deletions lib/net/http/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,17 @@ def uri= uri # :nodoc:
#

def response #:nodoc:
warn "#{caller(1, 1)[0]}: warning: Net::HTTPResponse#response is obsolete" if $VERBOSE
warn "Net::HTTPResponse#response is obsolete", uplevel: 1 if $VERBOSE
self
end

def header #:nodoc:
warn "#{caller(1, 1)[0]}: warning: Net::HTTPResponse#header is obsolete" if $VERBOSE
warn "Net::HTTPResponse#header is obsolete", uplevel: 1 if $VERBOSE
self
end

def read_header #:nodoc:
warn "#{caller(1, 1)[0]}: warning: Net::HTTPResponse#read_header is obsolete" if $VERBOSE
warn "Net::HTTPResponse#read_header is obsolete", uplevel: 1 if $VERBOSE
self
end

Expand Down
12 changes: 4 additions & 8 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2032,8 +2032,7 @@ def multipart?
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
$stderr.printf("warning: media_subtype is obsolete.\n")
$stderr.printf(" use subtype instead.\n")
warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
Expand All @@ -2060,8 +2059,7 @@ def multipart?
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
$stderr.printf("warning: media_subtype is obsolete.\n")
$stderr.printf(" use subtype instead.\n")
warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
Expand Down Expand Up @@ -2090,8 +2088,7 @@ def multipart?
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
$stderr.printf("warning: media_subtype is obsolete.\n")
$stderr.printf(" use subtype instead.\n")
warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
Expand Down Expand Up @@ -2151,8 +2148,7 @@ def multipart?
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
$stderr.printf("warning: media_subtype is obsolete.\n")
$stderr.printf(" use subtype instead.\n")
warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/ostruct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def modifiable? # :nodoc:
end
private :modifiable?

# ::Kernel.warn("#{caller(1, 1)[0]}: do not use OpenStruct#modifiable")
# ::Kernel.warn("do not use OpenStruct#modifiable", uplevel: 1)
alias modifiable modifiable? # :nodoc:
protected :modifiable

Expand All @@ -181,7 +181,7 @@ def new_ostruct_member!(name) # :nodoc:
end
private :new_ostruct_member!

# ::Kernel.warn("#{caller(1, 1)[0]}: do not use OpenStruct#new_ostruct_member")
# ::Kernel.warn("do not use OpenStruct#new_ostruct_member", uplevel: 1)
alias new_ostruct_member new_ostruct_member! # :nodoc:
protected :new_ostruct_member

Expand Down
2 changes: 1 addition & 1 deletion lib/rexml/cdata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def value
# c = CData.new( " Some text " )
# c.write( $stdout ) #-> <![CDATA[ Some text ]]>
def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
Kernel.warn( "#{self.class.name}.write is deprecated" )
Kernel.warn( "#{self.class.name}.write is deprecated", uplevel: 1)
indent( output, indent )
output << START
output << @string
Expand Down
2 changes: 1 addition & 1 deletion lib/rexml/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def clone
# ie_hack::
# Needed for conformity to the child API, but not used by this class.
def write( output, indent=-1, transitive=false, ie_hack=false )
Kernel.warn("Comment.write is deprecated. See REXML::Formatters")
Kernel.warn("Comment.write is deprecated. See REXML::Formatters", uplevel: 1)
indent( output, indent )
output << START
output << @string
Expand Down
2 changes: 1 addition & 1 deletion lib/rexml/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ def texts
# doc.write( out ) #-> doc is written to the string 'out'
# doc.write( $stdout ) #-> doc written to the console
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters", uplevel: 1)
formatter = if indent > -1
if transitive
require "rexml/formatters/transitive"
Expand Down
2 changes: 1 addition & 1 deletion lib/rexml/instruction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def clone
# See the rexml/formatters package
#
def write writer, indent=-1, transitive=false, ie_hack=false
Kernel.warn( "#{self.class.name}.write is deprecated" )
Kernel.warn( "#{self.class.name}.write is deprecated", uplevel: 1)
indent(writer, indent)
writer << START.sub(/\\/u, '')
writer << @target
Expand Down
2 changes: 1 addition & 1 deletion lib/rexml/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def previous_sibling_node
# REXML::Formatters package for changing the output style.
def to_s indent=nil
unless indent.nil?
Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated" )
Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated", uplevel: 1)
f = REXML::Formatters::Pretty.new( indent )
f.write( self, rv = "" )
else
Expand Down
2 changes: 1 addition & 1 deletion lib/rexml/text.rb
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def indent_text(string, level=1, style="\t", indentfirstline=true)
# See REXML::Formatters
#
def write( writer, indent=-1, transitive=false, ie_hack=false )
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters", uplevel: 1)
formatter = if indent > -1
REXML::Formatters::Pretty.new( indent )
else
Expand Down
5 changes: 2 additions & 3 deletions lib/rss/rss.rb
Original file line number Diff line number Diff line change
Expand Up @@ -596,11 +596,10 @@ def #{accessor_name}(*args)
def #{accessor_name}=(*args)
receiver = self.class.name
warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \
"Don't use `\#{receiver}\##{accessor_name} = XXX'/" \
warn("Don't use `\#{receiver}\##{accessor_name} = XXX'/" \
"`\#{receiver}\#set_#{accessor_name}(XXX)'. " \
"Those APIs are not sense of Ruby. " \
"Use `\#{receiver}\##{plural_name} << XXX' instead of them.")
"Use `\#{receiver}\##{plural_name} << XXX' instead of them.", uplevel: 1)
if args.size == 1
@#{accessor_name}.push(args[0])
else
Expand Down
Loading

0 comments on commit f2a9139

Please sign in to comment.