mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
allow underscores in integer literals; close #1960
This commit is contained in:
+25
-8
@@ -1952,10 +1952,10 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
|
||||
mrb_value
|
||||
mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
|
||||
{
|
||||
char *end;
|
||||
const char *p;
|
||||
char sign = 1;
|
||||
int c;
|
||||
unsigned long n;
|
||||
int c, us;
|
||||
unsigned long n = 0;
|
||||
mrb_int val;
|
||||
|
||||
#undef ISDIGIT
|
||||
@@ -2042,7 +2042,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
|
||||
break;
|
||||
} /* end of switch (base) { */
|
||||
if (*str == '0') { /* squeeze preceeding 0s */
|
||||
int us = 0;
|
||||
us = 0;
|
||||
while ((c = *++str) == '0' || c == '_') {
|
||||
if (c == '_') {
|
||||
if (++us >= 2)
|
||||
@@ -2060,15 +2060,32 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
|
||||
n = strtoul((char*)str, &end, base);
|
||||
us = 0;
|
||||
for (p=str;*p;p++) {
|
||||
if (*p == '_') {
|
||||
if (us == 0) {
|
||||
us++;
|
||||
continue;
|
||||
}
|
||||
if (badcheck) goto bad;
|
||||
break;
|
||||
}
|
||||
c = conv_digit(*p);
|
||||
if (c < 0 || c >= base) {
|
||||
if (badcheck) goto bad;
|
||||
break;
|
||||
}
|
||||
n *= base;
|
||||
n += c;
|
||||
}
|
||||
if (n > MRB_INT_MAX) {
|
||||
mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", mrb_str_new_cstr(mrb, str));
|
||||
}
|
||||
val = n;
|
||||
if (badcheck) {
|
||||
if (end == str) goto bad; /* no number */
|
||||
while (*end && ISSPACE(*end)) end++;
|
||||
if (*end) goto bad; /* trailing garbage */
|
||||
if (p == str) goto bad; /* no number */
|
||||
while (*p && ISSPACE(*p)) p++;
|
||||
if (*p) goto bad; /* trailing garbage */
|
||||
}
|
||||
|
||||
return mrb_fixnum_value(sign ? val : -val);
|
||||
|
||||
@@ -433,11 +433,13 @@ assert('String#to_i', '15.2.10.5.39') do
|
||||
b = '32143'.to_i
|
||||
c = 'a'.to_i(16)
|
||||
d = '100'.to_i(2)
|
||||
e = '1_000'.to_i
|
||||
|
||||
assert_equal 0, a
|
||||
assert_equal 32143, b
|
||||
assert_equal 10, c
|
||||
assert_equal 4, d
|
||||
assert_equal 1_000, e
|
||||
end
|
||||
|
||||
assert('String#to_s', '15.2.10.5.40') do
|
||||
|
||||
Reference in New Issue
Block a user