diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-05-22 14:16:55 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-05-22 14:16:55 +0900 |
| commit | 5c7fe225a6d675f3e213f8792f116035a35c63a4 (patch) | |
| tree | dffa11b3f82bb6d516b7f0eb710e9b97e08d07bc /mrbgems/mruby-sprintf | |
| parent | 328563995f7c817fc4ec1e92ffcadfde101ced06 (diff) | |
| download | mruby-5c7fe225a6d675f3e213f8792f116035a35c63a4.tar.gz mruby-5c7fe225a6d675f3e213f8792f116035a35c63a4.zip | |
fp_fmt.c: remove `mrb_float_to_cstr()`.
The function was intended to be a utility function for `mruby-sprintf`.
The functionality was integrated into `sprintf.c`.
Diffstat (limited to 'mrbgems/mruby-sprintf')
| -rw-r--r-- | mrbgems/mruby-sprintf/src/sprintf.c | 83 |
1 files changed, 47 insertions, 36 deletions
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index de8dbc513..2e6cec803 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -21,9 +21,6 @@ #define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n))) mrb_value mrb_str_format(mrb_state *, mrb_int, const mrb_value *, mrb_value); -#ifndef MRB_NO_FLOAT -static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int); -#endif static char* remove_sign_bits(char *str, int base) @@ -133,7 +130,52 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) #define FPREC 64 #define FPREC0 128 -#define CHECK(l) do {\ +#ifndef MRB_NO_FLOAT +static int +fmt_float(char *buf, size_t buf_size, char fmt, int flags, mrb_int width, mrb_int prec, mrb_float f) +{ + char sign = '\0'; + int left_align = 0; + int zero_pad = 0; + + if (flags & FSHARP) fmt |= 0x80; + if (flags & FPLUS) sign = '+'; + if (flags & FMINUS) left_align = 1; + if (flags & FZERO) zero_pad = 1; + if (flags & FSPACE) sign = ' '; + + int len = mrb_format_float(f, buf, buf_size, fmt, prec, sign); + + // buf[0] < '0' returns true if the first character is space, + or - + // buf[1] < '9' matches a digit, and doesn't match when we get back +nan or +inf + if (buf[0] < '0' && buf[1] <= '9' && zero_pad) { + buf++; + width--; + len--; + } + if (*buf < '0' || *buf >= '9') { + // For inf or nan, we don't want to zero pad. + zero_pad = 0; + } + if (len >= width) { + return len; + } + buf[width] = '\0'; + if (left_align) { + memset(&buf[len], ' ', width - len); + return width; + } + memmove(&buf[width - len], buf, len); + if (zero_pad) { + memset(buf, '0', width - len); + } else { + memset(buf, ' ', width - len); + } + return width; +} +#endif + +#define CHECK(l) do { \ while ((l) >= bsiz - blen) {\ if (bsiz > MRB_INT_MAX/2) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \ bsiz*=2;\ @@ -1052,7 +1094,6 @@ retry: mrb_value val = GETARG(); double fval; mrb_int need = 6; - char fbuf[64]; fval = mrb_as_float(mrb, val); if (!isfinite(fval)) { @@ -1114,8 +1155,7 @@ retry: need += 20; CHECK(need); - fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec); - n = mrb_float_to_cstr(mrb, &buf[blen], need, fbuf, fval); + n = fmt_float(&buf[blen], need, *p, flags, width, prec, fval); if (n < 0 || n >= need) { mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); } @@ -1142,35 +1182,6 @@ retry: return result; } -#ifndef MRB_NO_FLOAT -static void -fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec) -{ - char *end = buf + size; - int n; - - *buf++ = '%'; - if (flags & FSHARP) *buf++ = '#'; - if (flags & FPLUS) *buf++ = '+'; - if (flags & FMINUS) *buf++ = '-'; - if (flags & FZERO) *buf++ = '0'; - if (flags & FSPACE) *buf++ = ' '; - - if (flags & FWIDTH) { - n = mrb_int2str(buf, end - buf, width); - buf += n; - } - - if (flags & FPREC) { - *buf ++ = '.'; - n = mrb_int2str(buf, end - buf, prec); - buf += n; - } - - *buf++ = c; - *buf = '\0'; -} -#endif void mrb_mruby_sprintf_gem_init(mrb_state *mrb) |
