diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-01 10:23:22 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-01 10:23:22 +0000 |
commit | c2269d5b4f60829a523f3479492267ef99e1c5fb (patch) | |
tree | 1b0a0b035dbca831b168c86d833de524b5cf7848 /object.c | |
parent | d9b49e39b2f3380cb6c4bb68a175a230c4702b58 (diff) |
* 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
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 134 |
1 files changed, 86 insertions, 48 deletions
@@ -945,7 +945,7 @@ rb_Integer(val) return val; case T_STRING: - return rb_str2inum(val, 0); + return rb_str_to_inum(val, 0, Qtrue); case T_FIXNUM: return val; @@ -963,6 +963,90 @@ rb_f_integer(obj, 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 rb_Float(val) VALUE val; @@ -978,53 +1062,7 @@ rb_Float(val) return rb_float_new(rb_big2dbl(val)); case T_STRING: - { - 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); - } + return rb_float_new(rb_str_to_dbl(val, Qtrue)); case T_NIL: return rb_float_new(0.0); |