Skip to content

Commit 8f5a822

Browse files
committed
[GR-18163] Implement rb_category_warn C function
PullRequest: truffleruby/4397
2 parents 78dd425 + 95e39c8 commit 8f5a822

File tree

10 files changed

+103
-22
lines changed

10 files changed

+103
-22
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Compatibility:
2323
* Implement `rb_enc_interned_str()` (#3703, @Th3-M4jor).
2424
* Implement `rb_hash_bulk_insert()` (#3705, @Th3-M4jor).
2525
* Remove deprecated `Pathname#{taint,untaint}` methods (#3681, @andrykonchin).
26+
* Add `rb_category_warn` function (#3710, @andrykonchin).
2627

2728
Performance:
2829

lib/cext/ABI_check.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2
1+
3

lib/cext/include/ruby/internal/error.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,11 @@ static inline void rb_warn(const char *fmt, ...) {
607607
void rb_warn(const char *fmt, ...);
608608
#endif
609609

610+
#ifdef TRUFFLERUBY
611+
bool rb_warning_category_enabled_p(rb_warning_category_t category);
612+
void rb_tr_category_warn_va_list(rb_warning_category_t category, const char *fmt, va_list args);
613+
#endif
614+
610615
RBIMPL_ATTR_COLD()
611616
RBIMPL_ATTR_NONNULL((2))
612617
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
@@ -616,7 +621,18 @@ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
616621
* @param[in] cat Category e.g. deprecated.
617622
* @param[in] fmt Format specifier string compatible with rb_sprintf().
618623
*/
624+
#ifdef TRUFFLERUBY
625+
static inline void rb_category_warn(rb_warning_category_t category, const char *fmt, ...) {
626+
if (!NIL_P(ruby_verbose) && rb_warning_category_enabled_p(category)) {
627+
va_list args;
628+
va_start(args, fmt);
629+
rb_tr_category_warn_va_list(category, fmt, args);
630+
va_end(args);
631+
}
632+
}
633+
#else
619634
void rb_category_warn(rb_warning_category_t cat, const char *fmt, ...);
635+
#endif
620636

621637
RBIMPL_ATTR_NONNULL((1, 3))
622638
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)

lib/cext/include/truffleruby/truffleruby-abi-version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
// $RUBY_VERSION must be the same as TruffleRuby.LANGUAGE_VERSION.
2121
// $ABI_NUMBER starts at 1 and is incremented for every ABI-incompatible change.
2222

23-
#define TRUFFLERUBY_ABI_VERSION "3.3.5.1"
23+
#define TRUFFLERUBY_ABI_VERSION "3.3.5.2"
2424

2525
#endif

lib/truffle/truffle/cext.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,10 +2319,22 @@ def rb_eval_cmd_kw(cmd, args, kw_splat)
23192319
end
23202320
end
23212321

2322+
def rb_tr_warn(message)
2323+
location = caller_locations(1, 1)[0]
2324+
message_with_prefix = location.label + ': warning: ' + message
2325+
Warning.warn(message_with_prefix)
2326+
end
2327+
23222328
def rb_warning_category_enabled_p(category)
23232329
Warning[category]
23242330
end
23252331

2332+
def rb_tr_warn_category(message, category)
2333+
location = caller_locations(1, 1)[0]
2334+
message_with_prefix = location.label + ': warning: ' + message
2335+
Warning.warn(message_with_prefix, category: category)
2336+
end
2337+
23262338
def rb_tr_flags(object)
23272339
Truffle::CExt::RBasic.new(object).compute_flags
23282340
end

spec/ruby/optional/capi/ext/kernel_spec.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,20 @@ VALUE kernel_spec_rb_block_call_no_func(VALUE self, VALUE ary) {
6767
return rb_block_call(ary, rb_intern("map"), 0, NULL, (rb_block_call_func_t)NULL, Qnil);
6868
}
6969

70-
7170
VALUE kernel_spec_rb_frame_this_func(VALUE self) {
7271
return ID2SYM(rb_frame_this_func());
7372
}
7473

74+
VALUE kernel_spec_rb_category_warn_deprecated(VALUE self) {
75+
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "foo");
76+
return Qnil;
77+
}
78+
79+
VALUE kernel_spec_rb_category_warn_deprecated_with_integer_extra_value(VALUE self, VALUE value) {
80+
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "foo %d", FIX2INT(value));
81+
return Qnil;
82+
}
83+
7584
VALUE kernel_spec_rb_ensure(VALUE self, VALUE main_proc, VALUE arg,
7685
VALUE ensure_proc, VALUE arg2) {
7786
VALUE main_array, ensure_array;
@@ -381,6 +390,8 @@ void Init_kernel_spec(void) {
381390
rb_define_method(cls, "rb_block_lambda", kernel_spec_rb_block_lambda, 0);
382391
rb_define_method(cls, "rb_frame_this_func_test", kernel_spec_rb_frame_this_func, 0);
383392
rb_define_method(cls, "rb_frame_this_func_test_again", kernel_spec_rb_frame_this_func, 0);
393+
rb_define_method(cls, "rb_category_warn_deprecated", kernel_spec_rb_category_warn_deprecated, 0);
394+
rb_define_method(cls, "rb_category_warn_deprecated_with_integer_extra_value", kernel_spec_rb_category_warn_deprecated_with_integer_extra_value, 1);
384395
rb_define_method(cls, "rb_ensure", kernel_spec_rb_ensure, 4);
385396
rb_define_method(cls, "rb_eval_string", kernel_spec_rb_eval_string, 1);
386397
rb_define_method(cls, "rb_eval_cmd_kw", kernel_spec_rb_eval_cmd_kw, 3);

spec/ruby/optional/capi/kernel_spec.rb

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -156,26 +156,16 @@ class CApiKernelSpecs::Exc < StandardError
156156
end
157157

158158
describe "rb_warn" do
159-
before :each do
160-
@stderr, $stderr = $stderr, IOStub.new
161-
@verbose = $VERBOSE
162-
end
163-
164-
after :each do
165-
$stderr = @stderr
166-
$VERBOSE = @verbose
167-
end
168-
169159
it "prints a message to $stderr if $VERBOSE evaluates to true" do
170-
$VERBOSE = true
171-
@s.rb_warn("This is a warning")
172-
$stderr.should =~ /This is a warning/
160+
-> {
161+
@s.rb_warn("This is a warning")
162+
}.should complain(/warning: This is a warning/, verbose: true)
173163
end
174164

175165
it "prints a message to $stderr if $VERBOSE evaluates to false" do
176-
$VERBOSE = false
177-
@s.rb_warn("This is a warning")
178-
$stderr.should =~ /This is a warning/
166+
-> {
167+
@s.rb_warn("This is a warning")
168+
}.should complain(/warning: This is a warning/, verbose: false)
179169
end
180170
end
181171

@@ -530,6 +520,40 @@ def proc_caller
530520
end
531521
end
532522

523+
describe "rb_category_warn" do
524+
it "emits a warning into stderr" do
525+
Warning[:deprecated] = true
526+
527+
-> {
528+
@s.rb_category_warn_deprecated
529+
}.should complain(/warning: foo/, verbose: true)
530+
end
531+
532+
it "supports printf format modifiers" do
533+
Warning[:deprecated] = true
534+
535+
-> {
536+
@s.rb_category_warn_deprecated_with_integer_extra_value(42)
537+
}.should complain(/warning: foo 42/, verbose: true)
538+
end
539+
540+
it "does not emits a warning when a category is disabled" do
541+
Warning[:deprecated] = false
542+
543+
-> {
544+
@s.rb_category_warn_deprecated
545+
}.should_not complain(verbose: true)
546+
end
547+
548+
it "does not emits a warning when $VERBOSE is nil" do
549+
Warning[:deprecated] = true
550+
551+
-> {
552+
@s.rb_category_warn_deprecated
553+
}.should_not complain(verbose: nil)
554+
end
555+
end
556+
533557
describe "rb_ensure" do
534558
it "executes passed function and returns its value" do
535559
proc = -> x { x }

spec/truffle/capi/error_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
load_extension("error")
1212

13+
# C functions defined in CRuby internal headers, so they don't belong to the public API.
1314
describe "C-API error functions" do
1415
before :each do
1516
@e = CApiErrorSpecs.new

src/main/c/cext/error.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
#include <truffleruby-impl.h>
1111

12-
bool rb_warning_category_enabled_p(rb_warning_category_t category) {
12+
VALUE rb_tr_warning_category_to_name(rb_warning_category_t category) {
1313
VALUE category_name;
1414

1515
switch (category) {
@@ -23,9 +23,25 @@ bool rb_warning_category_enabled_p(rb_warning_category_t category) {
2323
category_name = Qnil;
2424
}
2525

26+
return category_name;
27+
}
28+
29+
void rb_tr_category_warn_va_list(rb_warning_category_t category, const char *fmt, va_list args) {
30+
VALUE message, category_name;
31+
32+
message = rb_vsprintf(fmt, args);
33+
category_name = rb_tr_warning_category_to_name(category);
34+
RUBY_CEXT_INVOKE("rb_tr_warn_category", message, category_name);
35+
}
36+
37+
bool rb_warning_category_enabled_p(rb_warning_category_t category) {
38+
VALUE category_name;
39+
40+
category_name = rb_tr_warning_category_to_name(category);
41+
2642
if (category_name != Qnil) {
2743
return polyglot_as_boolean(RUBY_CEXT_INVOKE_NO_WRAP("rb_warning_category_enabled_p", category_name));
2844
} else {
29-
return Qtrue;
45+
return true;
3046
}
3147
}

src/main/c/cext/truffleruby.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ int rb_tr_obj_equal(VALUE first, VALUE second) {
3535
}
3636

3737
void rb_tr_warn_va_list(const char *fmt, va_list args) {
38-
RUBY_INVOKE(rb_mKernel, "warn", rb_vsprintf(fmt, args));
38+
RUBY_CEXT_INVOKE("rb_tr_warn", rb_vsprintf(fmt, args));
3939
}
4040

4141
VALUE rb_tr_zlib_crc_table(void) {

0 commit comments

Comments
 (0)