From 5e5ee841a1c6aee13c7683b233c26d7db79f9c2f Mon Sep 17 00:00:00 2001 From: chasonr Date: Wed, 26 Feb 2014 20:18:26 -0500 Subject: Implement sprintf("%c") for UTF-8. * sprintf("%c") is changed to accept a string for which String#size returns 1, even if it is longer than one byte, and to convert a Fixnum via Fixnum#chr (possibly returning more than one byte). Thus, if the UTF-8 gem is in use, a character will be understood as a single UTF-8 character. * The change to sprintf depends on the implementation of Fixnum#chr added to mrbgems/mruby-string-utf8/src/string.c. This should work with any other gem that implements a multibyte encoding, as long as it implements String#size and Fixnum#chr as appropriate. --- mrbgems/mruby-sprintf/src/sprintf.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'mrbgems/mruby-sprintf/src') diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index b20cbe1df..5b255d28e 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -666,38 +666,37 @@ retry: case 'c': { mrb_value val = GETARG(); mrb_value tmp; - unsigned int c; + char *c; tmp = mrb_check_string_type(mrb, val); if (!mrb_nil_p(tmp)) { - if (RSTRING_LEN(tmp) != 1 ) { + if (mrb_fixnum(mrb_funcall(mrb, tmp, "size", 0)) != 1 ) { mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character"); } - c = RSTRING_PTR(tmp)[0]; - n = 1; } - else { - c = mrb_fixnum(val); - n = 1; + else if (mrb_fixnum_p(val)) { + tmp = mrb_funcall(mrb, val, "chr", 0); } - if (n <= 0) { + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); } + c = RSTRING_PTR(tmp); + n = RSTRING_LEN(tmp); if (!(flags & FWIDTH)) { CHECK(n); - buf[blen] = c; + memcpy(buf+blen, c, n); blen += n; } else if ((flags & FMINUS)) { CHECK(n); - buf[blen] = c; + memcpy(buf+blen, c, n); blen += n; FILL(' ', width-1); } else { FILL(' ', width-1); CHECK(n); - buf[blen] = c; + memcpy(buf+blen, c, n); blen += n; } } -- cgit v1.2.3