From 842ae6fde71d3cde4a17ca2405582c6a6cf2a857 Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Thu, 14 Nov 2024 16:12:55 +0200 Subject: [PATCH] Implement rb_str_format C function --- CHANGELOG.md | 1 + lib/cext/include/truffleruby/truffleruby-abi-version.h | 2 +- lib/truffle/truffle/cext.rb | 4 ++++ spec/ruby/optional/capi/ext/kernel_spec.c | 5 +++++ spec/ruby/optional/capi/kernel_spec.rb | 6 ++++++ src/main/c/cext/printf.c | 4 ++++ 6 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78155aead1b..25fdf250fdc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Compatibility: * Implement `rb_hash_bulk_insert()` (#3705, @Th3-M4jor). * Remove deprecated `Pathname#{taint,untaint}` methods (#3681, @andrykonchin). * Add `rb_category_warn` function (#3710, @andrykonchin). +* Implement `rb_str_format()` (#3716, @andrykonchin). Performance: diff --git a/lib/cext/include/truffleruby/truffleruby-abi-version.h b/lib/cext/include/truffleruby/truffleruby-abi-version.h index 8298adea4d1f..755035a3f380 100644 --- a/lib/cext/include/truffleruby/truffleruby-abi-version.h +++ b/lib/cext/include/truffleruby/truffleruby-abi-version.h @@ -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.2" +#define TRUFFLERUBY_ABI_VERSION "3.3.5.3" #endif diff --git a/lib/truffle/truffle/cext.rb b/lib/truffle/truffle/cext.rb index 4c7554fd3722..e337ceb3914e 100644 --- a/lib/truffle/truffle/cext.rb +++ b/lib/truffle/truffle/cext.rb @@ -1416,6 +1416,10 @@ def rb_f_sprintf(args) sprintf(*args) end + def rb_str_format(args, format) + sprintf(format, *args) + end + def rb_io_printf(out, args) out.printf(*args) end diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c index 56448010d8aa..f2ce94bd8914 100644 --- a/spec/ruby/optional/capi/ext/kernel_spec.c +++ b/spec/ruby/optional/capi/ext/kernel_spec.c @@ -332,6 +332,10 @@ static VALUE kernel_spec_rb_f_sprintf(VALUE self, VALUE ary) { return rb_f_sprintf((int)RARRAY_LEN(ary), RARRAY_PTR(ary)); } +static VALUE kernel_spec_rb_str_format(VALUE self, VALUE count, VALUE ary, VALUE format) { + return rb_str_format(FIX2INT(count), RARRAY_PTR(ary), format); +} + static VALUE kernel_spec_rb_make_backtrace(VALUE self) { return rb_make_backtrace(); } @@ -421,6 +425,7 @@ void Init_kernel_spec(void) { rb_define_method(cls, "rb_exec_recursive", kernel_spec_rb_exec_recursive, 1); rb_define_method(cls, "rb_set_end_proc", kernel_spec_rb_set_end_proc, 1); rb_define_method(cls, "rb_f_sprintf", kernel_spec_rb_f_sprintf, 1); + rb_define_method(cls, "rb_str_format", kernel_spec_rb_str_format, 3); rb_define_method(cls, "rb_make_backtrace", kernel_spec_rb_make_backtrace, 0); rb_define_method(cls, "rb_funcallv", kernel_spec_rb_funcallv, 3); #ifdef RUBY_VERSION_IS_3_0 diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb index 50e8b2f3fdc7..43eea07182c9 100644 --- a/spec/ruby/optional/capi/kernel_spec.rb +++ b/spec/ruby/optional/capi/kernel_spec.rb @@ -892,4 +892,10 @@ def obj.method_missing(name, *args) @s.rb_check_funcall(object, :protected_method, []).should == :protected end end + + describe "rb_str_format" do + it "returns a string according to format and arguments" do + @s.rb_str_format(3, [10, 2.5, "test"], "%d %f %s").should == "10 2.500000 test" + end + end end diff --git a/src/main/c/cext/printf.c b/src/main/c/cext/printf.c index ed85ce92dd95..06fccad812aa 100644 --- a/src/main/c/cext/printf.c +++ b/src/main/c/cext/printf.c @@ -183,3 +183,7 @@ VALUE rb_str_vcatf(VALUE str, const char *fmt, va_list args) { rb_str_concat(str, result); return str; } + +VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt) { + return RUBY_CEXT_INVOKE("rb_str_format", rb_ary_new4(argc, argv), fmt); +}