summaryrefslogtreecommitdiff
path: root/sprintf.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2022-08-17 17:39:40 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2022-08-17 17:40:59 +0900
commitddb81b9307f7114fcb37f6fcc37b7692b1a40cb4 (patch)
tree8dda8bf221c258b2e8c971516e002c0cc4d6e499 /sprintf.c
parent72adee6e36249b39460913ce54ca9296bea80225 (diff)
Extract common code from `rb_enc_vsprintf` and `rb_str_vcatf`
Diffstat (limited to 'sprintf.c')
-rw-r--r--sprintf.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/sprintf.c b/sprintf.c
index 09b9bf15d2..2b2b34b5b4 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -1145,35 +1145,44 @@ ruby__sfvextra(rb_printf_buffer *fp, size_t valsize, void *valp, long *sz, int s
return cp;
}
-VALUE
-rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
+static void
+ruby_vsprintf0(VALUE result, char *p, const char *fmt, va_list ap)
{
rb_printf_buffer_extra buffer;
#define f buffer.base
- VALUE result;
+ VALUE klass = RBASIC(result)->klass;
f._flags = __SWR | __SSTR;
f._bf._size = 0;
- f._w = 120;
- result = rb_str_buf_new(f._w);
- if (enc) {
- if (rb_enc_mbminlen(enc) > 1) {
- /* the implementation deeply depends on plain char */
- rb_raise(rb_eArgError, "cannot construct wchar_t based encoding string: %s",
- rb_enc_name(enc));
- }
- rb_enc_associate(result, enc);
- }
+ f._w = rb_str_capacity(result);
f._bf._base = (unsigned char *)result;
- f._p = (unsigned char *)RSTRING_PTR(result);
+ f._p = (unsigned char *)p;
RBASIC_CLEAR_CLASS(result);
f.vwrite = ruby__sfvwrite;
f.vextra = ruby__sfvextra;
buffer.value = 0;
BSD_vfprintf(&f, fmt, ap);
- RBASIC_SET_CLASS_RAW(result, rb_cString);
+ RBASIC_SET_CLASS_RAW(result, klass);
rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
#undef f
+}
+
+VALUE
+rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
+{
+ const int initial_len = 120;
+ VALUE result;
+
+ result = rb_str_buf_new(initial_len);
+ if (enc) {
+ if (rb_enc_mbminlen(enc) > 1) {
+ /* the implementation deeply depends on plain char */
+ rb_raise(rb_eArgError, "cannot construct wchar_t based encoding string: %s",
+ rb_enc_name(enc));
+ }
+ rb_enc_associate(result, enc);
+ }
+ ruby_vsprintf0(result, RSTRING_PTR(result), fmt, ap);
return result;
}
@@ -1213,26 +1222,9 @@ rb_sprintf(const char *format, ...)
VALUE
rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
{
- rb_printf_buffer_extra buffer;
-#define f buffer.base
- VALUE klass;
-
StringValue(str);
rb_str_modify(str);
- f._flags = __SWR | __SSTR;
- f._bf._size = 0;
- f._w = rb_str_capacity(str);
- f._bf._base = (unsigned char *)str;
- f._p = (unsigned char *)RSTRING_END(str);
- klass = RBASIC(str)->klass;
- RBASIC_CLEAR_CLASS(str);
- f.vwrite = ruby__sfvwrite;
- f.vextra = ruby__sfvextra;
- buffer.value = 0;
- BSD_vfprintf(&f, fmt, ap);
- RBASIC_SET_CLASS_RAW(str, klass);
- rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
-#undef f
+ ruby_vsprintf0(str, RSTRING_END(str), fmt, ap);
return str;
}