summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-sprintf
diff options
context:
space:
mode:
authordearblue <[email protected]>2020-04-11 20:30:54 +0900
committerdearblue <[email protected]>2020-04-11 22:11:24 +0900
commit191ccbf660b80016c554d9b2d71ba9f0bc6429d8 (patch)
tree7f570ab1a9241713b0f20a888c7c8280f3e77ae6 /mrbgems/mruby-sprintf
parentd9832699085d60e21002e4ba76e3e3fd0480d9e8 (diff)
downloadmruby-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.c78
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;
}