diff options
| author | dearblue <[email protected]> | 2020-04-11 20:30:54 +0900 |
|---|---|---|
| committer | dearblue <[email protected]> | 2020-04-11 22:11:24 +0900 |
| commit | 191ccbf660b80016c554d9b2d71ba9f0bc6429d8 (patch) | |
| tree | 7f570ab1a9241713b0f20a888c7c8280f3e77ae6 /mrbgems/mruby-sprintf | |
| parent | d9832699085d60e21002e4ba76e3e3fd0480d9e8 (diff) | |
| download | mruby-191ccbf660b80016c554d9b2d71ba9f0bc6429d8.tar.gz mruby-191ccbf660b80016c554d9b2d71ba9f0bc6429d8.zip | |
Support `MRB_DISABLE_STDIO` for mruby-sprintf; ref #4954
Diffstat (limited to 'mrbgems/mruby-sprintf')
| -rw-r--r-- | mrbgems/mruby-sprintf/src/sprintf.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 558d57173..987ec711f 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -5,11 +5,6 @@ */ #include <mruby.h> - -#ifdef MRB_DISABLE_STDIO -# error sprintf conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' -#endif - #include <limits.h> #include <string.h> #include <mruby/string.h> @@ -521,6 +516,50 @@ mrb_f_sprintf(mrb_state *mrb, mrb_value obj) } } +static int +mrb_int2str(char *buf, size_t len, mrb_int n) +{ +#ifdef MRB_DISABLE_STDIO + char *bufend = buf + len; + char *p = bufend - 1; + + if (len < 1) return -1; + + *p -- = '\0'; + len --; + + if (n < 0) { + if (len < 1) return -1; + + *p -- = '-'; + len --; + n = -n; + } + + if (n > 0) { + for (; n > 0; len --, n /= 10) { + if (len < 1) return -1; + + *p -- = '0' + (n % 10); + } + p ++; + } + else if (len > 0) { + *p = '0'; + len --; + } + else { + return -1; + } + + memmove(buf, p, bufend - p); + + return bufend - p - 1; +#else + return snprintf(buf, len, "%" MRB_PRId, n); +#endif /* MRB_DISABLE_STDIO */ +} + mrb_value mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt) { @@ -869,7 +908,7 @@ retry: width--; } mrb_assert(base == 10); - snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); + mrb_int2str(nbuf, sizeof(nbuf), v); s = nbuf; if (v < 0) s++; /* skip minus sign */ } @@ -877,24 +916,12 @@ retry: s = nbuf; if (v < 0) { dots = 1; + val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); } - switch (base) { - case 2: - if (v < 0) { - val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); - } - else { - val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); - } - strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); - break; - case 8: - snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v); - break; - case 16: - snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v); - break; + else { + val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); } + strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); if (v < 0) { char d; @@ -1071,7 +1098,7 @@ retry: need += 20; CHECK(need); - n = snprintf(&buf[blen], need, fbuf, fval); + n = mrb_float_to_cstr(mrb, &buf[blen], need, fbuf, fval); if (n < 0 || n >= need) { mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); } @@ -1113,12 +1140,13 @@ fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec) if (flags & FSPACE) *buf++ = ' '; if (flags & FWIDTH) { - n = snprintf(buf, end - buf, "%d", (int)width); + n = mrb_int2str(buf, end - buf, width); buf += n; } if (flags & FPREC) { - n = snprintf(buf, end - buf, ".%d", (int)prec); + *buf ++ = '.'; + n = mrb_int2str(buf, end - buf, prec); buf += n; } |
