1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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
This commit is contained in:
matz 2001-12-03 10:07:48 +00:00
parent 9e8553e5cc
commit b3144a7a0e
3 changed files with 117 additions and 77 deletions

View file

@ -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. * 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> Mon Dec 3 03:32:22 2001 Usaku Nakamura <usa@ruby-lang.org>
* configure.in: apply patch from NetBSD's pkgsrc (patch-aa). * 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. * 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> Fri Nov 30 17:02:55 2001 WATANABE Hirofumi <eban@ruby-lang.org>
* configure.in: set target_cpu to i386 on cygwin and mingw32. * 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> Wed Aug 13 17:51:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1 alpha0 released. * version 1.1 alpha0 released.

View file

@ -44,60 +44,64 @@
# of a previous state of ``the instance'' - see third example. # of a previous state of ``the instance'' - see third example.
# #
module Singleton module Singleton
def Singleton.included (klass) def Singleton.included (klass)
# should this be checked? # should this be checked?
# raise TypeError.new "..." if klass.type == Module # raise TypeError.new "..." if klass.type == Module
class << klass klass.module_eval {
def inherited(sub_klass) undef_method :clone
# @__instance__ takes on one of the following values undef_method :dup
# * nil - before (and after a failed) creation }
# * false - during creation class << klass
# * sub_class instance - after a successful creation def inherited(sub_klass)
sub_klass.instance_eval { @__instance__ = nil } # @__instance__ takes on one of the following values
def sub_klass.instance # * nil - before (and after a failed) creation
unless @__instance__.nil? # * false - during creation
# is the extra flexiblity having the hook method # * sub_class instance - after a successful creation
# _wait() around ever useful? sub_klass.instance_eval { @__instance__ = nil }
_wait() def sub_klass.instance
# check for instance creation unless @__instance__.nil?
return @__instance__ if @__instance__ # is the extra flexiblity having the hook method
end # _wait() around ever useful?
Thread.critical = true _wait()
unless @__instance__ # check for instance creation
@__instance__ = false return @__instance__ if @__instance__
Thread.critical = false end
begin Thread.critical = true
@__instance__ = new unless @__instance__
ensure @__instance__ = false
if @__instance__ Thread.critical = false
define_method(:instance) {@__instance__ } begin
else @__instance__ = new
# failed instance creation ensure
@__instance__ = nil if @__instance__
end define_method(:instance) {@__instance__ }
end else
else # failed instance creation
Thread.critical = false @__instance__ = nil
end end
return @__instance__ end
end else
end Thread.critical = false
def _load(str) end
instance return @__instance__
end end
def _wait end
sleep(0.05) while false.equal?(@__instance__) def _load(str)
end instance
private :new, :allocate end
# hook methods are also marked private def _wait
private :_load,:_wait sleep(0.05) while false.equal?(@__instance__)
end end
klass.inherited klass private :new, :allocate
end # hook methods are also marked private
private private :_load,:_wait
def _dump(depth)
return ""
end end
klass.inherited klass
end
private
def _dump(depth)
return ""
end
end end
if __FILE__ == $0 if __FILE__ == $0

62
time.c
View file

@ -68,6 +68,14 @@ time_new_internal(klass, sec, usec)
VALUE obj; VALUE obj;
struct time_object *tobj; 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 #ifndef NEGATIVE_TIME_T
if (sec < 0 || (sec == 0 && usec < 0)) if (sec < 0 || (sec == 0 && usec < 0))
rb_raise(rb_eArgError, "time must be positive"); rb_raise(rb_eArgError, "time must be positive");
@ -601,7 +609,13 @@ time_cmp(time1, time2)
switch (TYPE(time2)) { switch (TYPE(time2)) {
case T_FIXNUM: case T_FIXNUM:
i = FIX2LONG(time2); 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); if (tobj1->tv.tv_sec > i) return INT2FIX(1);
return INT2FIX(-1); return INT2FIX(-1);
@ -706,8 +720,11 @@ time_localtime(time)
time_t t; time_t t;
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got) { if (!tobj->gmt) {
if (!tobj->gmt) return time; if (tobj->tm_got)
return time;
}
else {
time_modify(time); time_modify(time);
} }
t = tobj->tv.tv_sec; t = tobj->tv.tv_sec;
@ -727,8 +744,11 @@ time_gmtime(time)
time_t t; time_t t;
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got) { if (tobj->gmt) {
if (tobj->gmt) return time; if (tobj->tm_got)
return time;
}
else {
time_modify(time); time_modify(time);
} }
t = tobj->tv.tv_sec; t = tobj->tv.tv_sec;
@ -804,14 +824,12 @@ time_plus(time1, time2)
usec = tobj->tv.tv_usec + (time_t)((f - (double)sec)*1e6); usec = tobj->tv.tv_usec + (time_t)((f - (double)sec)*1e6);
sec = tobj->tv.tv_sec + sec; sec = tobj->tv.tv_sec + sec;
if (usec >= 1000000) { /* usec overflow */ #ifdef NEGATIVE_TIME_T
sec++; if ((tobj->tv.tv_sec > 0 && f > 0 && sec < 0) ||
usec -= 1000000; (tobj->tv.tv_sec < 0 && f < 0 && sec > 0)) {
} rb_raise(rb_eRangeError, "time + %f out of Time range", f);
if (usec < 0) { /* usec underflow */
sec--;
usec += 1000000;
} }
#endif
time2 = rb_time_new(sec, usec); time2 = rb_time_new(sec, usec);
if (tobj->gmt) { if (tobj->gmt) {
GetTimeval(time2, tobj); GetTimeval(time2, tobj);
@ -833,8 +851,8 @@ time_minus(time1, time2)
struct time_object *tobj2; struct time_object *tobj2;
GetTimeval(time2, tobj2); GetTimeval(time2, tobj2);
f = tobj->tv.tv_sec - tobj2->tv.tv_sec; f = (double)tobj->tv.tv_sec - (double)tobj2->tv.tv_sec;
f += (tobj->tv.tv_usec - tobj2->tv.tv_usec)*1e-6; f += ((double)tobj->tv.tv_usec - (double)tobj2->tv.tv_usec)*1e-6;
return rb_float_new(f); return rb_float_new(f);
} }
@ -844,16 +862,14 @@ time_minus(time1, time2)
usec = tobj->tv.tv_usec - (time_t)((f - (double)sec)*1e6); usec = tobj->tv.tv_usec - (time_t)((f - (double)sec)*1e6);
sec = tobj->tv.tv_sec - sec; sec = tobj->tv.tv_sec - sec;
} }
#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
if (usec >= 1000000) { /* usec overflow */ time2 = rb_time_new(sec, usec);
sec++;
usec -= 1000000;
}
if (usec < 0) { /* usec underflow */
sec--;
usec += 1000000;
}
time2 = time_new_internal(rb_obj_class(time1), sec, usec);
if (tobj->gmt) { if (tobj->gmt) {
GetTimeval(time2, tobj); GetTimeval(time2, tobj);
tobj->gmt = 1; tobj->gmt = 1;