summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-01 10:23:22 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-01 10:23:22 +0000
commitc2269d5b4f60829a523f3479492267ef99e1c5fb (patch)
tree1b0a0b035dbca831b168c86d833de524b5cf7848 /object.c
parentd9b49e39b2f3380cb6c4bb68a175a230c4702b58 (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.c134
1 files changed, 86 insertions, 48 deletions
diff --git a/object.c b/object.c
index f455813..35517e9 100644
--- a/object.c
+++ b/object.c
@@ -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);