mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
numeric.c: introduce mrb_int_to_cstr() to dump mrb_int.
* refactor `mrb_integer_to_str()` * refactor `mrb_str_format()`
This commit is contained in:
@@ -35,6 +35,7 @@ MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
|
||||
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);
|
||||
|
||||
/* internal function(s) */
|
||||
mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
|
||||
@@ -585,50 +585,6 @@ mrb_f_sprintf(mrb_state *mrb, mrb_value obj)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mrb_int2str(char *buf, size_t len, mrb_int n)
|
||||
{
|
||||
#ifdef MRB_NO_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_NO_STDIO */
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt)
|
||||
{
|
||||
@@ -983,13 +939,10 @@ retry:
|
||||
sc = '-';
|
||||
width--;
|
||||
}
|
||||
mrb_assert(base == 10);
|
||||
mrb_int2str(nbuf, sizeof(nbuf)-1, v);
|
||||
s = nbuf;
|
||||
s = mrb_int_to_cstr(nbuf, sizeof(nbuf), v, base);
|
||||
if (v < 0) s++; /* skip minus sign */
|
||||
}
|
||||
else {
|
||||
s = nbuf;
|
||||
if (v < 0) {
|
||||
dots = 1;
|
||||
val = mrb_fix2binstr(mrb, mrb_int_value(mrb, v), base);
|
||||
@@ -997,7 +950,8 @@ retry:
|
||||
else {
|
||||
val = mrb_integer_to_str(mrb, mrb_int_value(mrb, v), base);
|
||||
}
|
||||
strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-2);
|
||||
strncpy(nbuf+1, RSTRING_PTR(val), sizeof(nbuf)-2);
|
||||
s = nbuf+1;
|
||||
}
|
||||
{
|
||||
size_t size;
|
||||
|
||||
+35
-19
@@ -1507,35 +1507,51 @@ int_sub(mrb_state *mrb, mrb_value self)
|
||||
return int_minus(mrb, self, other);
|
||||
}
|
||||
|
||||
MRB_API char*
|
||||
mrb_int_to_cstr(char *buf, size_t len, mrb_int n, mrb_int base)
|
||||
{
|
||||
char *bufend = buf + len;
|
||||
char *b = bufend-1;
|
||||
|
||||
if (base < 2 || 36 < base) return NULL;
|
||||
if (len < 2) return NULL;
|
||||
|
||||
if (n == 0) {
|
||||
buf[0] = '0';
|
||||
buf[1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
*b-- = '\0';
|
||||
if (n < 0) {
|
||||
do {
|
||||
if (b-- == buf) return NULL;
|
||||
*b = mrb_digitmap[-(n % base)];
|
||||
} while (n /= base);
|
||||
if (b-- == buf) return NULL;
|
||||
*b = '-';
|
||||
}
|
||||
else {
|
||||
do {
|
||||
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];
|
||||
char *b = buf + sizeof buf;
|
||||
mrb_int val = mrb_integer(x);
|
||||
mrb_value str;
|
||||
|
||||
if (base < 2 || 36 < base) {
|
||||
mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base);
|
||||
}
|
||||
|
||||
if (val == 0) {
|
||||
*--b = '0';
|
||||
}
|
||||
else if (val < 0) {
|
||||
do {
|
||||
*--b = mrb_digitmap[-(val % base)];
|
||||
} while (val /= base);
|
||||
*--b = '-';
|
||||
}
|
||||
else {
|
||||
do {
|
||||
*--b = mrb_digitmap[(int)(val % base)];
|
||||
} while (val /= base);
|
||||
}
|
||||
|
||||
str = mrb_str_new(mrb, b, buf + sizeof(buf) - b);
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user