Skip to content

Commit

Permalink
[GR-18163] Implement rb_category_warn C function
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/4397
  • Loading branch information
andrykonchin committed Nov 13, 2024
2 parents 78dd425 + 95e39c8 commit 8f5a822
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Compatibility:
* Implement `rb_enc_interned_str()` (#3703, @Th3-M4jor).
* Implement `rb_hash_bulk_insert()` (#3705, @Th3-M4jor).
* Remove deprecated `Pathname#{taint,untaint}` methods (#3681, @andrykonchin).
* Add `rb_category_warn` function (#3710, @andrykonchin).

Performance:

Expand Down
2 changes: 1 addition & 1 deletion lib/cext/ABI_check.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2
3
16 changes: 16 additions & 0 deletions lib/cext/include/ruby/internal/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,11 @@ static inline void rb_warn(const char *fmt, ...) {
void rb_warn(const char *fmt, ...);
#endif

#ifdef TRUFFLERUBY
bool rb_warning_category_enabled_p(rb_warning_category_t category);
void rb_tr_category_warn_va_list(rb_warning_category_t category, const char *fmt, va_list args);
#endif

RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
Expand All @@ -616,7 +621,18 @@ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
* @param[in] cat Category e.g. deprecated.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
#ifdef TRUFFLERUBY
static inline void rb_category_warn(rb_warning_category_t category, const char *fmt, ...) {
if (!NIL_P(ruby_verbose) && rb_warning_category_enabled_p(category)) {
va_list args;
va_start(args, fmt);
rb_tr_category_warn_va_list(category, fmt, args);
va_end(args);
}
}
#else
void rb_category_warn(rb_warning_category_t cat, const char *fmt, ...);
#endif

RBIMPL_ATTR_NONNULL((1, 3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
Expand Down
2 changes: 1 addition & 1 deletion lib/cext/include/truffleruby/truffleruby-abi-version.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
// $RUBY_VERSION must be the same as TruffleRuby.LANGUAGE_VERSION.
// $ABI_NUMBER starts at 1 and is incremented for every ABI-incompatible change.

#define TRUFFLERUBY_ABI_VERSION "3.3.5.1"
#define TRUFFLERUBY_ABI_VERSION "3.3.5.2"

#endif
12 changes: 12 additions & 0 deletions lib/truffle/truffle/cext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2319,10 +2319,22 @@ def rb_eval_cmd_kw(cmd, args, kw_splat)
end
end

def rb_tr_warn(message)
location = caller_locations(1, 1)[0]
message_with_prefix = location.label + ': warning: ' + message
Warning.warn(message_with_prefix)
end

def rb_warning_category_enabled_p(category)
Warning[category]
end

def rb_tr_warn_category(message, category)
location = caller_locations(1, 1)[0]
message_with_prefix = location.label + ': warning: ' + message
Warning.warn(message_with_prefix, category: category)
end

def rb_tr_flags(object)
Truffle::CExt::RBasic.new(object).compute_flags
end
Expand Down
13 changes: 12 additions & 1 deletion spec/ruby/optional/capi/ext/kernel_spec.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,20 @@ VALUE kernel_spec_rb_block_call_no_func(VALUE self, VALUE ary) {
return rb_block_call(ary, rb_intern("map"), 0, NULL, (rb_block_call_func_t)NULL, Qnil);
}


VALUE kernel_spec_rb_frame_this_func(VALUE self) {
return ID2SYM(rb_frame_this_func());
}

VALUE kernel_spec_rb_category_warn_deprecated(VALUE self) {
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "foo");
return Qnil;
}

VALUE kernel_spec_rb_category_warn_deprecated_with_integer_extra_value(VALUE self, VALUE value) {
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "foo %d", FIX2INT(value));
return Qnil;
}

VALUE kernel_spec_rb_ensure(VALUE self, VALUE main_proc, VALUE arg,
VALUE ensure_proc, VALUE arg2) {
VALUE main_array, ensure_array;
Expand Down Expand Up @@ -381,6 +390,8 @@ void Init_kernel_spec(void) {
rb_define_method(cls, "rb_block_lambda", kernel_spec_rb_block_lambda, 0);
rb_define_method(cls, "rb_frame_this_func_test", kernel_spec_rb_frame_this_func, 0);
rb_define_method(cls, "rb_frame_this_func_test_again", kernel_spec_rb_frame_this_func, 0);
rb_define_method(cls, "rb_category_warn_deprecated", kernel_spec_rb_category_warn_deprecated, 0);
rb_define_method(cls, "rb_category_warn_deprecated_with_integer_extra_value", kernel_spec_rb_category_warn_deprecated_with_integer_extra_value, 1);
rb_define_method(cls, "rb_ensure", kernel_spec_rb_ensure, 4);
rb_define_method(cls, "rb_eval_string", kernel_spec_rb_eval_string, 1);
rb_define_method(cls, "rb_eval_cmd_kw", kernel_spec_rb_eval_cmd_kw, 3);
Expand Down
56 changes: 40 additions & 16 deletions spec/ruby/optional/capi/kernel_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,26 +156,16 @@ class CApiKernelSpecs::Exc < StandardError
end

describe "rb_warn" do
before :each do
@stderr, $stderr = $stderr, IOStub.new
@verbose = $VERBOSE
end

after :each do
$stderr = @stderr
$VERBOSE = @verbose
end

it "prints a message to $stderr if $VERBOSE evaluates to true" do
$VERBOSE = true
@s.rb_warn("This is a warning")
$stderr.should =~ /This is a warning/
-> {
@s.rb_warn("This is a warning")
}.should complain(/warning: This is a warning/, verbose: true)
end

it "prints a message to $stderr if $VERBOSE evaluates to false" do
$VERBOSE = false
@s.rb_warn("This is a warning")
$stderr.should =~ /This is a warning/
-> {
@s.rb_warn("This is a warning")
}.should complain(/warning: This is a warning/, verbose: false)
end
end

Expand Down Expand Up @@ -530,6 +520,40 @@ def proc_caller
end
end

describe "rb_category_warn" do
it "emits a warning into stderr" do
Warning[:deprecated] = true

-> {
@s.rb_category_warn_deprecated
}.should complain(/warning: foo/, verbose: true)
end

it "supports printf format modifiers" do
Warning[:deprecated] = true

-> {
@s.rb_category_warn_deprecated_with_integer_extra_value(42)
}.should complain(/warning: foo 42/, verbose: true)
end

it "does not emits a warning when a category is disabled" do
Warning[:deprecated] = false

-> {
@s.rb_category_warn_deprecated
}.should_not complain(verbose: true)
end

it "does not emits a warning when $VERBOSE is nil" do
Warning[:deprecated] = true

-> {
@s.rb_category_warn_deprecated
}.should_not complain(verbose: nil)
end
end

describe "rb_ensure" do
it "executes passed function and returns its value" do
proc = -> x { x }
Expand Down
1 change: 1 addition & 0 deletions spec/truffle/capi/error_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

load_extension("error")

# C functions defined in CRuby internal headers, so they don't belong to the public API.
describe "C-API error functions" do
before :each do
@e = CApiErrorSpecs.new
Expand Down
20 changes: 18 additions & 2 deletions src/main/c/cext/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
#include <truffleruby-impl.h>

bool rb_warning_category_enabled_p(rb_warning_category_t category) {
VALUE rb_tr_warning_category_to_name(rb_warning_category_t category) {
VALUE category_name;

switch (category) {
Expand All @@ -23,9 +23,25 @@ bool rb_warning_category_enabled_p(rb_warning_category_t category) {
category_name = Qnil;
}

return category_name;
}

void rb_tr_category_warn_va_list(rb_warning_category_t category, const char *fmt, va_list args) {
VALUE message, category_name;

message = rb_vsprintf(fmt, args);
category_name = rb_tr_warning_category_to_name(category);
RUBY_CEXT_INVOKE("rb_tr_warn_category", message, category_name);
}

bool rb_warning_category_enabled_p(rb_warning_category_t category) {
VALUE category_name;

category_name = rb_tr_warning_category_to_name(category);

if (category_name != Qnil) {
return polyglot_as_boolean(RUBY_CEXT_INVOKE_NO_WRAP("rb_warning_category_enabled_p", category_name));
} else {
return Qtrue;
return true;
}
}
2 changes: 1 addition & 1 deletion src/main/c/cext/truffleruby.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ int rb_tr_obj_equal(VALUE first, VALUE second) {
}

void rb_tr_warn_va_list(const char *fmt, va_list args) {
RUBY_INVOKE(rb_mKernel, "warn", rb_vsprintf(fmt, args));
RUBY_CEXT_INVOKE("rb_tr_warn", rb_vsprintf(fmt, args));
}

VALUE rb_tr_zlib_crc_table(void) {
Expand Down

0 comments on commit 8f5a822

Please sign in to comment.