summaryrefslogtreecommitdiffhomepage
path: root/src/numeric.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-05-29 23:41:35 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-05-30 08:15:51 +0900
commit8a4bcc58c92ff921368b3f41a5e234266a11728c (patch)
tree6977fee05e27e35285100973f5b275e72c160826 /src/numeric.c
parent60aa2192a8afc7a2f58196f1667f254832ca8c25 (diff)
downloadmruby-8a4bcc58c92ff921368b3f41a5e234266a11728c.tar.gz
mruby-8a4bcc58c92ff921368b3f41a5e234266a11728c.zip
numeric.c: introduce `mrb_int_to_cstr()` to dump `mrb_int`.
* refactor `mrb_integer_to_str()` * refactor `mrb_str_format()`
Diffstat (limited to 'src/numeric.c')
-rw-r--r--src/numeric.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/src/numeric.c b/src/numeric.c
index fe9995bd4..a344440f4 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -1507,35 +1507,51 @@ int_sub(mrb_state *mrb, mrb_value self)
return int_minus(mrb, self, other);
}
-
-MRB_API mrb_value
-mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
+MRB_API char*
+mrb_int_to_cstr(char *buf, size_t len, mrb_int n, mrb_int base)
{
- char buf[MRB_INT_BIT+1];
- char *b = buf + sizeof buf;
- mrb_int val = mrb_integer(x);
- mrb_value str;
+ char *bufend = buf + len;
+ char *b = bufend-1;
- if (base < 2 || 36 < base) {
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base);
- }
+ if (base < 2 || 36 < base) return NULL;
+ if (len < 2) return NULL;
- if (val == 0) {
- *--b = '0';
+ if (n == 0) {
+ buf[0] = '0';
+ buf[1] = '\0';
+ return buf;
}
- else if (val < 0) {
+
+ *b-- = '\0';
+ if (n < 0) {
do {
- *--b = mrb_digitmap[-(val % base)];
- } while (val /= base);
- *--b = '-';
+ if (b-- == buf) return NULL;
+ *b = mrb_digitmap[-(n % base)];
+ } while (n /= base);
+ if (b-- == buf) return NULL;
+ *b = '-';
}
else {
do {
- *--b = mrb_digitmap[(int)(val % base)];
- } while (val /= base);
+ if (b-- == buf) return NULL;
+ *b = mrb_digitmap[(int)(n % base)];
+ } while (n /= base);
}
+ return b;
+}
+
+MRB_API mrb_value
+mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
+{
+ char buf[MRB_INT_BIT+1];
+ mrb_int val = mrb_integer(x);
- str = mrb_str_new(mrb, b, buf + sizeof(buf) - b);
+ if (base < 2 || 36 < base) {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base);
+ }
+ const char *p = mrb_int_to_cstr(buf, sizeof(buf), val, base);
+ mrb_assert(p != NULL);
+ mrb_value str = mrb_str_new_cstr(mrb, p);
RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
return str;
}