* intern.h: prototypes for new functions; rb_cstr_to_inum(),
rb_str_to_inum(), rb_cstr_to_dbl(), rb_str_to_dbl() * bignum.c (rb_cstr_to_inum): changed from rb_cstr2inum(), and added argument badcheck to be consistent with parser. [new] * bignum.c (rb_str_to_inum): ditto. * bignum.c (rb_cstr2inum): wapper of rb_cstr_to_inum() now. * bignum.c (rb_str2inum): ditto. * object.c (rb_cstr_to_dbl): float number parser. [new] * object.c (rb_str_to_dbl): ditto. * object.c (rb_Float): use rb_cstr_to_dbl() for strict check. * object.c (rb_Integer): use rb_str_to_inum() for strict check. * string.c (rb_str_to_f): use rb_str_to_dbl() with less check. * string.c (rb_str_to_i): use rb_str_to_inum() with less check. * string.c (rb_str_hex): ditto. * string.c (rb_str_oct): ditto. * sprintf.c (rb_f_sprintf): ditto. * time.c (obj2long): ditto. * parse.y (yylex): use rb_cstr_to_inum() for strict check. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2041 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d9b49e39b2
commit
c2269d5b4f
36
ChangeLog
36
ChangeLog
@ -1,3 +1,39 @@
|
|||||||
|
Fri Feb 1 19:10:04 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
|
|
||||||
|
* intern.h: prototypes for new functions; rb_cstr_to_inum(),
|
||||||
|
rb_str_to_inum(), rb_cstr_to_dbl(), rb_str_to_dbl()
|
||||||
|
|
||||||
|
* bignum.c (rb_cstr_to_inum): changed from rb_cstr2inum(), and
|
||||||
|
added argument badcheck to be consistent with parser. [new]
|
||||||
|
|
||||||
|
* bignum.c (rb_str_to_inum): ditto.
|
||||||
|
|
||||||
|
* bignum.c (rb_cstr2inum): wapper of rb_cstr_to_inum() now.
|
||||||
|
|
||||||
|
* bignum.c (rb_str2inum): ditto.
|
||||||
|
|
||||||
|
* object.c (rb_cstr_to_dbl): float number parser. [new]
|
||||||
|
|
||||||
|
* object.c (rb_str_to_dbl): ditto.
|
||||||
|
|
||||||
|
* object.c (rb_Float): use rb_cstr_to_dbl() for strict check.
|
||||||
|
|
||||||
|
* object.c (rb_Integer): use rb_str_to_inum() for strict check.
|
||||||
|
|
||||||
|
* string.c (rb_str_to_f): use rb_str_to_dbl() with less check.
|
||||||
|
|
||||||
|
* string.c (rb_str_to_i): use rb_str_to_inum() with less check.
|
||||||
|
|
||||||
|
* string.c (rb_str_hex): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_oct): ditto.
|
||||||
|
|
||||||
|
* sprintf.c (rb_f_sprintf): ditto.
|
||||||
|
|
||||||
|
* time.c (obj2long): ditto.
|
||||||
|
|
||||||
|
* parse.y (yylex): use rb_cstr_to_inum() for strict check.
|
||||||
|
|
||||||
Fri Feb 1 17:46:39 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
Fri Feb 1 17:46:39 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
|
|
||||||
* regex.c (mbc_startpos): become macro.
|
* regex.c (mbc_startpos): become macro.
|
||||||
|
60
bignum.c
60
bignum.c
@ -186,21 +186,26 @@ rb_int2inum(n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_cstr2inum(str, base)
|
rb_cstr_to_inum(str, base, badcheck)
|
||||||
const char *str;
|
const char *str;
|
||||||
int base;
|
int base;
|
||||||
|
int badcheck;
|
||||||
{
|
{
|
||||||
const char *s = str;
|
const char *s = str;
|
||||||
char *end;
|
char *end;
|
||||||
int badcheck = (base==0)?1:0;
|
char sign = 1, c, nondigit = 0;
|
||||||
char sign = 1, c;
|
|
||||||
BDIGIT_DBL num;
|
BDIGIT_DBL num;
|
||||||
long len, blen = 1;
|
long len, blen = 1;
|
||||||
long i;
|
long i;
|
||||||
VALUE z;
|
VALUE z;
|
||||||
BDIGIT *zds;
|
BDIGIT *zds;
|
||||||
|
|
||||||
while (*str && ISSPACE(*str)) str++;
|
if (badcheck) {
|
||||||
|
while (ISSPACE(*str)) str++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (ISSPACE(*str) || *str == '_') str++;
|
||||||
|
}
|
||||||
|
|
||||||
if (str[0] == '+') {
|
if (str[0] == '+') {
|
||||||
str++;
|
str++;
|
||||||
@ -213,7 +218,7 @@ rb_cstr2inum(str, base)
|
|||||||
if (badcheck) goto bad;
|
if (badcheck) goto bad;
|
||||||
return INT2FIX(0);
|
return INT2FIX(0);
|
||||||
}
|
}
|
||||||
if (base == 0) {
|
if (base <= 0) {
|
||||||
if (str[0] == '0') {
|
if (str[0] == '0') {
|
||||||
if (str[1] == 'x' || str[1] == 'X') {
|
if (str[1] == 'x' || str[1] == 'X') {
|
||||||
base = 16;
|
base = 16;
|
||||||
@ -225,6 +230,9 @@ rb_cstr2inum(str, base)
|
|||||||
base = 8;
|
base = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (base < -1) {
|
||||||
|
base = -base;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
base = 10;
|
base = 10;
|
||||||
}
|
}
|
||||||
@ -290,18 +298,27 @@ rb_cstr2inum(str, base)
|
|||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7':
|
case '5': case '6': case '7':
|
||||||
c = c - '0';
|
c = c - '0';
|
||||||
|
nondigit = 0;
|
||||||
break;
|
break;
|
||||||
case 'a': case 'b': case 'c':
|
case 'a': case 'b': case 'c':
|
||||||
case 'd': case 'e': case 'f':
|
case 'd': case 'e': case 'f':
|
||||||
if (base != 16) c = base;
|
c -= 'a' - 'A';
|
||||||
else c = c - 'a' + 10;
|
|
||||||
break;
|
|
||||||
case 'A': case 'B': case 'C':
|
case 'A': case 'B': case 'C':
|
||||||
case 'D': case 'E': case 'F':
|
case 'D': case 'E': case 'F':
|
||||||
if (base != 16) c = base;
|
if (base != 16) {
|
||||||
else c = c - 'A' + 10;
|
nondigit = c;
|
||||||
|
c = base;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = c - 'A' + 10;
|
||||||
|
nondigit = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '_':
|
case '_':
|
||||||
|
if (badcheck) {
|
||||||
|
if (nondigit) goto bad;
|
||||||
|
nondigit = c;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
c = base;
|
c = base;
|
||||||
@ -334,9 +351,10 @@ rb_cstr2inum(str, base)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_str2inum(str, base)
|
rb_str_to_inum(str, base, badcheck)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
int base;
|
int base;
|
||||||
|
int badcheck;
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
int len;
|
int len;
|
||||||
@ -351,10 +369,26 @@ rb_str2inum(str, base)
|
|||||||
p[len] = '\0';
|
p[len] = '\0';
|
||||||
s = p;
|
s = p;
|
||||||
}
|
}
|
||||||
if (base == 0 && len != strlen(s)) {
|
if (badcheck && len != strlen(s)) {
|
||||||
rb_raise(rb_eArgError, "string for Integer contains null byte");
|
rb_raise(rb_eArgError, "string for Integer contains null byte");
|
||||||
}
|
}
|
||||||
return rb_cstr2inum(s, base);
|
return rb_cstr_to_inum(s, base, badcheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_cstr2inum(str, base)
|
||||||
|
const char *str;
|
||||||
|
int base;
|
||||||
|
{
|
||||||
|
return rb_cstr_to_inum(str, base, base==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str2inum(str, base)
|
||||||
|
VALUE str;
|
||||||
|
int base;
|
||||||
|
{
|
||||||
|
return rb_str_to_inum(str, base, base==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char hexmap[] = "0123456789abcdef";
|
static char hexmap[] = "0123456789abcdef";
|
||||||
|
4
intern.h
4
intern.h
@ -61,6 +61,8 @@ VALUE rb_uint2big _((unsigned long));
|
|||||||
VALUE rb_int2big _((long));
|
VALUE rb_int2big _((long));
|
||||||
VALUE rb_uint2inum _((unsigned long));
|
VALUE rb_uint2inum _((unsigned long));
|
||||||
VALUE rb_int2inum _((long));
|
VALUE rb_int2inum _((long));
|
||||||
|
VALUE rb_cstr_to_inum _((const char*, int, int));
|
||||||
|
VALUE rb_str_to_inum _((VALUE, int, int));
|
||||||
VALUE rb_cstr2inum _((const char*, int));
|
VALUE rb_cstr2inum _((const char*, int));
|
||||||
VALUE rb_str2inum _((VALUE, int));
|
VALUE rb_str2inum _((VALUE, int));
|
||||||
VALUE rb_big2str _((VALUE, int));
|
VALUE rb_big2str _((VALUE, int));
|
||||||
@ -263,6 +265,8 @@ VALUE rb_Integer _((VALUE));
|
|||||||
VALUE rb_Float _((VALUE));
|
VALUE rb_Float _((VALUE));
|
||||||
VALUE rb_String _((VALUE));
|
VALUE rb_String _((VALUE));
|
||||||
VALUE rb_Array _((VALUE));
|
VALUE rb_Array _((VALUE));
|
||||||
|
double rb_cstr_to_dbl _((const char *, int));
|
||||||
|
double rb_str_to_dbl _((VALUE, int));
|
||||||
/* parse.y */
|
/* parse.y */
|
||||||
EXTERN int ruby_sourceline;
|
EXTERN int ruby_sourceline;
|
||||||
EXTERN char *ruby_sourcefile;
|
EXTERN char *ruby_sourcefile;
|
||||||
|
134
object.c
134
object.c
@ -945,7 +945,7 @@ rb_Integer(val)
|
|||||||
return val;
|
return val;
|
||||||
|
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
return rb_str2inum(val, 0);
|
return rb_str_to_inum(val, 0, Qtrue);
|
||||||
|
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
return val;
|
return val;
|
||||||
@ -963,6 +963,90 @@ rb_f_integer(obj, arg)
|
|||||||
return rb_Integer(arg);
|
return rb_Integer(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
rb_cstr_to_dbl(p, badcheck)
|
||||||
|
const char *p;
|
||||||
|
int badcheck;
|
||||||
|
{
|
||||||
|
const char *q;
|
||||||
|
char *end;
|
||||||
|
double d;
|
||||||
|
|
||||||
|
q = p;
|
||||||
|
if (badcheck) {
|
||||||
|
while (ISSPACE(*p)) p++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (ISSPACE(*p) || *p == '_') p++;
|
||||||
|
}
|
||||||
|
d = strtod(p, &end);
|
||||||
|
if (p == end) {
|
||||||
|
if (badcheck) {
|
||||||
|
bad:
|
||||||
|
rb_invalid_str(q, "Float()");
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
if (*end) {
|
||||||
|
char *buf = ALLOCA_N(char, strlen(p));
|
||||||
|
char *n = buf;
|
||||||
|
|
||||||
|
while (p < end) *n++ = *p++;
|
||||||
|
while (*p) {
|
||||||
|
if (*p == '_') {
|
||||||
|
/* remove underscores between digits */
|
||||||
|
if (badcheck) {
|
||||||
|
if (n == buf || !ISDIGIT(n[-1])) goto bad;
|
||||||
|
++p;
|
||||||
|
if (!ISDIGIT(*p)) goto bad;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (*++p == '_');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*n++ = *p++;
|
||||||
|
}
|
||||||
|
*n = '\0';
|
||||||
|
p = buf;
|
||||||
|
d = strtod(p, &end);
|
||||||
|
if (badcheck) {
|
||||||
|
if (p == end) goto bad;
|
||||||
|
while (*end && ISSPACE(*end)) end++;
|
||||||
|
if (*end) goto bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errno == ERANGE) {
|
||||||
|
errno = 0;
|
||||||
|
rb_raise(rb_eArgError, "Float %s out of range", q);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
rb_str_to_dbl(str, badcheck)
|
||||||
|
VALUE str;
|
||||||
|
int badcheck;
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
StringValue(str);
|
||||||
|
s = RSTRING(str)->ptr;
|
||||||
|
len = RSTRING(str)->len;
|
||||||
|
if (s[len]) { /* no sentinel somehow */
|
||||||
|
char *p = ALLOCA_N(char, len+1);
|
||||||
|
|
||||||
|
MEMCPY(p, s, char, len);
|
||||||
|
p[len] = '\0';
|
||||||
|
s = p;
|
||||||
|
}
|
||||||
|
if (badcheck && len != strlen(s)) {
|
||||||
|
rb_raise(rb_eArgError, "string for Float contains null byte");
|
||||||
|
}
|
||||||
|
return rb_cstr_to_dbl(s, badcheck);
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_Float(val)
|
rb_Float(val)
|
||||||
VALUE val;
|
VALUE val;
|
||||||
@ -978,53 +1062,7 @@ rb_Float(val)
|
|||||||
return rb_float_new(rb_big2dbl(val));
|
return rb_float_new(rb_big2dbl(val));
|
||||||
|
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
{
|
return rb_float_new(rb_str_to_dbl(val, Qtrue));
|
||||||
char *q, *p, *end;
|
|
||||||
double d;
|
|
||||||
|
|
||||||
q = p = StringValuePtr(val);
|
|
||||||
while (*p && ISSPACE(*p)) p++;
|
|
||||||
d = strtod(p, &end);
|
|
||||||
if (p == end) {
|
|
||||||
bad:
|
|
||||||
rb_invalid_str(q, "Float()");
|
|
||||||
}
|
|
||||||
if (*end) {
|
|
||||||
if (*end == '_') {
|
|
||||||
char *buf = ALLOCA_N(char, strlen(p));
|
|
||||||
char *n = buf, *last = p;
|
|
||||||
|
|
||||||
while (p < end) *n++ = *p++;
|
|
||||||
while (*p) {
|
|
||||||
if (*p == '_' && (n > buf && ISDIGIT(n[-1]))) {
|
|
||||||
/* remove underscores between digits */
|
|
||||||
last = ++p;
|
|
||||||
while (*p == '_') ++p;
|
|
||||||
if (!ISDIGIT(*p)) {
|
|
||||||
while (last < p) *n++ = *last++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
last = p;
|
|
||||||
}
|
|
||||||
*n++ = *p++;
|
|
||||||
}
|
|
||||||
while (*last && (*last == '_' || ISSPACE(*last)))
|
|
||||||
last++;
|
|
||||||
if (!*last) goto bad;
|
|
||||||
*n = '\0';
|
|
||||||
p = buf;
|
|
||||||
d = strtod(p, &end);
|
|
||||||
if (p == end) goto bad;
|
|
||||||
}
|
|
||||||
while (*end && ISSPACE(*end)) end++;
|
|
||||||
if (*end) goto bad;
|
|
||||||
}
|
|
||||||
if (errno == ERANGE) {
|
|
||||||
errno = 0;
|
|
||||||
rb_raise(rb_eArgError, "Float %s out of range", p);
|
|
||||||
}
|
|
||||||
return rb_float_new(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_NIL:
|
case T_NIL:
|
||||||
return rb_float_new(0.0);
|
return rb_float_new(0.0);
|
||||||
|
8
parse.y
8
parse.y
@ -3345,7 +3345,7 @@ yylex()
|
|||||||
yyerror("hexadecimal number without hex-digits");
|
yyerror("hexadecimal number without hex-digits");
|
||||||
}
|
}
|
||||||
else if (nondigit) goto trailing_uc;
|
else if (nondigit) goto trailing_uc;
|
||||||
yylval.val = rb_cstr2inum(tok(), 16);
|
yylval.val = rb_cstr_to_inum(tok(), 16, Qfalse);
|
||||||
return tINTEGER;
|
return tINTEGER;
|
||||||
}
|
}
|
||||||
if (c == 'b' || c == 'B') {
|
if (c == 'b' || c == 'B') {
|
||||||
@ -3369,7 +3369,7 @@ yylex()
|
|||||||
yyerror("numeric literal without digits");
|
yyerror("numeric literal without digits");
|
||||||
}
|
}
|
||||||
else if (nondigit) goto trailing_uc;
|
else if (nondigit) goto trailing_uc;
|
||||||
yylval.val = rb_cstr2inum(tok(), 2);
|
yylval.val = rb_cstr_to_inum(tok(), 2, Qfalse);
|
||||||
return tINTEGER;
|
return tINTEGER;
|
||||||
}
|
}
|
||||||
if (c >= '0' && c <= '7' || c == '_') {
|
if (c >= '0' && c <= '7' || c == '_') {
|
||||||
@ -3388,7 +3388,7 @@ yylex()
|
|||||||
pushback(c);
|
pushback(c);
|
||||||
tokfix();
|
tokfix();
|
||||||
if (nondigit) goto trailing_uc;
|
if (nondigit) goto trailing_uc;
|
||||||
yylval.val = rb_cstr2inum(tok(), 8);
|
yylval.val = rb_cstr_to_inum(tok(), 8, Qfalse);
|
||||||
return tINTEGER;
|
return tINTEGER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3482,7 +3482,7 @@ yylex()
|
|||||||
yylval.val = rb_float_new(d);
|
yylval.val = rb_float_new(d);
|
||||||
return tFLOAT;
|
return tFLOAT;
|
||||||
}
|
}
|
||||||
yylval.val = rb_cstr2inum(tok(), 10);
|
yylval.val = rb_cstr_to_inum(tok(), 10, Qfalse);
|
||||||
return tINTEGER;
|
return tINTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,6 @@
|
|||||||
|
|
||||||
#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
|
#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
|
||||||
|
|
||||||
#if !defined(atof) && !defined(HAVE_STDLIB_H)
|
|
||||||
double strtod();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void fmt_setup _((char*,int,int,int,int));
|
static void fmt_setup _((char*,int,int,int,int));
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
@ -397,7 +393,7 @@ rb_f_sprintf(argc, argv)
|
|||||||
bignum = 1;
|
bignum = 1;
|
||||||
break;
|
break;
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
val = rb_str2inum(val, 0);
|
val = rb_str_to_inum(val, 0, Qtrue);
|
||||||
goto bin_retry;
|
goto bin_retry;
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
bignum = 1;
|
bignum = 1;
|
||||||
|
24
string.c
24
string.c
@ -1766,16 +1766,14 @@ rb_str_to_i(argc, argv, str)
|
|||||||
default:
|
default:
|
||||||
rb_raise(rb_eArgError, "illegal radix %d", base);
|
rb_raise(rb_eArgError, "illegal radix %d", base);
|
||||||
}
|
}
|
||||||
return rb_str2inum(str, base);
|
return rb_str_to_inum(str, base, Qfalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_str_to_f(str)
|
rb_str_to_f(str)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
double f = strtod(RSTRING(str)->ptr, 0);
|
return rb_float_new(rb_str_to_dbl(str, Qfalse));
|
||||||
|
|
||||||
return rb_float_new(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -2963,28 +2961,14 @@ static VALUE
|
|||||||
rb_str_hex(str)
|
rb_str_hex(str)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
return rb_str2inum(str, 16);
|
return rb_str_to_inum(str, 16, Qfalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_str_oct(str)
|
rb_str_oct(str)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
int base = 8;
|
return rb_str_to_inum(str, -8, Qfalse);
|
||||||
|
|
||||||
if (RSTRING(str)->len > 2 && RSTRING(str)->ptr[0] == '0') {
|
|
||||||
switch (RSTRING(str)->ptr[1]) {
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
base = 16;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
base = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rb_str2inum(str, base);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user