summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-07-06 07:21:26 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-07-06 07:21:26 +0000
commitd1375688cdde3d094984f7f3a7bffe57306a0bca (patch)
treef5320945b9bfd9fc19b133335a7be45076fe03e9
parenta60db057a2a8456f8f5b59a6c5805e25d1d47d34 (diff)
matz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@816 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog44
-rw-r--r--bignum.c76
-rw-r--r--eval.c1
-rw-r--r--ext/extmk.rb.in4
-rw-r--r--ext/tcltklib/tcltklib.c9
-rw-r--r--ext/tk/lib/tk.rb6
-rw-r--r--io.c75
-rw-r--r--lib/date.rb54
-rw-r--r--lib/mkmf.rb4
-rw-r--r--lib/profile.rb1
-rw-r--r--lib/tempfile.rb2
-rw-r--r--numeric.c190
-rw-r--r--object.c2
-rw-r--r--sample/test.rb23
-rw-r--r--struct.c2
-rw-r--r--time.c23
-rw-r--r--win32/ruby.def1
-rw-r--r--win32/win32.c11
18 files changed, 384 insertions, 144 deletions
diff --git a/ChangeLog b/ChangeLog
index 656e5da..6c87b9e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Thu Jul 6 13:51:57 2000 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * object.c (rb_to_id): name may not be symbol or fixnum.
+
+ * struct.c (rb_struct_s_def): name may be nil.
+
+Thu Jul 6 02:09:06 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * bignum.c (bigdivrem): new function to return remainder.
+
+ * numeric.c (fixdivmod): now returns modulo, not remainder.
+
+ * numeric.c (flodivmod): ditto.
+
+ * bignum.c (bigdivmod): ditto.
+
+ * numeric.c (num_modulo): new method; alias to '%'.
+
Thu Jul 6 00:51:43 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* win32/win32.c (NtCmdGlob): patterns should be separated and
@@ -11,6 +29,26 @@ Wed Jul 5 22:27:56 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* lib/mkmf.rb: ditto.
+Wed Jul 5 09:47:14 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * time.c (time_arg): Time::local, Time::gm now take 7th optional
+ argument for usec.
+
+ * numeric.c (num_ceil, etc): default ceil, floor, round, trancate
+ implementation for Numeric, using `to_f'.
+
+ * io.c (rb_io_reopen): clear fptr->path after free() to prevent
+ potential GC crash.
+
+ * io.c (rb_file_s_open): terminate fptr uless null.
+
+ * io.c (rb_file_initialize): ditto.
+
+ * lib/tempfile.rb: specify FILE::CREAT|File::EXCL to open for
+ better security.
+
+ * numeric.c (flo_truncate): new method.
+
Wed Jul 5 01:02:53 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* ext/extmk.rb.in: join ' ' -> join(' ').
@@ -57,6 +95,12 @@ Tue Jul 4 00:15:23 2000 Dave Thomas <Dave@thomases.com>
* numeric.c (Init_Numeric): forgot to register Numeric#remainder.
+Mon Jul 3 23:46:56 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
+
+ * win32/win32.c (myselect, myaccept): disable interrupt while
+ executing accept() or select() to avoid Ctrl-C causes
+ "unknown software exception (0xc0000029)".
+
Mon Jul 3 18:35:41 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* lib/mkmf.rb: use null device if it exists for cross-compiling.
diff --git a/bignum.c b/bignum.c
index 9a095ae..95de973 100644
--- a/bignum.c
+++ b/bignum.c
@@ -445,13 +445,6 @@ rb_big2long(x)
}
static VALUE
-rb_big_to_i(x)
- VALUE x;
-{
- return bignorm(x);
-}
-
-static VALUE
dbl2big(d)
double d;
{
@@ -777,7 +770,7 @@ rb_big_mul(x, y)
}
static void
-bigdivmod(x, y, div, mod)
+bigdivrem(x, y, div, mod)
VALUE x, y;
VALUE *div, *mod;
{
@@ -793,7 +786,7 @@ bigdivmod(x, y, div, mod)
if (ny == 0 && yds[0] == 0) rb_num_zerodiv();
if (nx < ny || nx == ny && BDIGITS(x)[nx - 1] < BDIGITS(y)[ny - 1]) {
if (div) *div = INT2FIX(0);
- if (mod) *mod = bignorm(x);
+ if (mod) *mod = x;
return;
}
xds = BDIGITS(x);
@@ -808,11 +801,9 @@ bigdivmod(x, y, div, mod)
t2 %= dd;
}
RBIGNUM(z)->sign = RBIGNUM(x)->sign==RBIGNUM(y)->sign;
- if (div) *div = bignorm(z);
- if (mod) {
- if (!RBIGNUM(x)->sign) t2 = -(long)t2;
- *mod = INT2NUM(t2);
- }
+ if (!RBIGNUM(x)->sign) t2 = -(long)t2;
+ if (mod) *mod = rb_uint2big(t2);
+ if (div) *div = z;
return;
}
z = bignew(nx==ny?nx+2:nx+1, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
@@ -879,7 +870,6 @@ bigdivmod(x, y, div, mod)
j = (nx==ny ? nx+2 : nx+1) - ny;
for (i = 0;i < j;i++) zds[i] = zds[i+ny];
RBIGNUM(*div)->len = i;
- *div = bignorm(*div);
}
if (mod) { /* just normalize remainder */
*mod = rb_big_clone(z);
@@ -894,7 +884,24 @@ bigdivmod(x, y, div, mod)
}
RBIGNUM(*mod)->len = ny;
RBIGNUM(*mod)->sign = RBIGNUM(x)->sign;
- *mod = bignorm(*mod);
+ }
+}
+
+static void
+bigdivmod(x, y, divp, modp)
+ VALUE x, y;
+ VALUE *divp, *modp;
+{
+ VALUE mod;
+
+ bigdivrem(x, y, divp, &mod);
+ if (RBIGNUM(x)->sign != RBIGNUM(y)->sign && RBIGNUM(mod)->len > 0) {
+ if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
+ if (modp) *modp = bigadd(mod, y, 1);
+ }
+ else {
+ if (divp) *divp = bignorm(*divp);
+ if (modp) *modp = bignorm(mod);
}
}
@@ -918,14 +925,14 @@ rb_big_div(x, y)
default:
return rb_num_coerce_bin(x, y);
}
- bigdivmod(x, y, &z, 0, 0);
+ bigdivmod(x, y, &z, 0);
return z;
}
static VALUE
-rb_big_mod(x, y)
+rb_big_modulo(x, y)
VALUE x, y;
{
VALUE z;
@@ -950,6 +957,32 @@ rb_big_mod(x, y)
return z;
}
+static VALUE
+rb_big_remainder(x, y)
+ VALUE x, y;
+{
+ VALUE z;
+
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = rb_int2big(FIX2LONG(y));
+ break;
+
+ case T_BIGNUM:
+ break;
+
+ case T_FLOAT:
+ y = dbl2big(RFLOAT(y)->value);
+ break;
+
+ default:
+ return rb_num_coerce_bin(x, y);
+ }
+ bigdivrem(x, y, 0, &z);
+
+ return bignorm(z);
+}
+
VALUE
rb_big_divmod(x, y)
VALUE x, y;
@@ -1326,7 +1359,7 @@ rb_big_rand(max, rand)
BDIGITS(v)[len] = ((USHORT)~0) * rand;
}
- return rb_big_mod((VALUE)v, max);
+ return rb_big_modulo((VALUE)v, max);
}
static VALUE
@@ -1357,8 +1390,10 @@ Init_Bignum()
rb_define_method(rb_cBignum, "-", rb_big_minus, 1);
rb_define_method(rb_cBignum, "*", rb_big_mul, 1);
rb_define_method(rb_cBignum, "/", rb_big_div, 1);
- rb_define_method(rb_cBignum, "%", rb_big_mod, 1);
+ rb_define_method(rb_cBignum, "%", rb_big_modulo, 1);
rb_define_method(rb_cBignum, "divmod", rb_big_divmod, 1);
+ rb_define_method(rb_cBignum, "modulo", rb_big_modulo, 1);
+ rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
rb_define_method(rb_cBignum, "**", rb_big_pow, 1);
rb_define_method(rb_cBignum, "&", rb_big_and, 1);
rb_define_method(rb_cBignum, "|", rb_big_or, 1);
@@ -1373,7 +1408,6 @@ Init_Bignum()
rb_define_method(rb_cBignum, "===", rb_big_eq, 1);
rb_define_method(rb_cBignum, "eql?", rb_big_eq, 1);
rb_define_method(rb_cBignum, "hash", rb_big_hash, 0);
- rb_define_method(rb_cBignum, "to_i", rb_big_to_i, 0);
rb_define_method(rb_cBignum, "to_f", rb_big_to_f, 0);
rb_define_method(rb_cBignum, "abs", rb_big_abs, 0);
rb_define_method(rb_cBignum, "size", rb_big_size, 0);
diff --git a/eval.c b/eval.c
index 6d8b1a5..9ba6b52 100644
--- a/eval.c
+++ b/eval.c
@@ -2790,6 +2790,7 @@ rb_eval(self, n)
}
rb_clear_cache_by_id(node->nd_mid);
if (node->nd_noex) { /* toplevel */
+ /* should be upgrade to rb_warn() if no super was called? */
rb_warning("overriding global function `%s'",
rb_id2name(node->nd_mid));
}
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index 6efcf45..5b94f97 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -422,7 +422,11 @@ TARGET = #{target}
DLLIB = $(TARGET).#{$static ? $LIBEXT : "@DLEXT@"}
RUBY = #{ruby_interpreter} -I$(topdir) -I$(hdrdir)/lib
+<<<<<<< extmk.rb.in
+RM = $(RUBY) -r ftools -e "File::rm_f *Dir[ARGV.join(' ')]"
+=======
RM = $(RUBY) -r ftools -e 'File::rm_f(*Dir[ARGV.join(" ")])'
+>>>>>>> 1.20
EXEEXT = @EXEEXT@
diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c
index 93f7745..f2e4a22 100644
--- a/ext/tcltklib/tcltklib.c
+++ b/ext/tcltklib/tcltklib.c
@@ -4,12 +4,13 @@
* Oct. 24, 1997 Y. Matsumoto
*/
+#include "ruby.h"
+#include "rubysig.h"
+#undef EXTERN /* avoid conflict with tcl.h of tcl8.2 or before */
#include <stdio.h>
#include <string.h>
#include <tcl.h>
#include <tk.h>
-#include "ruby.h"
-#include "rubysig.h"
#ifdef __MACOS__
# include <tkMac.h>
@@ -228,11 +229,11 @@ ip_new(self)
/* add ruby command to the interpreter */
#if TCL_MAJOR_VERSION >= 8
DUMP1("Tcl_CreateObjCommand(\"ruby\")");
- Tcl_CreateObjCommand(ptr->ip, "ruby", ip_ruby, (ClientData *)NULL,
+ Tcl_CreateObjCommand(ptr->ip, "ruby", ip_ruby, (ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL);
#else
DUMP1("Tcl_CreateCommand(\"ruby\")");
- Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby, (ClientData *)NULL,
+ Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby, (ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL);
#endif
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index a696d3b..b495a2e 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -527,15 +527,15 @@ module TkCore
tk_call 'tk_messageBox', *hash_kv(keys)
end
- def getOpenFile(keys)
+ def getOpenFile(keys = nil)
tk_call 'tk_getOpenFile', *hash_kv(keys)
end
- def getSaveFile(keys)
+ def getSaveFile(keys = nil)
tk_call 'tk_getSaveFile', *hash_kv(keys)
end
- def chooseColor(keys)
+ def chooseColor(keys = nil)
tk_call 'tk_chooseColor', *hash_kv(keys)
end
diff --git a/io.c b/io.c
index 725e072..6216a0d 100644
--- a/io.c
+++ b/io.c
@@ -132,8 +132,9 @@ rb_io_check_closed(fptr)
if (!fptr) {
rb_raise(rb_eIOError, "uninitialized stream");
}
- if (fptr->f == NULL && fptr->f2 == NULL)
+ if (!fptr->f && !fptr->f2) {
rb_raise(rb_eIOError, "closed stream");
+ }
}
void
@@ -980,10 +981,10 @@ static void
fptr_finalize(fptr)
OpenFile *fptr;
{
- if (fptr->f != NULL) {
+ if (fptr->f) {
fclose(fptr->f);
}
- if (fptr->f2 != NULL) {
+ if (fptr->f2) {
fclose(fptr->f2);
}
}
@@ -993,7 +994,7 @@ rb_io_fptr_finalize(fptr)
OpenFile *fptr;
{
if (!fptr) return;
- if (fptr->f == NULL && fptr->f2 == NULL) return;
+ if (!fptr->f && !fptr->f2) return;
if (fptr->finalize) {
(*fptr->finalize)(fptr);
@@ -1001,11 +1002,11 @@ rb_io_fptr_finalize(fptr)
else {
fptr_finalize(fptr);
}
- fptr->f = fptr->f2 = NULL;
+ fptr->f = fptr->f2 = 0;
if (fptr->path) {
free(fptr->path);
- fptr->path = NULL;
+ fptr->path = 0;
}
}
@@ -1016,7 +1017,7 @@ rb_io_fptr_close(fptr)
int fd;
if (!fptr) return;
- if (fptr->f == NULL && fptr->f2 == NULL) return;
+ if (!fptr->f && !fptr->f2) return;
fd = fileno(fptr->f);
rb_io_fptr_finalize(fptr);
@@ -1295,7 +1296,7 @@ rb_io_flags_mode(flags)
}
static int
-rb_open(fname, flag, mode)
+rb_sysopen(fname, flag, mode)
char *fname;
int flag;
unsigned int mode;
@@ -1323,12 +1324,12 @@ rb_fopen(fname, mode)
FILE *file;
file = fopen(fname, mode);
- if (file == NULL) {
+ if (!file) {
if (errno == EMFILE || errno == ENFILE) {
rb_gc();
file = fopen(fname, mode);
}
- if (file == NULL) {
+ if (!file) {
rb_sys_fail(fname);
}
}
@@ -1346,12 +1347,12 @@ rb_fdopen(fd, mode)
FILE *file;
file = fdopen(fd, mode);
- if (file == NULL) {
+ if (!file) {
if (errno == EMFILE || errno == ENFILE) {
rb_gc();
file = fdopen(fd, mode);
}
- if (file == NULL) {
+ if (!file) {
rb_sys_fail(0);
}
}
@@ -1395,7 +1396,7 @@ rb_file_sysopen_internal(io, fname, flags, mode)
MakeOpenFile(io, fptr);
- fd = rb_open(fname, flags, mode);
+ fd = rb_sysopen(fname, flags, mode);
m = rb_io_flags_mode(flags);
fptr->mode = rb_io_mode_flags2(flags);
fptr->f = rb_fdopen(fd, m);
@@ -1474,13 +1475,13 @@ pipe_finalize(fptr)
OpenFile *fptr;
{
#if !defined (__CYGWIN__)
- if (fptr->f != NULL) {
+ if (fptr->f) {
pclose(fptr->f);
}
- if (fptr->f2 != NULL) {
+ if (fptr->f2) {
pclose(fptr->f2);
}
- fptr->f = fptr->f2 = NULL;
+ fptr->f = fptr->f2 = 0;
#else
fptr_finalize(fptr);
#endif
@@ -1512,7 +1513,7 @@ pipe_open(pname, mode)
#if defined(NT) || defined(DJGPP) || defined(__human68k__)
FILE *f = popen(pname, mode);
- if (f == NULL) rb_sys_fail(pname);
+ if (!f) rb_sys_fail(pname);
else {
NEWOBJ(port, struct RFile);
OBJSETUP(port, rb_cIO, T_FILE);
@@ -1680,6 +1681,11 @@ rb_file_s_open(argc, argv, klass)
Check_SafeStr(fname);
path = RSTRING(fname)->ptr;
+ if (RFILE(io)->fptr) {
+ rb_io_close_m(io);
+ free(RFILE(io)->fptr);
+ RFILE(io)->fptr = 0;
+ }
if (FIXNUM_P(vmode)) {
int flags = NUM2INT(vmode);
int fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
@@ -1687,12 +1693,7 @@ rb_file_s_open(argc, argv, klass)
file = rb_file_sysopen_internal((VALUE)io, path, flags, fmode);
}
else {
- if (NIL_P(vmode)) {
- mode = "r";
- }
- else {
- mode = STR2CSTR(vmode);
- }
+ mode = NIL_P(vmode) ? "r" : STR2CSTR(vmode);
file = rb_file_open_internal((VALUE)io, RSTRING(fname)->ptr, mode);
}
@@ -1854,23 +1855,27 @@ rb_io_reopen(argc, argv, file)
}
GetOpenFile(file, fptr);
- if (fptr->path) free(fptr->path);
+ if (fptr->path) {
+ free(fptr->path);
+ fptr->path = 0;
+ }
+
fptr->path = strdup(RSTRING(fname)->ptr);
fptr->mode = rb_io_mode_flags(mode);
if (!fptr->f) {
fptr->f = rb_fopen(RSTRING(fname)->ptr, mode);
if (fptr->f2) {
fclose(fptr->f2);
- fptr->f2 = NULL;
+ fptr->f2 = 0;
}
return file;
}
- if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == NULL) {
+ if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == 0) {
rb_sys_fail(fptr->path);
}
if (fptr->f2) {
- if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == NULL) {
+ if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == 0) {
rb_sys_fail(fptr->path);
}
}
@@ -2296,6 +2301,11 @@ rb_file_initialize(argc, argv, io)
Check_SafeStr(fname);
path = RSTRING(fname)->ptr;
+ if (RFILE(io)->fptr) {
+ rb_io_close_m(io);
+ free(RFILE(io)->fptr);
+ RFILE(io)->fptr = 0;
+ }
if (FIXNUM_P(vmode)) {
int flags = NUM2INT(vmode);
int fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
@@ -2599,7 +2609,7 @@ rb_f_select(argc, argv, obj)
rb_scan_args(argc, argv, "13", &read, &write, &except, &timeout);
if (NIL_P(timeout)) {
- tp = NULL;
+ tp = 0;
}
else {
timerec = rb_time_interval(timeout);
@@ -2626,7 +2636,7 @@ rb_f_select(argc, argv, obj)
}
}
else
- rp = NULL;
+ rp = 0;
if (!NIL_P(write)) {
Check_Type(write, T_ARRAY);
@@ -2643,7 +2653,7 @@ rb_f_select(argc, argv, obj)
}
}
else
- wp = NULL;
+ wp = 0;
if (!NIL_P(except)) {
Check_Type(except, T_ARRAY);
@@ -2659,8 +2669,9 @@ rb_f_select(argc, argv, obj)
}
}
}
- else
- ep = NULL;
+ else {
+ ep = 0;
+ }
max++;
diff --git a/lib/date.rb b/lib/date.rb
index 9de49bc..3a7d3c7 100644
--- a/lib/date.rb
+++ b/lib/date.rb
@@ -1,8 +1,8 @@
#
# Date.rb -
# $Release Version: $
-# $Revision: 1.1.1.1.4.5 $
-# $Date: 1998/03/03 02:39:34 $
+# $Revision: 1.1.1.2 $
+# $Date: 1999/01/20 04:59:35 $
# by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
@@ -64,14 +64,17 @@ class Date
def month
return @month
end
+ alias mon month
def day
return @day
end
+ alias mday day
def period
return Date.period!(@year, @month, @day)
end
+ protected :period
def jd
return period + 1721423
@@ -89,10 +92,15 @@ class Date
to_s
end
- def day_of_week
+ def wday
return (period + 5) % 7
end
-
+ alias day_of_week wday
+
+ def yday
+ return period - Date.new(@year-1,12,31).period
+ end
+
def name_of_week
return Weektag[self.day_of_week]
end
@@ -148,9 +156,10 @@ class Date
return @year ^ @month ^ @day
end
- def leapyear?
+ def leap?
Date.leapyear(@year) != 1
end
+ alias leapyear? leap?
def _check_date
if @year == nil or @month == nil or @day == nil
@@ -176,6 +185,31 @@ class Date
end
return self
end
+
+ def << (n)
+ self >> -n
+ end
+
+ def >> (n)
+ y = @year
+ m = @month-1
+ d = @day
+
+ m += n
+ y += m/12
+ m = m%12
+ m += 1
+
+ if y == 1752 && m == 9 && d >= 3 && d <= 13
+ d = 2
+ else
+ lasts = Date.daylist(y)
+ if d > lasts[m]
+ d = lasts[m]
+ end
+ end
+ Date.new(y,m,d)
+ end
private :_check_date
end
@@ -213,6 +247,15 @@ def Date.at(d)
return Date.new(yy, mm, dd)
end
+def Date.new3(year,mon=1,day=1)
+ Date.new(year,mon,day)
+end
+
+def Date.today
+ Date.new(*Time.now.to_a[3,3].reverse!)
+end
+
+## private class methods - do not call
def Date.period!(y, m, d)
p = d
dl = Date.daylist(y)
@@ -256,3 +299,4 @@ def Date.jan1!(y)
end
return (d % 7)
end
+
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index c042561..ae59322 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -406,7 +406,11 @@ TARGET = #{target}
DLLIB = $(TARGET).#{CONFIG["DLEXT"]}
RUBY = #{CONFIG["ruby_install_name"]}
+<<<<<<< mkmf.rb
+RM = $(RUBY) -r ftools -e 'File::rm_f *Dir[ARGV.join(" ")]'
+=======
RM = $(RUBY) -r ftools -e 'File::rm_f(*Dir[ARGV.join(" ")])'
+>>>>>>> 1.22
EXEEXT = #{CONFIG["EXEEXT"]}
diff --git a/lib/profile.rb b/lib/profile.rb
index d94b09d..b00caac 100644
--- a/lib/profile.rb
+++ b/lib/profile.rb
@@ -49,7 +49,6 @@ module Profiler__
f.printf "%6.2f %8.2f %8.2f %8d ", d[2]/total*100, sum, d[2], d[0]
f.printf "%8.2f %8.2f %s\n", d[2]*1000/d[0], d[1]*1000/d[0], d[3]
end
- p total
f.close
}
set_trace_func p
diff --git a/lib/tempfile.rb b/lib/tempfile.rb
index c432285..0e4c99e 100644
--- a/lib/tempfile.rb
+++ b/lib/tempfile.rb
@@ -52,7 +52,7 @@ class Tempfile < SimpleDelegator
@clean_files = Tempfile.callback(tmpname, @protect)
ObjectSpace.define_finalizer(self, @clean_files)
- @tmpfile = File.open(tmpname, 'w+')
+ @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL)
@protect[0] = @tmpfile
@tmpname = tmpname
super(@tmpfile)
diff --git a/numeric.c b/numeric.c
index 01b0c0d..b051c4c 100644
--- a/numeric.c
+++ b/numeric.c
@@ -133,14 +133,28 @@ num_divmod(x, y)
}
static VALUE
-num_remainder(x, y)
+num_modulo(x, y)
VALUE x, y;
{
- rb_warn("remainder is deprecated; use %% opearator");
return rb_funcall(x, '%', 1, y);
}
static VALUE
+num_remainder(x, y)
+ VALUE x, y;
+{
+ VALUE z = rb_funcall(x, '%', 1, y);
+
+ if ((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) &&
+ RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) ||
+ (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) &&
+ RTEST(rb_funcall(y, '<', 1, INT2FIX(0))))) {
+ return rb_funcall(z, '-', 1, y);
+ }
+ return z;
+}
+
+static VALUE
num_int_p(num)
VALUE num;
{
@@ -308,7 +322,7 @@ flodivmod(x, y, divp, modp)
double x, y;
double *divp, *modp;
{
- double mod;
+ double div, mod;
#ifdef HAVE_FMOD
mod = fmod(x, y);
@@ -320,10 +334,13 @@ flodivmod(x, y, divp, modp)
mod = x - z * x;
}
#endif
- if (modp) *modp = mod;
- if (divp) {
- *divp = (x - mod) / y;
+ div = (x - mod) / y;
+ if (y*mod < 0) {
+ mod += y;
+ div -= 1.0;
}
+ if (modp) *modp = mod;
+ if (divp) *divp = div;
}
static VALUE
@@ -582,19 +599,63 @@ flo_eql(x, y)
}
static VALUE
-flo_to_i(num)
+flo_to_f(num)
VALUE num;
{
- double f = RFLOAT(num)->value;
- long val;
+ return num;
+}
- if (!FIXABLE(f)) {
- return rb_dbl2big(f);
+static VALUE
+flo_abs(flt)
+ VALUE flt;
+{
+ double val = fabs(RFLOAT(flt)->value);
+ return rb_float_new(val);
+}
+
+static VALUE
+flo_zero_p(num)
+ VALUE num;
+{
+ if (RFLOAT(num)->value == 0.0) {
+ return Qtrue;
}
- val = f;
- return INT2FIX(val);
+ return Qfalse;
+}
+
+static VALUE flo_is_nan_p(num)
+ VALUE num;
+{
+
+ double value = RFLOAT(num)->value;
+
+ return isnan(value) ? Qtrue : Qfalse;
}
+static VALUE flo_is_infinite_p(num)
+ VALUE num;
+{
+ double value = RFLOAT(num)->value;
+
+ if (isinf(value)) {
+ return INT2FIX( value < 0 ? -1 : +1 );
+ }
+
+ return Qnil;
+}
+
+static VALUE flo_is_finite_p(num)
+ VALUE num;
+{
+ double value = RFLOAT(num)->value;
+
+ if (isinf(value) || isnan(value))
+ return Qfalse;
+
+ return Qtrue;
+}
+
+
static VALUE
flo_floor(num)
VALUE num;
@@ -641,64 +702,50 @@ flo_round(num)
}
static VALUE
-flo_to_f(num)
+flo_truncate(num)
VALUE num;
{
- return num;
+ double f = RFLOAT(num)->value;
+ long val;
+
+ if (f > 0.0) f = floor(f);
+ if (f < 0.0) f = ceil(f);
+
+ if (!FIXABLE(f)) {
+ return rb_dbl2big(f);
+ }
+ val = f;
+ return INT2FIX(val);
}
static VALUE
-flo_abs(flt)
- VALUE flt;
+num_floor(num)
+ VALUE num;
{
- double val = fabs(RFLOAT(flt)->value);
- return rb_float_new(val);
+ return flo_floor(rb_Float(num));
}
static VALUE
-flo_zero_p(num)
+num_ceil(num)
VALUE num;
{
- if (RFLOAT(num)->value == 0.0) {
- return Qtrue;
- }
- return Qfalse;
+ return flo_ceil(rb_Float(num));
}
-static VALUE flo_is_nan_p(num)
- VALUE num;
-{
-
- double value = RFLOAT(num)->value;
-
- return isnan(value) ? Qtrue : Qfalse;
-}
-
-static VALUE flo_is_infinite_p(num)
- VALUE num;
-{
- double value = RFLOAT(num)->value;
-
- if (isinf(value)) {
- return INT2FIX( value < 0 ? -1 : +1 );
- }
-
- return Qnil;
+static VALUE
+num_round(num)
+ VALUE num;
+{
+ return flo_round(rb_Float(num));
}
-
-static VALUE flo_is_finite_p(num)
- VALUE num;
-{
- double value = RFLOAT(num)->value;
-
- if (isinf(value) || isnan(value))
- return Qfalse;
-
- return Qtrue;
+static VALUE
+num_truncate(num)
+ VALUE num;
+{
+ return flo_truncate(rb_Float(num));
}
-
static VALUE
to_integer(val)
VALUE val;
@@ -826,6 +873,13 @@ rb_num2fix(val)
}
static VALUE
+int_to_i(num)
+ VALUE num;
+{
+ return num;
+}
+
+static VALUE
int_int_p(num)
VALUE num;
{
@@ -1017,6 +1071,10 @@ fixdivmod(x, y, divp, modp)
div = x / y;
}
mod = x - div*y;
+ if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
+ mod += y;
+ div -= 1;
+ }
if (divp) *divp = div;
if (modp) *modp = mod;
}
@@ -1266,13 +1324,6 @@ fix_aref(fix, idx)
}
static VALUE
-fix_to_i(num)
- VALUE num;
-{
- return num;
-}
-
-static VALUE
fix_to_f(num)
VALUE num;
{
@@ -1507,6 +1558,7 @@ Init_Numeric()
rb_define_method(rb_cNumeric, "===", num_equal, 1);
rb_define_method(rb_cNumeric, "eql?", num_eql, 1);
rb_define_method(rb_cNumeric, "divmod", num_divmod, 1);
+ rb_define_method(rb_cNumeric, "modulo", num_modulo, 1);
rb_define_method(rb_cNumeric, "remainder", num_remainder, 1);
rb_define_method(rb_cNumeric, "abs", num_abs, 0);
@@ -1514,6 +1566,11 @@ Init_Numeric()
rb_define_method(rb_cNumeric, "zero?", num_zero_p, 0);
rb_define_method(rb_cNumeric, "nonzero?", num_nonzero_p, 0);
+ rb_define_method(rb_cNumeric, "floor", num_floor, 0);
+ rb_define_method(rb_cNumeric, "ceil", num_ceil, 0);
+ rb_define_method(rb_cNumeric, "round", num_round, 0);
+ rb_define_method(rb_cNumeric, "truncate", num_truncate, 0);
+
rb_cInteger = rb_define_class("Integer", rb_cNumeric);
rb_define_method(rb_cInteger, "integer?", int_int_p, 0);
rb_define_method(rb_cInteger, "upto", int_upto, 1);
@@ -1524,6 +1581,11 @@ Init_Numeric()
rb_define_method(rb_cInteger, "succ", int_succ, 0);
rb_define_method(rb_cInteger, "next", int_succ, 0);
rb_define_method(rb_cInteger, "chr", int_chr, 0);
+ rb_define_method(rb_cInteger, "to_i", int_to_i, 0);
+ rb_define_method(rb_cInteger, "floor", int_to_i, 0);
+ rb_define_method(rb_cInteger, "ceil", int_to_i, 0);
+ rb_define_method(rb_cInteger, "round", int_to_i, 0);
+ rb_define_method(rb_cInteger, "truncate", int_to_i, 0);
rb_cFixnum = rb_define_class("Fixnum", rb_cInteger);
rb_include_module(rb_cFixnum, rb_mPrecision);
@@ -1543,6 +1605,7 @@ Init_Numeric()
rb_define_method(rb_cFixnum, "*", fix_mul, 1);
rb_define_method(rb_cFixnum, "/", fix_div, 1);
rb_define_method(rb_cFixnum, "%", fix_mod, 1);
+ rb_define_method(rb_cFixnum, "modulo", fix_mod, 1);
rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);
rb_define_method(rb_cFixnum, "**", fix_pow, 1);
@@ -1564,7 +1627,6 @@ Init_Numeric()
rb_define_method(rb_cFixnum, "<<", fix_lshift, 1);
rb_define_method(rb_cFixnum, ">>", fix_rshift, 1);
- rb_define_method(rb_cFixnum, "to_i", fix_to_i, 0);
rb_define_method(rb_cFixnum, "to_f", fix_to_f, 0);
rb_define_method(rb_cFixnum, "succ", fix_succ, 0);
@@ -1592,6 +1654,7 @@ Init_Numeric()
rb_define_method(rb_cFloat, "*", flo_mul, 1);
rb_define_method(rb_cFloat, "/", flo_div, 1);
rb_define_method(rb_cFloat, "%", flo_mod, 1);
+ rb_define_method(rb_cFloat, "modulo", flo_mod, 1);
rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
rb_define_method(rb_cFloat, "**", flo_pow, 1);
rb_define_method(rb_cFloat, "==", flo_eq, 1);
@@ -1602,14 +1665,15 @@ Init_Numeric()
rb_define_method(rb_cFloat, "<=", flo_le, 1);
rb_define_method(rb_cFloat, "eql?", flo_eql, 1);
rb_define_method(rb_cFloat, "hash", flo_hash, 0);
- rb_define_method(rb_cFloat, "to_i", flo_to_i, 0);
rb_define_method(rb_cFloat, "to_f", flo_to_f, 0);
rb_define_method(rb_cFloat, "abs", flo_abs, 0);
rb_define_method(rb_cFloat, "zero?", flo_zero_p, 0);
+ rb_define_method(rb_cFloat, "to_i", flo_truncate, 0);
rb_define_method(rb_cFloat, "floor", flo_floor, 0);
rb_define_method(rb_cFloat, "ceil", flo_ceil, 0);
rb_define_method(rb_cFloat, "round", flo_round, 0);
+ rb_define_method(rb_cFloat, "truncate", flo_truncate, 0);
rb_define_method(rb_cFloat, "nan?", flo_is_nan_p, 0);
rb_define_method(rb_cFloat, "infinite?", flo_is_infinite_p, 0);
diff --git a/object.c b/object.c
index 0a764cc..1c0b1bf 100644
--- a/object.c
+++ b/object.c
@@ -718,6 +718,8 @@ rb_to_id(name)
case T_SYMBOL:
id = SYM2ID(name);
break;
+ default:
+ rb_raise(rb_eTypeError, "%s is not a symbol", STR2CSTR(rb_inspect(name)));
}
return id;
}
diff --git a/sample/test.rb b/sample/test.rb
index 9135596..8710633 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -550,6 +550,17 @@ ok($x == [0,0])
IterTest.new([[8,8]]).each8 { |x| $x = x }
ok($x == [8,8])
+check "float"
+ok(2.6.floor == 2)
+ok(-2.6.floor == -3)
+ok(2.6.ceil == 3)
+ok(-2.6.ceil == -2)
+ok(2.6.truncate == 2)
+ok(-2.6.truncate == -2)
+ok(2.6.round == 3)
+ok(-2.4.truncate == -2)
+ok((13.4 % 1 - 0.4).abs < 0.0001)
+
check "bignum"
def fact(n)
return 1 if n == 0
@@ -609,10 +620,14 @@ ok($good)
b = 10**80
a = b * 9 + 7
-ok(7 ==a % b)
-ok(7 ==a % -b)
-ok(-7 == (-a) % b)
-ok(-7 == (-a) % (-b))
+ok(7 == a.modulo(b))
+ok(-b + 7 == a.modulo(-b))
+ok(b + -7 == (-a).modulo(b))
+ok(-7 == (-a).modulo(-b))
+ok(7 == a.remainder(b))
+ok(7 == a.remainder(-b))
+ok(-7 == (-a).remainder(b))
+ok(-7 == (-a).remainder(-b))
check "string & char"
diff --git a/struct.c b/struct.c
index 4d9018a..977d411 100644
--- a/struct.c
+++ b/struct.c
@@ -235,7 +235,7 @@ rb_struct_s_def(argc, argv, klass)
id = rb_to_id(RARRAY(rest)->ptr[i]);
RARRAY(rest)->ptr[i] = ID2SYM(id);
}
- if (TYPE(name) != T_STRING) {
+ if (!NIL_P(name) && TYPE(name) != T_STRING) {
id = rb_to_id(name);
rb_ary_unshift(rest, ID2SYM(id));
name = Qnil;
diff --git a/time.c b/time.c
index a165baf..77257eb 100644
--- a/time.c
+++ b/time.c
@@ -200,12 +200,13 @@ obj2long(obj)
}
static void
-time_arg(argc, argv, tm)
+time_arg(argc, argv, tm, usec)
int argc;
VALUE *argv;
struct tm *tm;
+ time_t *usec;
{
- VALUE v[6];
+ VALUE v[7];
int i;
MEMZERO(tm, struct tm, 1);
@@ -216,10 +217,12 @@ time_arg(argc, argv, tm)
v[3] = argv[2];
v[4] = argv[1];
v[5] = argv[0];
+ *usec = 0;
tm->tm_isdst = RTEST(argv[9]) ? 1 : 0;
}
else {
- rb_scan_args(argc, argv, "15", &v[0],&v[1],&v[2],&v[3],&v[4],&v[5]);
+ rb_scan_args(argc, argv, "16", &v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6]);
+ *usec = (argc == 7) ? NUM2INT(v[6]) : 0;
}
tm->tm_year = obj2long(v[0]);
@@ -370,18 +373,19 @@ make_time_t(tptr, utc_or_local)
}
static VALUE
-time_utc_or_local(argc, argv, utc_or_local, klass)
+time_utc_or_local(argc, argv, utc_p, klass)
int argc;
VALUE *argv;
- int utc_or_local;
+ int utc_p;
VALUE klass;
{
struct tm tm;
VALUE time;
+ time_t usec;
- time_arg(argc, argv, &tm);
- time = time_new_internal(klass, make_time_t(&tm, utc_or_local), 0);
- if (utc_or_local) return time_gmtime(time);
+ time_arg(argc, argv, &tm, &usec);
+ time = time_new_internal(klass, make_time_t(&tm, utc_p), usec);
+ if (utc_p) return time_gmtime(time);
return time_localtime(time);
}
@@ -420,7 +424,7 @@ time_to_f(time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return rb_float_new((double)tobj->tv.tv_sec+(double)tobj->tv.tv_usec/1000000);
+ return rb_float_new((double)tobj->tv.tv_sec+(double)tobj->tv.tv_usec/1e6);
}
static VALUE
@@ -1065,6 +1069,7 @@ Init_Time()
rb_define_method(rb_cTime, "localtime", time_localtime, 0);
rb_define_method(rb_cTime, "gmtime", time_gmtime, 0);
+ rb_define_method(rb_cTime, "utc", time_gmtime, 0);
rb_define_method(rb_cTime, "ctime", time_asctime, 0);
rb_define_method(rb_cTime, "asctime", time_asctime, 0);
rb_define_method(rb_cTime, "to_s", time_to_s, 0);
diff --git a/win32/ruby.def b/win32/ruby.def
index 8f5977c..ebb37a0 100644
--- a/win32/ruby.def
+++ b/win32/ruby.def
@@ -377,6 +377,7 @@ EXPORTS
rb_hash_new
rb_hash_aref
rb_hash_aset
+ rb_hash_delete_if
rb_path_check
rb_env_path_tainted
ruby_setenv
diff --git a/win32/win32.c b/win32/win32.c
index 2bc633a..e772117 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -11,6 +11,7 @@
*/
#include "ruby.h"
+#include "rubysig.h"
#include <fcntl.h>
#include <process.h>
#include <sys/stat.h>
@@ -1884,6 +1885,7 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
fd_set file_rd;
fd_set file_wr;
int file_nfds;
+ int trap_immediate = rb_trap_immediate;
if (!NtSocketsInitialized++) {
StartSockets();
@@ -1902,6 +1904,8 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
if (wr) *wr = file_wr;
return file_nfds;
}
+ if (trap_immediate)
+ TRAP_END;
if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
errno = WSAGetLastError();
switch (errno) {
@@ -1910,6 +1914,8 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
break;
}
}
+ if (trap_immediate)
+ TRAP_BEG;
return r;
}
@@ -1949,12 +1955,17 @@ SOCKET
myaccept (SOCKET s, struct sockaddr *addr, int *addrlen)
{
SOCKET r;
+ int trap_immediate = rb_trap_immediate;
if (!NtSocketsInitialized++) {
StartSockets();
}
+ if (trap_immediate)
+ TRAP_END;
if ((r = accept (TO_SOCKET(s), addr, addrlen)) == INVALID_SOCKET)
errno = WSAGetLastError();
+ if (trap_immediate)
+ TRAP_BEG;
return r;
}