Commit 191ccbf6 authored by dearblue's avatar dearblue

Support `MRB_DISABLE_STDIO` for mruby-sprintf; ref #4954

parent d9832699
...@@ -5,11 +5,6 @@ ...@@ -5,11 +5,6 @@
*/ */
#include <mruby.h> #include <mruby.h>
#ifdef MRB_DISABLE_STDIO
# error sprintf conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
#endif
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <mruby/string.h> #include <mruby/string.h>
...@@ -521,6 +516,50 @@ mrb_f_sprintf(mrb_state *mrb, mrb_value obj) ...@@ -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_value
mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt) mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt)
{ {
...@@ -869,7 +908,7 @@ retry: ...@@ -869,7 +908,7 @@ retry:
width--; width--;
} }
mrb_assert(base == 10); mrb_assert(base == 10);
snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); mrb_int2str(nbuf, sizeof(nbuf), v);
s = nbuf; s = nbuf;
if (v < 0) s++; /* skip minus sign */ if (v < 0) s++; /* skip minus sign */
} }
...@@ -877,24 +916,12 @@ retry: ...@@ -877,24 +916,12 @@ retry:
s = nbuf; s = nbuf;
if (v < 0) { if (v < 0) {
dots = 1; dots = 1;
}
switch (base) {
case 2:
if (v < 0) {
val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
} }
else { else {
val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
} }
strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); 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;
}
if (v < 0) { if (v < 0) {
char d; char d;
...@@ -1071,7 +1098,7 @@ retry: ...@@ -1071,7 +1098,7 @@ retry:
need += 20; need += 20;
CHECK(need); 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) { if (n < 0 || n >= need) {
mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); 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) ...@@ -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 & FSPACE) *buf++ = ' ';
if (flags & FWIDTH) { if (flags & FWIDTH) {
n = snprintf(buf, end - buf, "%d", (int)width); n = mrb_int2str(buf, end - buf, width);
buf += n; buf += n;
} }
if (flags & FPREC) { if (flags & FPREC) {
n = snprintf(buf, end - buf, ".%d", (int)prec); *buf ++ = '.';
n = mrb_int2str(buf, end - buf, prec);
buf += n; buf += n;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment