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

* string.c (rb_str_replace): swap arguments of OBJ_INFECT.

* eval.c (rb_thread_schedule): should not select a thread which is
  not yet initialized.

* time.c (time_plus): wrong boundary check.

* time.c (time_minus): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1918 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2001-12-18 08:47:06 +00:00
parent cd956b3114
commit 35f851bcfe
14 changed files with 135 additions and 77 deletions

View file

@ -1,3 +1,12 @@
Mon Dec 17 18:53:49 2001 K.Kosako <kosako@sofnec.co.jp>
* string.c (rb_str_replace): swap arguments of OBJ_INFECT.
Tue Dec 18 01:02:13 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_thread_schedule): should not select a thread which is
not yet initialized.
Mon Dec 17 16:52:20 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp> Mon Dec 17 16:52:20 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* intern.h: add prototypes. * intern.h: add prototypes.
@ -22,6 +31,12 @@ Mon Dec 17 16:52:20 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* ruby.c (require_libraries): ditto. * ruby.c (require_libraries): ditto.
Mon Dec 17 15:41:24 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* time.c (time_plus): wrong boundary check.
* time.c (time_minus): ditto.
Mon Dec 17 15:19:32 2001 Tanaka Akira <akr@m17n.org> Mon Dec 17 15:19:32 2001 Tanaka Akira <akr@m17n.org>
* time.c: new method `gmtoff', `gmt_offset' and `utc_offset'. * time.c: new method `gmtoff', `gmt_offset' and `utc_offset'.
@ -49,8 +64,16 @@ Mon Dec 17 15:19:32 2001 Tanaka Akira <akr@m17n.org>
* missing/strftime.c: fix overflow by tm_year + 1900. * missing/strftime.c: fix overflow by tm_year + 1900.
Mon Dec 17 00:02:04 2001 Guy Decoux <ts@moulon.inra.fr>
<<<<<<< ChangeLog
* variable.c (find_class_path): should initialize iv_tbl if it's
NULL.
=======
* lib/time.rb: use Time#utc_offset. * lib/time.rb: use Time#utc_offset.
>>>>>>> 1.655
Fri Dec 14 04:23:36 2001 Minero Aoki <aamine@loveruby.net> Fri Dec 14 04:23:36 2001 Minero Aoki <aamine@loveruby.net>
* lib/net/pop.rb: new method Net::POP3.APOP * lib/net/pop.rb: new method Net::POP3.APOP
@ -66,6 +89,17 @@ Fri Dec 14 04:23:36 2001 Minero Aoki <aamine@loveruby.net>
* lib/net/http.rb: ditto. * lib/net/http.rb: ditto.
Fri Dec 14 00:16:06 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* class.c (rb_define_class): should return the existing class if
the class is already defined and its superclass is ideintical to
the specified superclass.
* class.c (rb_define_class_under): ditto.
* class.c (rb_define_module): should return the existing module if
the module is already defined.
Thu Dec 13 09:52:59 2001 Yukihiro Matsumoto <matz@ruby-lang.org> Thu Dec 13 09:52:59 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* time.c (time_new_internal): avoid loop to calculate negative * time.c (time_new_internal): avoid loop to calculate negative

1
ToDo
View file

@ -98,6 +98,7 @@ Standard Libraries
* remove dependency on MAXPATHLEN. * remove dependency on MAXPATHLEN.
* pointer share mechanism similar to one in String for Array. * pointer share mechanism similar to one in String for Array.
* deprecate Array#indexes, and Array#indices. * deprecate Array#indexes, and Array#indices.
* require "1.6" etc. by /usr/lib/ruby/1.6/1.6.rb ;-)
Extension Libraries Extension Libraries

12
class.c
View file

@ -170,8 +170,14 @@ rb_define_class(name, super)
id = rb_intern(name); id = rb_intern(name);
if (rb_const_defined(rb_cObject, id)) { if (rb_const_defined(rb_cObject, id)) {
klass = rb_const_get(rb_cObject, id); klass = rb_const_get(rb_cObject, id);
if (TYPE(klass) != T_CLASS) {
rb_raise(rb_eTypeError, "%s is not a class", name);
}
if (rb_class_real(RCLASS(klass)->super) != super) {
rb_name_error(id, "%s is already defined", name); rb_name_error(id, "%s is already defined", name);
} }
return klass;
}
klass = rb_define_class_id(id, super); klass = rb_define_class_id(id, super);
st_add_direct(rb_class_tbl, id, klass); st_add_direct(rb_class_tbl, id, klass);
@ -190,8 +196,14 @@ rb_define_class_under(outer, name, super)
id = rb_intern(name); id = rb_intern(name);
if (rb_const_defined_at(outer, id)) { if (rb_const_defined_at(outer, id)) {
klass = rb_const_get(outer, id); klass = rb_const_get(outer, id);
if (TYPE(klass) != T_CLASS) {
rb_raise(rb_eTypeError, "%s is not a class", name);
}
if (rb_class_real(RCLASS(klass)->super) != super) {
rb_name_error(id, "%s is already defined", name); rb_name_error(id, "%s is already defined", name);
} }
return klass;
}
klass = rb_define_class_id(id, super); klass = rb_define_class_id(id, super);
rb_const_set(outer, id, klass); rb_const_set(outer, id, klass);
rb_set_class_path(klass, outer, name); rb_set_class_path(klass, outer, name);

2
eval.c
View file

@ -7732,7 +7732,7 @@ rb_thread_schedule()
next = th; next = th;
break; break;
} }
if (th->status == THREAD_RUNNABLE) { if (th->status == THREAD_RUNNABLE && th->stk_ptr) {
if (!next || next->priority < th->priority) if (!next || next->priority < th->priority)
next = th; next = th;
} }

View file

@ -64,8 +64,8 @@ Win32API_initialize(self, dllname, proc, import, export)
int len; int len;
int ex; int ex;
Check_SafeStr(dllname); SafeStringValue(dllname);
Check_SafeStr(proc); SafeStringValue(proc);
hdll = LoadLibrary(RSTRING(dllname)->ptr); hdll = LoadLibrary(RSTRING(dllname)->ptr);
if (!hdll) if (!hdll)
rb_raise(rb_eRuntimeError, "LoadLibrary: %s\n", RSTRING(dllname)->ptr); rb_raise(rb_eRuntimeError, "LoadLibrary: %s\n", RSTRING(dllname)->ptr);
@ -90,7 +90,7 @@ Win32API_initialize(self, dllname, proc, import, export)
case T_ARRAY: case T_ARRAY:
ptr = RARRAY(import)->ptr; ptr = RARRAY(import)->ptr;
for (i = 0, len = RARRAY(import)->len; i < len; i++) { for (i = 0, len = RARRAY(import)->len; i < len; i++) {
Check_SafeStr(ptr[i]); SafeStringValue(ptr[i]);
switch (*(char *)RSTRING(ptr[i])->ptr) { switch (*(char *)RSTRING(ptr[i])->ptr) {
case 'N': case 'n': case 'L': case 'l': case 'N': case 'n': case 'L': case 'l':
rb_ary_push(a_import, INT2FIX(_T_NUMBER)); rb_ary_push(a_import, INT2FIX(_T_NUMBER));
@ -105,7 +105,7 @@ Win32API_initialize(self, dllname, proc, import, export)
} }
break; break;
default: default:
Check_SafeStr(import); SafeStringValue(import);
s = RSTRING(import)->ptr; s = RSTRING(import)->ptr;
for (i = 0, len = RSTRING(import)->len; i < len; i++) { for (i = 0, len = RSTRING(import)->len; i < len; i++) {
switch (*s++) { switch (*s++) {
@ -127,7 +127,7 @@ Win32API_initialize(self, dllname, proc, import, export)
if (NIL_P(export)) { if (NIL_P(export)) {
ex = _T_VOID; ex = _T_VOID;
} else { } else {
Check_SafeStr(export); SafeStringValue(export);
switch (*RSTRING(export)->ptr) { switch (*RSTRING(export)->ptr) {
case 'V': case 'v': case 'V': case 'v':
ex = _T_VOID; ex = _T_VOID;
@ -228,7 +228,7 @@ Win32API_Call(argc, argv, obj)
} else if (FIXNUM_P(str)){ } else if (FIXNUM_P(str)){
pParam = (char *)NUM2ULONG(str); pParam = (char *)NUM2ULONG(str);
} else { } else {
Check_Type(str, T_STRING); StringValue(str);
rb_str_modify(str); rb_str_modify(str);
pParam = RSTRING(str)->ptr; pParam = RSTRING(str)->ptr;
} }

View file

@ -117,7 +117,7 @@ etc_getpwnam(obj, nam)
#ifdef HAVE_GETPWENT #ifdef HAVE_GETPWENT
struct passwd *pwd; struct passwd *pwd;
Check_Type(nam, T_STRING); StringValue(nam);
pwd = getpwnam(RSTRING(nam)->ptr); pwd = getpwnam(RSTRING(nam)->ptr);
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %s", RSTRING(nam)->ptr); if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %s", RSTRING(nam)->ptr);
return setup_passwd(pwd); return setup_passwd(pwd);
@ -194,7 +194,7 @@ etc_getgrnam(obj, nam)
#ifdef HAVE_GETGRENT #ifdef HAVE_GETGRENT
struct group *grp; struct group *grp;
Check_Type(nam, T_STRING); StringValue(nam);
grp = getgrnam(RSTRING(nam)->ptr); grp = getgrnam(RSTRING(nam)->ptr);
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING(nam)->ptr); if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING(nam)->ptr);
return setup_group(grp); return setup_group(grp);

View file

@ -561,7 +561,7 @@ ip_addrsetup(host, port)
else { else {
char *name; char *name;
Check_SafeStr(host); SafeStringValue(host);
name = RSTRING(host)->ptr; name = RSTRING(host)->ptr;
if (*name == 0) { if (*name == 0) {
mkinetaddr(INADDR_ANY, hbuf, sizeof(hbuf)); mkinetaddr(INADDR_ANY, hbuf, sizeof(hbuf));
@ -793,7 +793,7 @@ load_addr_info(h, serv, type, res)
int error; int error;
if (!NIL_P(h)) { if (!NIL_P(h)) {
Check_SafeStr(h); SafeStringValue(h);
host = RSTRING(h)->ptr; host = RSTRING(h)->ptr;
} }
else { else {
@ -804,7 +804,7 @@ load_addr_info(h, serv, type, res)
portp = pbuf; portp = pbuf;
} }
else { else {
Check_SafeStr(serv); SafeStringValue(serv);
if (RSTRING(serv)->len >= sizeof(pbuf)) if (RSTRING(serv)->len >= sizeof(pbuf))
rb_raise(rb_eArgError, "servicename too long (%d)", RSTRING(serv)->len); rb_raise(rb_eArgError, "servicename too long (%d)", RSTRING(serv)->len);
strcpy(pbuf, RSTRING(serv)->ptr); strcpy(pbuf, RSTRING(serv)->ptr);
@ -918,10 +918,9 @@ tcp_s_open(argc, argv, class)
&remote_host, &remote_serv, &remote_host, &remote_serv,
&local_host, &local_serv); &local_host, &local_serv);
Check_SafeStr(remote_host); SafeStringValue(remote_host);
if (!NIL_P(local_host)) { if (!NIL_P(local_host)) {
Check_SafeStr(local_host); SafeStringValue(local_host);
} }
return open_inet(class, remote_host, remote_serv, return open_inet(class, remote_host, remote_serv,
@ -940,7 +939,7 @@ socks_s_open(class, host, serv)
init = 1; init = 1;
} }
Check_SafeStr(host); SafeStringValue(host);
return open_inet(class, host, serv, Qnil, Qnil, INET_SOCKS); return open_inet(class, host, serv, Qnil, Qnil, INET_SOCKS);
} }
@ -1150,7 +1149,7 @@ tcp_accept(sock)
static VALUE static VALUE
open_unix(class, path, server) open_unix(class, path, server)
VALUE class; VALUE class;
struct RString *path; VALUE path;
int server; int server;
{ {
struct sockaddr_un sockaddr; struct sockaddr_un sockaddr;
@ -1158,7 +1157,7 @@ open_unix(class, path, server)
VALUE sock; VALUE sock;
OpenFile *fptr; OpenFile *fptr;
Check_SafeStr(path); SafeStringValue(path);
fd = ruby_socket(AF_UNIX, SOCK_STREAM, 0); fd = ruby_socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) { if (fd < 0) {
rb_sys_fail("socket(2)"); rb_sys_fail("socket(2)");
@ -1166,7 +1165,7 @@ open_unix(class, path, server)
MEMZERO(&sockaddr, struct sockaddr_un, 1); MEMZERO(&sockaddr, struct sockaddr_un, 1);
sockaddr.sun_family = AF_UNIX; sockaddr.sun_family = AF_UNIX;
strncpy(sockaddr.sun_path, path->ptr, sizeof(sockaddr.sun_path)-1); strncpy(sockaddr.sun_path, RSTRING(path)->ptr, sizeof(sockaddr.sun_path)-1);
sockaddr.sun_path[sizeof(sockaddr.sun_path)-1] = '\0'; sockaddr.sun_path[sizeof(sockaddr.sun_path)-1] = '\0';
if (server) { if (server) {
@ -1189,7 +1188,7 @@ open_unix(class, path, server)
sock = sock_new(class, fd); sock = sock_new(class, fd);
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);
fptr->path = strdup(path->ptr); fptr->path = strdup(RSTRING(path)->ptr);
return sock; return sock;
} }
@ -1466,7 +1465,7 @@ setup_domain_and_type(domain, dv, type, tv)
char *ptr; char *ptr;
if (TYPE(domain) == T_STRING) { if (TYPE(domain) == T_STRING) {
Check_SafeStr(domain); SafeStringValue(domain);
ptr = RSTRING(domain)->ptr; ptr = RSTRING(domain)->ptr;
if (strcmp(ptr, "AF_INET") == 0) if (strcmp(ptr, "AF_INET") == 0)
*dv = AF_INET; *dv = AF_INET;
@ -1515,7 +1514,7 @@ setup_domain_and_type(domain, dv, type, tv)
*dv = NUM2INT(domain); *dv = NUM2INT(domain);
} }
if (TYPE(type) == T_STRING) { if (TYPE(type) == T_STRING) {
Check_SafeStr(type); SafeStringValue(type);
ptr = RSTRING(type)->ptr; ptr = RSTRING(type)->ptr;
if (strcmp(ptr, "SOCK_STREAM") == 0) if (strcmp(ptr, "SOCK_STREAM") == 0)
*tv = SOCK_STREAM; *tv = SOCK_STREAM;
@ -1597,7 +1596,7 @@ sock_connect(sock, addr)
OpenFile *fptr; OpenFile *fptr;
int fd; int fd;
Check_Type(addr, T_STRING); StringValue(addr);
rb_str_modify(addr); rb_str_modify(addr);
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);
@ -1615,7 +1614,7 @@ sock_bind(sock, addr)
{ {
OpenFile *fptr; OpenFile *fptr;
Check_Type(addr, T_STRING); StringValue(addr);
rb_str_modify(addr); rb_str_modify(addr);
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);

View file

@ -62,7 +62,7 @@ static VALUE cSyslog_open(int argc, VALUE *argv, VALUE self)
fac = INT2NUM(LOG_USER); fac = INT2NUM(LOG_USER);
} }
Check_SafeStr(ident); SafeStringValue(ident);
syslog_ident = ident; syslog_ident = ident;
syslog_options = opt; syslog_options = opt;
syslog_facility = fac; syslog_facility = fac;

2
file.c
View file

@ -1908,7 +1908,7 @@ rb_stat_init(obj, fname)
{ {
struct stat st, *nst; struct stat st, *nst;
Check_SafeStr(fname); SafeStringValue(fname);
if (stat(RSTRING(fname)->ptr, &st) == -1) { if (stat(RSTRING(fname)->ptr, &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr); rb_sys_fail(RSTRING(fname)->ptr);

View file

@ -680,22 +680,22 @@ An end of a defun is found by moving forward from the beginning of one."
("\\(#\\)[{$@]" 1 (1 . nil)) ("\\(#\\)[{$@]" 1 (1 . nil))
;; the last $' in the string ,'...$' is not variable ;; the last $' in the string ,'...$' is not variable
;; the last ?' in the string ,'...?' is not ascii code ;; the last ?' in the string ,'...?' is not ascii code
("\\(^\\|[[\\s <+(,=]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[\\?\\$]\\('\\)" ("\\(^\\|[[\\s <+(,=]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[?$]\\('\\)"
(2 (7 . nil)) (2 (7 . nil))
(4 (7 . nil))) (4 (7 . nil)))
;; the last $` in the string ,`...$` is not variable ;; the last $` in the string ,`...$` is not variable
;; the last ?` in the string ,`...?` is not ascii code ;; the last ?` in the string ,`...?` is not ascii code
("\\(^\\|[[\\s <+(,=]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[\\?\\$]\\(`\\)" ("\\(^\\|[[\\s <+(,=]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[?$]\\(`\\)"
(2 (7 . nil)) (2 (7 . nil))
(4 (7 . nil))) (4 (7 . nil)))
;; the last $" in the string ,"...$" is not variable ;; the last $" in the string ,"...$" is not variable
;; the last ?" in the string ,"...?" is not ascii code ;; the last ?" in the string ,"...?" is not ascii code
("\\(^\\|[[\\s <+(,=]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[\\?\\$]\\(\"\\)" ("\\(^\\|[[\\s <+(,=]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[?$]\\(\"\\)"
(2 (7 . nil)) (2 (7 . nil))
(4 (7 . nil))) (4 (7 . nil)))
;; $' $" $` .... are variables ;; $' $" $` .... are variables
;; ?' ?" ?` are ascii codes ;; ?' ?" ?` are ascii codes
("[\\?\\$][#\"'`]" 0 (1 . nil)) ("[?$][#\"'`]" 0 (1 . nil))
;; regexps ;; regexps
("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)" ("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
(4 (7 . ?/)) (4 (7 . ?/))

View file

@ -195,13 +195,6 @@ rb_str_to_str(str)
return rb_convert_type(str, T_STRING, "String", "to_str"); return rb_convert_type(str, T_STRING, "String", "to_str");
} }
VALUE
rb_string_value(ptr)
volatile VALUE *ptr;
{
return *ptr = rb_str_to_str(*ptr);
}
static void static void
rb_str_become(str, str2) rb_str_become(str, str2)
VALUE str, str2; VALUE str, str2;
@ -428,6 +421,48 @@ rb_str_format(str, arg)
return rb_f_sprintf(2, argv); return rb_f_sprintf(2, argv);
} }
static int
str_independent(str)
VALUE str;
{
if (OBJ_FROZEN(str)) rb_error_frozen("string");
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
if (!FL_TEST(str, ELTS_SHARED)) return 1;
return 0;
}
static void
str_make_independent(str)
VALUE str;
{
char *ptr;
ptr = ALLOC_N(char, RSTRING(str)->len+1);
if (RSTRING(str)->ptr) {
memcpy(ptr, RSTRING(str)->ptr, RSTRING(str)->len);
}
ptr[RSTRING(str)->len] = 0;
RSTRING(str)->ptr = ptr;
RSTRING(str)->aux.capa = RSTRING(str)->len;
FL_UNSET(str, ELTS_SHARED|STR_ASSOC);
}
void
rb_str_modify(str)
VALUE str;
{
if (str_independent(str)) return;
str_make_independent(str);
}
VALUE
rb_string_value(ptr)
volatile VALUE *ptr;
{
return *ptr = rb_str_to_str(*ptr);
}
VALUE VALUE
rb_str_substr(str, beg, len) rb_str_substr(str, beg, len)
VALUE str; VALUE str;
@ -455,34 +490,6 @@ rb_str_substr(str, beg, len)
return str2; return str2;
} }
static int
str_independent(str)
VALUE str;
{
if (OBJ_FROZEN(str)) rb_error_frozen("string");
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
if (!FL_TEST(str, ELTS_SHARED)) return 1;
return 0;
}
void
rb_str_modify(str)
VALUE str;
{
char *ptr;
if (str_independent(str)) return;
ptr = ALLOC_N(char, RSTRING(str)->len+1);
if (RSTRING(str)->ptr) {
memcpy(ptr, RSTRING(str)->ptr, RSTRING(str)->len);
}
ptr[RSTRING(str)->len] = 0;
RSTRING(str)->ptr = ptr;
RSTRING(str)->aux.capa = RSTRING(str)->len;
FL_UNSET(str, ELTS_SHARED|STR_ASSOC);
}
VALUE VALUE
rb_str_freeze(str) rb_str_freeze(str)
VALUE str; VALUE str;
@ -1610,7 +1617,7 @@ rb_str_replace(str, str2)
memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len); memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len);
} }
OBJ_INFECT(str2, str); OBJ_INFECT(str, str2);
return str; return str;
} }

16
time.c
View file

@ -174,7 +174,7 @@ time_s_at(argc, argv, klass)
if (rb_scan_args(argc, argv, "11", &time, &t) == 2) { if (rb_scan_args(argc, argv, "11", &time, &t) == 2) {
tv.tv_sec = NUM2LONG(time); tv.tv_sec = NUM2LONG(time);
tv.tv_usec = NUM2INT(t); tv.tv_usec = NUM2LONG(t);
} }
else { else {
tv = rb_time_timeval(time); tv = rb_time_timeval(time);
@ -925,7 +925,7 @@ time_plus(time1, time2)
{ {
struct time_object *tobj; struct time_object *tobj;
time_t sec, usec; time_t sec, usec;
double f; double f, d;
GetTimeval(time1, tobj); GetTimeval(time1, tobj);
@ -934,10 +934,11 @@ time_plus(time1, time2)
} }
f = NUM2DBL(time2); f = NUM2DBL(time2);
sec = (time_t)f; sec = (time_t)f;
if (f != (double)sec) { d = f - (double)sec;
if (d >= 1.0 || d <= -1.0) {
rb_raise(rb_eRangeError, "time + %f out of Time range", f); rb_raise(rb_eRangeError, "time + %f out of Time range", f);
} }
usec = tobj->tv.tv_usec + (time_t)((f - (double)sec)*1e6); usec = tobj->tv.tv_usec + (time_t)(d*1e6);
sec = tobj->tv.tv_sec + sec; sec = tobj->tv.tv_sec + sec;
#ifdef NEGATIVE_TIME_T #ifdef NEGATIVE_TIME_T
@ -960,7 +961,7 @@ time_minus(time1, time2)
{ {
struct time_object *tobj; struct time_object *tobj;
time_t sec, usec; time_t sec, usec;
double f; double f, d;
GetTimeval(time1, tobj); GetTimeval(time1, tobj);
if (rb_obj_is_kind_of(time2, rb_cTime)) { if (rb_obj_is_kind_of(time2, rb_cTime)) {
@ -974,10 +975,11 @@ time_minus(time1, time2)
} }
f = NUM2DBL(time2); f = NUM2DBL(time2);
sec = (time_t)f; sec = (time_t)f;
if (f != (double)sec) { d = f - (double)sec;
if (d >= 1.0 || d <= -1.0) {
rb_raise(rb_eRangeError, "time - %f out of Time range", f); rb_raise(rb_eRangeError, "time - %f out of Time range", f);
} }
usec = tobj->tv.tv_usec - (time_t)((f - (double)sec)*1e6); usec = tobj->tv.tv_usec - (time_t)(d*1e6);
sec = tobj->tv.tv_sec - sec; sec = tobj->tv.tv_sec - sec;
#ifdef NEGATIVE_TIME_T #ifdef NEGATIVE_TIME_T
if ((tobj->tv.tv_sec <= 0 && f >= 0 && sec > 0) || if ((tobj->tv.tv_sec <= 0 && f >= 0 && sec > 0) ||

View file

@ -129,6 +129,9 @@ find_class_path(klass)
st_foreach(rb_class_tbl, fc_i, &arg); st_foreach(rb_class_tbl, fc_i, &arg);
} }
if (arg.path) { if (arg.path) {
if (!ROBJECT(klass)->iv_tbl) {
ROBJECT(klass)->iv_tbl = st_init_numtable();
}
st_insert(ROBJECT(klass)->iv_tbl,rb_intern("__classpath__"),arg.path); st_insert(ROBJECT(klass)->iv_tbl,rb_intern("__classpath__"),arg.path);
return arg.path; return arg.path;
} }

View file

@ -1,4 +1,4 @@
#define RUBY_VERSION "1.7.2" #define RUBY_VERSION "1.7.2"
#define RUBY_RELEASE_DATE "2001-12-17" #define RUBY_RELEASE_DATE "2001-12-18"
#define RUBY_VERSION_CODE 172 #define RUBY_VERSION_CODE 172
#define RUBY_RELEASE_CODE 20011217 #define RUBY_RELEASE_CODE 20011218