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:
parent
9e8553e5cc
commit
b3144a7a0e
3 changed files with 117 additions and 77 deletions
22
ChangeLog
22
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.
|
* 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.
|
||||||
|
|
||||||
|
|
110
lib/singleton.rb
110
lib/singleton.rb
|
@ -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
62
time.c
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue