From eb6118992b77df9ddd3f95692d357e09b353c358 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 14 May 2002 06:22:31 +0000 Subject: [PATCH] * eval.c (rb_clear_cache_by_class): new function. * eval.c (set_method_visibility): should have clear cache forq updated visibility. * numeric.c (flo_to_s): default format precision to be "%.16g". * util.c (ruby_strtod): use own strtod(3) implementation to avoid locale hell. Due to this change "0xff".to_f no longer returns 255.0 * eval.c (avalue_to_yvalue): new function to distinguish yvalue (no-arg == Qundef) from svalue (no-arg == Qnil). * eval.c (rb_yield_0): use avalue_to_yvalue(). * eval.c (assign): warn if val == Qundef where it means rhs is void (e.g. yield without value or call without argument). * parse.y (value_expr): need not to warn for WHILE and UNTIL, since they can have return value (via valued break). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2457 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 29 ++++++ Makefile.in | 3 - ToDo | 2 +- bignum.c | 3 +- configure.in | 2 +- dln.c | 2 +- dln.h | 2 +- env.h | 2 +- eval.c | 62 ++++++++--- file.c | 2 +- gc.c | 13 +-- hash.c | 2 +- marshal.c | 6 +- misc/ruby-mode.el | 11 +- missing.h | 2 +- node.h | 2 +- numeric.c | 7 +- object.c | 3 +- pack.c | 2 +- parse.y | 3 +- process.c | 2 +- range.c | 2 +- re.c | 2 +- re.h | 2 +- ruby.c | 2 +- ruby.h | 2 +- rubyio.h | 2 +- rubysig.h | 2 +- sample/test.rb | 2 +- signal.c | 2 +- struct.c | 2 +- util.c | 258 +++++++++++++++++++++++++++++++++++++++++++++- util.h | 5 +- variable.c | 2 +- 34 files changed, 377 insertions(+), 70 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4df7d73e8ff6ef..140ce16cba3b7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,24 @@ Tue May 14 14:49:05 2002 WATANABE Hirofumi * missing/strftime.c (timezone): it should take no argument on Cygwin. +Tue May 14 03:07:35 2002 Yukihiro Matsumoto + + * eval.c (rb_clear_cache_by_class): new function. + + * eval.c (set_method_visibility): should have clear cache forq + updated visibility. + Mon May 13 14:38:33 2002 WATANABE Hirofumi * djgpp/config.hin, djgpp/config.sed: catch up with the latest change. +Mon May 13 01:59:55 2002 Yukihiro Matsumoto + + * numeric.c (flo_to_s): default format precision to be "%.16g". + + * util.c (ruby_strtod): use own strtod(3) implementation to avoid + locale hell. Due to this change "0xff".to_f no longer returns 255.0 + Sun May 12 03:01:08 2002 WATANABE Hirofumi * missing.h: add for missing/*.c. @@ -26,6 +40,16 @@ Sat May 11 10:52:09 2002 Nobuyoshi Nakada * dir.c (glob_helper): remove escaping backslashes. +Sat May 11 02:46:43 2002 Yukihiro Matsumoto + + * eval.c (avalue_to_yvalue): new function to distinguish yvalue + (no-arg == Qundef) from svalue (no-arg == Qnil). + + * eval.c (rb_yield_0): use avalue_to_yvalue(). + + * eval.c (assign): warn if val == Qundef where it means rhs is + void (e.g. yield without value or call without argument). + Fri May 10 19:00:47 2002 Nobuyoshi Nakada * parse.y (here_document): preserve line number begins here @@ -38,6 +62,11 @@ Fri May 10 01:55:44 2002 Nobuyoshi Nakada * eval.c (rb_thread_join_m): new. and added optional argument. +Wed May 8 23:48:40 2002 Yukihiro Matsumoto + + * parse.y (value_expr): need not to warn for WHILE and UNTIL, + since they can have return value (via valued break). + Tue May 7 17:13:40 2002 WATANABE Hirofumi * configure.in: forgot to add '-Wl,' to the gcc option on Cygwin/MinGW. diff --git a/Makefile.in b/Makefile.in index 9bb704568e0245..c9660106dedb7c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -223,9 +223,6 @@ strftime.@OBJEXT@: $(srcdir)/missing/strftime.c strstr.@OBJEXT@: $(srcdir)/missing/strstr.c $(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/missing/strstr.c -strtod.@OBJEXT@: $(srcdir)/missing/strtod.c - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/missing/strtod.c - strtol.@OBJEXT@: $(srcdir)/missing/strtol.c $(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/missing/strtol.c diff --git a/ToDo b/ToDo index 91c5787f5f8a52..d34bedbaf1f7bd 100644 --- a/ToDo +++ b/ToDo @@ -95,7 +95,7 @@ Standard Libraries * new user-defined marshal scheme. _dump(dumper), _load(restorer) * library to load per-user profile seeking .ruby_profile or ruby.ini file. * warning framework (warn, warning for Ruby level) -* marshal should not depend on sprintf/strtod (works bad with locale). +* marshal should not depend on sprintf (works bad with locale). * ternary arg pow: a.pow(b,c) == a**b%c * new caller(), e.g. call_stack; needs better name. * remove dependency on MAXPATHLEN. diff --git a/bignum.c b/bignum.c index b4e9148f429b5a..7955fe22bd2ed5 100644 --- a/bignum.c +++ b/bignum.c @@ -10,9 +10,10 @@ **********************************************************************/ +#include "ruby.h" + #include #include -#include "ruby.h" VALUE rb_cBignum; diff --git a/configure.in b/configure.in index 6215f6785d363d..e6295811ad02b3 100644 --- a/configure.in +++ b/configure.in @@ -987,7 +987,7 @@ if test "$enable_shared" = 'yes'; then darwin*) LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).$(MAJOR).$(MINOR).$(TEENY).dylib' LIBRUBY_LDSHARED='cc -dynamiclib -undefined suppress -flat_namespace' - LIBRUBY_DLDFLAGS='-install_name lib$(RUBY_INSTALL_NAME).dylib -current_version $(MAJOR).$(MINOR).$(TEENY) -compatibility_version $(MAJOR).$(MINOR)' + LIBRUBY_DLDFLAGS='-install_name $(prefix)/lib/lib$(RUBY_INSTALL_NAME).dylib -current_version $(MAJOR).$(MINOR).$(TEENY) -compatibility_version $(MAJOR).$(MINOR)' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).$(MAJOR).$(MINOR).dylib lib$(RUBY_INSTALL_NAME).dylib' ;; *) diff --git a/dln.c b/dln.c index ebad1e009149ec..563e18f555f19f 100644 --- a/dln.c +++ b/dln.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 18 17:05:06 JST 1994 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/dln.h b/dln.h index c6f9654eb64213..adef8139538c53 100644 --- a/dln.h +++ b/dln.h @@ -6,7 +6,7 @@ $Date$ created at: Wed Jan 19 16:53:09 JST 1994 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/env.h b/env.h index 8e96f1a7f706b9..b185d1262f7b94 100644 --- a/env.h +++ b/env.h @@ -6,7 +6,7 @@ $Date$ created at: Mon Jul 11 11:53:03 JST 1994 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/eval.c b/eval.c index 636648cb0e8807..628e16c9697c0b 100644 --- a/eval.c +++ b/eval.c @@ -217,6 +217,21 @@ rb_clear_cache_by_id(id) } } +static void +rb_clear_cache_by_class(klass) + VALUE klass; +{ + struct cache_entry *ent, *end; + + ent = cache; end = ent + CACHE_SIZE; + while (ent < end) { + if (ent->origin == klass) { + ent->mid = 0; + } + ent++; + } +} + void rb_add_method(klass, mid, node, noex) VALUE klass; @@ -2111,11 +2126,28 @@ avalue_to_svalue(v) return v; } +static VALUE +avalue_to_yvalue(v) + VALUE v; +{ + if (TYPE(v) != T_ARRAY) { + v = rb_ary_to_ary(v); + } + if (RARRAY(v)->len == 0) { + return Qundef; + } + if (RARRAY(v)->len == 1) { + return RARRAY(v)->ptr[0]; + } + return v; +} + static VALUE svalue_to_mvalue(v) VALUE v; { - if (NIL_P(v)) return rb_ary_new2(0); + if (v == Qnil || v == Qundef) + return rb_ary_new2(0); if (TYPE(v) == T_ARRAY) { return v; } @@ -2511,10 +2543,10 @@ rb_eval(self, n) case NODE_YIELD: if (node->nd_stts) { - result = avalue_to_svalue(rb_eval(self, node->nd_stts)); + result = avalue_to_yvalue(rb_eval(self, node->nd_stts)); } else { - result = Qnil; + result = Qundef; /* no arg */ } result = rb_yield_0(result, 0, 0, 0); break; @@ -3745,21 +3777,21 @@ rb_yield_0(val, self, klass, pcall) RARRAY(val)->len); } } + else if (nd_type(block->var) == NODE_MASGN) { + massign(self, block->var, val, pcall); + } else { - if (nd_type(block->var) == NODE_MASGN) { - massign(self, block->var, val, pcall); - } - else { - if (pcall) val = avalue_to_svalue(val); - assign(self, block->var, val, pcall); + if (pcall) { + val = avalue_to_yvalue(val); } + assign(self, block->var, val, pcall); } } POP_TAG(); if (state) goto pop_state; } else if (pcall) { - val = avalue_to_svalue(val); + val = avalue_to_yvalue(val); } PUSH_ITER(block->iter); @@ -3849,7 +3881,7 @@ static VALUE rb_f_loop() { for (;;) { - rb_yield_0(Qnil, 0, 0, 0); + rb_yield_0(Qundef, 0, 0, 0); CHECK_INTS; } return Qnil; /* dummy */ @@ -3912,7 +3944,10 @@ assign(self, lhs, val, pcall) VALUE val; int pcall; { - if (val == Qundef) val = Qnil; + if (val == Qundef) { + rb_warning("assigning void value"); + val = Qnil; + } switch (nd_type(lhs)) { case NODE_GASGN: rb_gvar_set(lhs->nd_entry, val); @@ -5623,6 +5658,7 @@ set_method_visibility(self, argc, argv, ex) for (i=0; iiter = ITER_CUR; if (!pcall) { - args = avalue_to_svalue(args); + args = avalue_to_yvalue(args); } PUSH_TAG(PROT_NONE); state = EXEC_TAG(); diff --git a/file.c b/file.c index a54c4ae96423a2..6b8527b26823af 100644 --- a/file.c +++ b/file.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Nov 15 12:24:34 JST 1993 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan diff --git a/gc.c b/gc.c index c2971756860133..21a4c2e1cbbba9 100644 --- a/gc.c +++ b/gc.c @@ -1128,18 +1128,7 @@ rb_gc() struct gc_list *list; struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */ jmp_buf save_regs_gc_mark; -#ifdef C_ALLOCA - VALUE stack_end; - alloca(0); -# define STACK_END (&stack_end) -#else -# if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS) - VALUE *stack_end = __builtin_frame_address(0); -# else - VALUE *stack_end = alloca(1); -# endif -# define STACK_END (stack_end) -#endif + SET_STACK_END; if (dont_gc || during_gc) { if (!freelist || malloc_memories > GC_MALLOC_LIMIT) { diff --git a/hash.c b/hash.c index 170913dc18269d..af1d832a20bdf6 100644 --- a/hash.c +++ b/hash.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Nov 22 18:51:18 JST 1993 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan diff --git a/marshal.c b/marshal.c index 738f7edd62813e..24eacc4b134896 100644 --- a/marshal.c +++ b/marshal.c @@ -15,10 +15,7 @@ #include "ruby.h" #include "rubyio.h" #include "st.h" - -#if !defined(atof) && !defined(HAVE_STDLIB_H) -double strtod(); -#endif +#include "util.h" #define BITSPERSHORT (2*CHAR_BIT) #define SHORTMASK ((1<value; double avalue, d1, d2; @@ -235,11 +235,12 @@ flo_to_s(flt) d1 = modf(d1, &d2); if (d1 == 0) fmt = "%.1e"; } - else if (avalue >= 1.0e10) { + else if (avalue >= 1.0e15) { d1 = avalue; while (d1 > 10.0) d1 /= 10.0; d1 = modf(d1, &d2); if (d1 == 0) fmt = "%.1e"; + else fmt = "%.16e"; } else if ((d1 = modf(value, &d2)) == 0) { fmt = "%.1f"; diff --git a/object.c b/object.c index 99b87678959dac..b5de7ca8bd9a6a 100644 --- a/object.c +++ b/object.c @@ -14,6 +14,7 @@ #include "ruby.h" #include "st.h" +#include "util.h" #include #include #include @@ -990,7 +991,7 @@ rb_cstr_to_dbl(p, badcheck) d = strtod(p, &end); if (p == end) { if (badcheck) { - bad: + bad: rb_invalid_str(q, "Float()"); } return d; diff --git a/pack.c b/pack.c index ef13d160bb693b..67224af21a2daf 100644 --- a/pack.c +++ b/pack.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Feb 10 15:17:05 JST 1994 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/parse.y b/parse.y index a0c5b22d2b7f58..b30f736673d0bd 100644 --- a/parse.y +++ b/parse.y @@ -4597,8 +4597,6 @@ value_expr(node) if (node == 0) return Qtrue; switch (nd_type(node)) { - case NODE_WHILE: - case NODE_UNTIL: case NODE_CLASS: case NODE_MODULE: case NODE_DEFN: @@ -4612,6 +4610,7 @@ value_expr(node) case NODE_REDO: case NODE_RETRY: yyerror("void value expression"); + /* or "control never reach"? */ return Qfalse; case NODE_BLOCK: diff --git a/process.c b/process.c index a2b3d7ceb5fb0a..329c5ff1d6cacb 100644 --- a/process.c +++ b/process.c @@ -726,7 +726,7 @@ rb_f_fork(obj) if (rb_block_given_p()) { int status; - rb_protect(rb_yield, Qnil, &status); + rb_protect(rb_yield, Qundef, &status); ruby_stop(status); } return Qnil; diff --git a/range.c b/range.c index 81d00f0077bc5b..a9abb245f695d2 100644 --- a/range.c +++ b/range.c @@ -265,7 +265,7 @@ range_step(argc, argv, range) } if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */ - long beg, end = FIX2LONG(e), s = NUM2LONG(step); + long end = FIX2LONG(e), s = NUM2LONG(step); long i; if (s <= 0) { rb_raise(rb_eArgError, "step can't be <= 0"); diff --git a/re.c b/re.c index d63ae67eeab452..6f7967ae656178 100644 --- a/re.c +++ b/re.c @@ -5,7 +5,7 @@ $Author$ created at: Mon Aug 9 18:24:49 JST 1993 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/re.h b/re.h index ec041f6b172bb9..47c5f424ad4288 100644 --- a/re.h +++ b/re.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Sep 30 14:18:32 JST 1993 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/ruby.c b/ruby.c index 155a6fa0adb13e..bcb21ca40b50e7 100644 --- a/ruby.c +++ b/ruby.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 12:47:31 JST 1993 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan diff --git a/ruby.h b/ruby.h index 6e4a740436a510..3d2b0990625c0b 100644 --- a/ruby.h +++ b/ruby.h @@ -5,7 +5,7 @@ $Author$ created at: Thu Jun 10 14:26:32 JST 1993 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan diff --git a/rubyio.h b/rubyio.h index 214128449f21f2..3ec91680b5bce4 100644 --- a/rubyio.h +++ b/rubyio.h @@ -6,7 +6,7 @@ $Date$ created at: Fri Nov 12 16:47:09 JST 1993 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/rubysig.h b/rubysig.h index 777bef31f2ace3..9e93296ff3831c 100644 --- a/rubysig.h +++ b/rubysig.h @@ -6,7 +6,7 @@ $Date$ created at: Wed Aug 16 01:15:38 JST 1995 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/sample/test.rb b/sample/test.rb index b20712019d663d..30a02dd24d75a5 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -1000,7 +1000,7 @@ def aaa(a, b=100, *rest) test_ok(!defined?(iii)) # out of scope loop{iii=5; test_ok(eval("defined? iii")); break} -loop {|iii| +loop { iii = 10 def dyna_var_check loop { diff --git a/signal.c b/signal.c index 5c635cc94cb162..3a2c5c6eebb42f 100644 --- a/signal.c +++ b/signal.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 20 10:13:44 JST 1994 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan diff --git a/struct.c b/struct.c index 083bc83fe45a7f..d63a7f95ad7ded 100644 --- a/struct.c +++ b/struct.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Mar 22 18:44:30 JST 1995 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ diff --git a/util.c b/util.c index d43ee634480106..e37d0adcbce036 100644 --- a/util.c +++ b/util.c @@ -10,6 +10,8 @@ **********************************************************************/ +#include "ruby.h" + #include #include @@ -17,8 +19,6 @@ #include "missing/file.h" #endif -#include "ruby.h" - #include "util.h" #ifndef HAVE_STRING_H char *strchr _((char*,char)); @@ -643,9 +643,261 @@ ruby_getcwd() char *buf = xmalloc(size); while (!getcwd(buf, size)) { - if (errno != ERANGE) rb_sys_fail(NULL); + if (errno != ERANGE) rb_sys_fail(0); size *= 2; buf = xrealloc(buf, size); } return buf; } + +/* copyright notice for strtod implementation -- + * + * Copyright (c) 1988-1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#define TRUE 1 +#define FALSE 0 + +static int maxExponent = 511; /* Largest possible base 10 exponent. Any + * exponent larger than this will already + * produce underflow or overflow, so there's + * no need to worry about additional digits. + */ +static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ + 10.0, /* is 10^2^i. Used to convert decimal */ + 100.0, /* exponents into floating-point numbers. */ + 1.0e4, + 1.0e8, + 1.0e16, + 1.0e32, + 1.0e64, + 1.0e128, + 1.0e256 +}; + +/* + *---------------------------------------------------------------------- + * + * strtod -- + * + * This procedure converts a floating-point number from an ASCII + * decimal representation to internal double-precision format. + * + * Results: + * The return value is the double-precision floating-point + * representation of the characters in string. If endPtr isn't + * NULL, then *endPtr is filled in with the address of the + * next character after the last one that was part of the + * floating-point number. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +double +ruby_strtod(string, endPtr) + const char *string; /* A decimal ASCII floating-point number, + * optionally preceded by white space. + * Must have form "-I.FE-X", where I is the + * integer part of the mantissa, F is the + * fractional part of the mantissa, and X + * is the exponent. Either of the signs + * may be "+", "-", or omitted. Either I + * or F may be omitted, or both. The decimal + * point isn't necessary unless F is present. + * The "E" may actually be an "e". E and X + * may both be omitted (but not just one). + */ + char **endPtr; /* If non-NULL, store terminating character's + * address here. */ +{ + int sign, expSign = FALSE; + double fraction, dblExp, *d; + register const char *p; + register int c; + int exp = 0; /* Exponent read from "EX" field. */ + int fracExp = 0; /* Exponent that derives from the fractional + * part. Under normal circumstatnces, it is + * the negative of the number of digits in F. + * However, if I is very long, the last digits + * of I get dropped (otherwise a long I with a + * large negative exponent could cause an + * unnecessary overflow on I alone). In this + * case, fracExp is incremented one for each + * dropped digit. */ + int mantSize; /* Number of digits in mantissa. */ + int decPt; /* Number of mantissa digits BEFORE decimal + * point. */ + const char *pExp; /* Temporarily holds location of exponent + * in string. */ + + /* + * Strip off leading blanks and check for a sign. + */ + + p = string; + while (isspace(*p)) { + p += 1; + } + if (*p == '-') { + sign = TRUE; + p += 1; + } + else { + if (*p == '+') { + p += 1; + } + sign = FALSE; + } + + /* + * Count the number of digits in the mantissa (including the decimal + * point), and also locate the decimal point. + */ + + decPt = -1; + for (mantSize = 0; ; mantSize += 1) { + c = *p; + if (!isdigit(c)) { + if ((c != '.') || (decPt >= 0)) { + break; + } + decPt = mantSize; + } + p += 1; + } + + /* + * Now suck up the digits in the mantissa. Use two integers to + * collect 9 digits each (this is faster than using floating-point). + * If the mantissa has more than 18 digits, ignore the extras, since + * they can't affect the value anyway. + */ + + pExp = p; + p -= mantSize; + if (decPt < 0) { + decPt = mantSize; + } + else { + mantSize -= 1; /* One of the digits was the point. */ + } + if (mantSize > 18) { + fracExp = decPt - 18; + mantSize = 18; + } + else { + fracExp = decPt - mantSize; + } + if (mantSize == 0) { + fraction = 0.0; + p = string; + goto done; + } + else { + int frac1, frac2; + frac1 = 0; + for ( ; mantSize > 9; mantSize -= 1) { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac1 = 10*frac1 + (c - '0'); + } + frac2 = 0; + for (; mantSize > 0; mantSize -= 1) { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac2 = 10*frac2 + (c - '0'); + } + fraction = (1.0e9 * frac1) + frac2; + } + + /* + * Skim off the exponent. + */ + + p = pExp; + if ((*p == 'E') || (*p == 'e')) { + p += 1; + if (*p == '-') { + expSign = TRUE; + p += 1; + } + else { + if (*p == '+') { + p += 1; + } + expSign = FALSE; + } + while (isdigit(*p)) { + exp = exp * 10 + (*p - '0'); + p += 1; + } + } + if (expSign) { + exp = fracExp - exp; + } + else { + exp = fracExp + exp; + } + + /* + * Generate a floating-point number that represents the exponent. + * Do this by processing the exponent one bit at a time to combine + * many powers of 2 of 10. Then combine the exponent with the + * fraction. + */ + + if (exp < 0) { + expSign = TRUE; + exp = -exp; + } + else { + expSign = FALSE; + } + if (exp > maxExponent) { + exp = maxExponent; + errno = ERANGE; + } + dblExp = 1.0; + for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { + if (exp & 01) { + dblExp *= *d; + } + } + if (expSign) { + fraction /= dblExp; + } + else { + fraction *= dblExp; + } + +done: + if (endPtr != NULL) { + *endPtr = (char *) p; + } + + if (sign) { + return -fraction; + } + return fraction; +} diff --git a/util.h b/util.h index 51f32d01793c5b..33889b2c32e339 100644 --- a/util.h +++ b/util.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Mar 9 11:55:53 JST 1995 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto **********************************************************************/ @@ -61,4 +61,7 @@ char *ruby_strdup _((const char*)); char *ruby_getcwd _((void)); #define my_getcwd() ruby_getcwd() +double ruby_strtod _((const char*, char **)); +#define strtod(s,e) ruby_strtod((s),(e)) + #endif /* UTIL_H */ diff --git a/variable.c b/variable.c index 62cfc416165786..bed89593d63eae 100644 --- a/variable.c +++ b/variable.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Apr 19 23:55:15 JST 1994 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 1993-2002 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan