summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-12-03 10:07:48 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-12-03 10:07:48 +0000
commitb3144a7a0e08500d212c9f30e889dfcff631fbc4 (patch)
treef07f5ab290541a34d6ce978bc4961917c1c6ac54
parent9e8553e5cccd1507597b7726da15a13fcae192af (diff)
* time.c (time_plus): must detect result overflow.
* time.c (time_minus): ditto. * time.c (time_new_internal): round usec overflow and underflow here. * time.c (time_plus): move operand overflow/underflow check to time_new_internal(). * time.c (time_minus): ditto. * time.c (time_cmp): should consider tv_usec too. * time.c (time_gmtime): time_modify() should be called even if tm struct is not calculated yet. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1880 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog22
-rw-r--r--lib/singleton.rb110
-rw-r--r--time.c62
3 files changed, 117 insertions, 77 deletions
diff --git a/ChangeLog b/ChangeLog
index 1df1d62966..d978c35d60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,22 @@ Mon Dec 3 16:04:16 2001 Usaku Nakamura <usa@ruby-lang.org>
* configure.in: not use X11BASE, since it's not always set.
+Mon Dec 3 09:59:08 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * time.c (time_plus): must detect result overflow.
+
+ * time.c (time_minus): ditto.
+
+ * time.c (time_new_internal): round usec overflow and underflow
+ here.
+
+ * time.c (time_plus): move operand overflow/underflow check to
+ time_new_internal().
+
+ * time.c (time_minus): ditto.
+
+ * time.c (time_cmp): should consider tv_usec too.
+
Mon Dec 3 03:32:22 2001 Usaku Nakamura <usa@ruby-lang.org>
* configure.in: apply patch from NetBSD's pkgsrc (patch-aa).
@@ -20,6 +36,11 @@ Sun Dec 2 22:01:52 2001 WATANABE Hirofumi <eban@ruby-lang.org>
* ext/dbm/extconf.rb: check if $CFLAGS includes DBM_HDR.
+Sat Dec 1 12:13:20 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * time.c (time_gmtime): time_modify() should be called even if tm
+ struct is not calculated yet.
+
Fri Nov 30 17:02:55 2001 WATANABE Hirofumi <eban@ruby-lang.org>
* configure.in: set target_cpu to i386 on cygwin and mingw32.
@@ -13145,4 +13166,3 @@ Fri Aug 15 19:40:43 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
Wed Aug 13 17:51:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1 alpha0 released.
-
diff --git a/lib/singleton.rb b/lib/singleton.rb
index 3ab048f5a3..404eaf7101 100644
--- a/lib/singleton.rb
+++ b/lib/singleton.rb
@@ -44,60 +44,64 @@
# of a previous state of ``the instance'' - see third example.
#
module Singleton
- def Singleton.included (klass)
- # should this be checked?
- # raise TypeError.new "..." if klass.type == Module
- class << klass
- def inherited(sub_klass)
- # @__instance__ takes on one of the following values
- # * nil - before (and after a failed) creation
- # * false - during creation
- # * sub_class instance - after a successful creation
- sub_klass.instance_eval { @__instance__ = nil }
- def sub_klass.instance
- unless @__instance__.nil?
- # is the extra flexiblity having the hook method
- # _wait() around ever useful?
- _wait()
- # check for instance creation
- return @__instance__ if @__instance__
- end
- Thread.critical = true
- unless @__instance__
- @__instance__ = false
- Thread.critical = false
- begin
- @__instance__ = new
- ensure
- if @__instance__
- define_method(:instance) {@__instance__ }
- else
- # failed instance creation
- @__instance__ = nil
- end
- end
- else
- Thread.critical = false
- end
- return @__instance__
- end
- end
- def _load(str)
- instance
- end
- def _wait
- sleep(0.05) while false.equal?(@__instance__)
- end
- private :new, :allocate
- # hook methods are also marked private
- private :_load,:_wait
- end
- klass.inherited klass
- end
- private
- def _dump(depth)
- return ""
+ def Singleton.included (klass)
+ # should this be checked?
+ # raise TypeError.new "..." if klass.type == Module
+ klass.module_eval {
+ undef_method :clone
+ undef_method :dup
+ }
+ class << klass
+ def inherited(sub_klass)
+ # @__instance__ takes on one of the following values
+ # * nil - before (and after a failed) creation
+ # * false - during creation
+ # * sub_class instance - after a successful creation
+ sub_klass.instance_eval { @__instance__ = nil }
+ def sub_klass.instance
+ unless @__instance__.nil?
+ # is the extra flexiblity having the hook method
+ # _wait() around ever useful?
+ _wait()
+ # check for instance creation
+ return @__instance__ if @__instance__
+ end
+ Thread.critical = true
+ unless @__instance__
+ @__instance__ = false
+ Thread.critical = false
+ begin
+ @__instance__ = new
+ ensure
+ if @__instance__
+ define_method(:instance) {@__instance__ }
+ else
+ # failed instance creation
+ @__instance__ = nil
+ end
+ end
+ else
+ Thread.critical = false
+ end
+ return @__instance__
+ end
+ end
+ def _load(str)
+ instance
+ end
+ def _wait
+ sleep(0.05) while false.equal?(@__instance__)
+ end
+ private :new, :allocate
+ # hook methods are also marked private
+ private :_load,:_wait
end
+ klass.inherited klass
+ end
+ private
+ def _dump(depth)
+ return ""
+ end
end
if __FILE__ == $0
diff --git a/time.c b/time.c
index e01f99fca5..35ef208802 100644
--- a/time.c
+++ b/time.c
@@ -68,6 +68,14 @@ time_new_internal(klass, sec, usec)
VALUE obj;
struct time_object *tobj;
+ if (usec >= 1000000) { /* usec overflow */
+ sec += usec / 1000000;
+ usec %= 1000000;
+ }
+ if (usec < 0) { /* usec underflow */
+ sec -= (-usec) / 1000000;
+ usec %= 1000000;
+ }
#ifndef NEGATIVE_TIME_T
if (sec < 0 || (sec == 0 && usec < 0))
rb_raise(rb_eArgError, "time must be positive");
@@ -601,7 +609,13 @@ time_cmp(time1, time2)
switch (TYPE(time2)) {
case T_FIXNUM:
i = FIX2LONG(time2);
- if (tobj1->tv.tv_sec == i) return INT2FIX(0);
+ if (tobj1->tv.tv_sec == i) {
+ if (tobj1->tv.tv_usec == 0)
+ return INT2FIX(0);
+ if (tobj1->tv.tv_usec > 0)
+ return INT2FIX(1);
+ return INT2FIX(-1);
+ }
if (tobj1->tv.tv_sec > i) return INT2FIX(1);
return INT2FIX(-1);
@@ -706,8 +720,11 @@ time_localtime(time)
time_t t;
GetTimeval(time, tobj);
- if (tobj->tm_got) {
- if (!tobj->gmt) return time;
+ if (!tobj->gmt) {
+ if (tobj->tm_got)
+ return time;
+ }
+ else {
time_modify(time);
}
t = tobj->tv.tv_sec;
@@ -727,8 +744,11 @@ time_gmtime(time)
time_t t;
GetTimeval(time, tobj);
- if (tobj->tm_got) {
- if (tobj->gmt) return time;
+ if (tobj->gmt) {
+ if (tobj->tm_got)
+ return time;
+ }
+ else {
time_modify(time);
}
t = tobj->tv.tv_sec;
@@ -804,14 +824,12 @@ time_plus(time1, time2)
usec = tobj->tv.tv_usec + (time_t)((f - (double)sec)*1e6);
sec = tobj->tv.tv_sec + sec;
- if (usec >= 1000000) { /* usec overflow */
- sec++;
- usec -= 1000000;
- }
- if (usec < 0) { /* usec underflow */
- sec--;
- usec += 1000000;
+#ifdef NEGATIVE_TIME_T
+ if ((tobj->tv.tv_sec > 0 && f > 0 && sec < 0) ||
+ (tobj->tv.tv_sec < 0 && f < 0 && sec > 0)) {
+ rb_raise(rb_eRangeError, "time + %f out of Time range", f);
}
+#endif
time2 = rb_time_new(sec, usec);
if (tobj->gmt) {
GetTimeval(time2, tobj);
@@ -833,8 +851,8 @@ time_minus(time1, time2)
struct time_object *tobj2;
GetTimeval(time2, tobj2);
- f = tobj->tv.tv_sec - tobj2->tv.tv_sec;
- f += (tobj->tv.tv_usec - tobj2->tv.tv_usec)*1e-6;
+ f = (double)tobj->tv.tv_sec - (double)tobj2->tv.tv_sec;
+ f += ((double)tobj->tv.tv_usec - (double)tobj2->tv.tv_usec)*1e-6;
return rb_float_new(f);
}
@@ -844,16 +862,14 @@ time_minus(time1, time2)
usec = tobj->tv.tv_usec - (time_t)((f - (double)sec)*1e6);
sec = tobj->tv.tv_sec - sec;
}
-
- if (usec >= 1000000) { /* usec overflow */
- sec++;
- usec -= 1000000;
- }
- if (usec < 0) { /* usec underflow */
- sec--;
- usec += 1000000;
+#ifdef NEGATIVE_TIME_T
+ if ((tobj->tv.tv_sec < 0 && f > 0 && sec > 0) ||
+ (tobj->tv.tv_sec > 0 && f < 0 && sec < 0)) {
+ rb_raise(rb_eRangeError, "time - %f out of Time range", f);
}
- time2 = time_new_internal(rb_obj_class(time1), sec, usec);
+#endif
+
+ time2 = rb_time_new(sec, usec);
if (tobj->gmt) {
GetTimeval(time2, tobj);
tobj->gmt = 1;