From d1375688cdde3d094984f7f3a7bffe57306a0bca Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 6 Jul 2000 07:21:26 +0000 Subject: matz git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@816 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 44 +++++++++++ bignum.c | 76 +++++++++++++------ eval.c | 1 + ext/extmk.rb.in | 4 + ext/tcltklib/tcltklib.c | 9 ++- ext/tk/lib/tk.rb | 6 +- io.c | 75 +++++++++++-------- lib/date.rb | 54 ++++++++++++-- lib/mkmf.rb | 4 + lib/profile.rb | 1 - lib/tempfile.rb | 2 +- numeric.c | 190 ++++++++++++++++++++++++++++++++---------------- object.c | 2 + sample/test.rb | 23 +++++- struct.c | 2 +- time.c | 23 +++--- win32/ruby.def | 1 + win32/win32.c | 11 +++ 18 files changed, 384 insertions(+), 144 deletions(-) diff --git a/ChangeLog b/ChangeLog index 656e5dacd3..6c87b9e4ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Thu Jul 6 13:51:57 2000 Nobuyoshi Nakada + + * 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 + + * 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 * win32/win32.c (NtCmdGlob): patterns should be separated and @@ -11,6 +29,26 @@ Wed Jul 5 22:27:56 2000 WATANABE Hirofumi * lib/mkmf.rb: ditto. +Wed Jul 5 09:47:14 2000 Yukihiro Matsumoto + + * 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 * ext/extmk.rb.in: join ' ' -> join(' '). @@ -57,6 +95,12 @@ Tue Jul 4 00:15:23 2000 Dave Thomas * numeric.c (Init_Numeric): forgot to register Numeric#remainder. +Mon Jul 3 23:46:56 2000 Katsuyuki Komatsu + + * 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 * lib/mkmf.rb: use null device if it exists for cross-compiling. diff --git a/bignum.c b/bignum.c index 9a095ae3da..95de973267 100644 --- a/bignum.c +++ b/bignum.c @@ -444,13 +444,6 @@ rb_big2long(x) return num; } -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 6d8b1a5a7b..9ba6b5243f 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 6efcf45986..5b94f975a2 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 93f7745f28..f2e4a22945 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 #include #include #include -#include "ruby.h" -#include "rubysig.h" #ifdef __MACOS__ # include @@ -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 a696d3b9bf..b495a2e2d1 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 725e072fd9..6216a0d359 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 9de49bcbc7..3a7d3c7b1b 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 c042561e13..ae593224e9 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 d94b09da9e..b00caac42e 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 c432285309..0e4c99e5ff 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 01b0c0d40f..b051c4c105 100644 --- a/numeric.c +++ b/numeric.c @@ -133,13 +133,27 @@ 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; @@ -825,6 +872,13 @@ rb_num2fix(val) return INT2FIX(v); } +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; } @@ -1265,13 +1323,6 @@ fix_aref(fix, idx) return INT2FIX(0); } -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 0a764cc75f..1c0b1bf828 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 91355969c9..87106330cc 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 4d9018a611..977d411211 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 a165bafe7f..77257eb030 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 8f5977c53b..ebb37a0d30 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 2bc633a214..e7721178bd 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -11,6 +11,7 @@ */ #include "ruby.h" +#include "rubysig.h" #include #include #include @@ -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; } -- cgit v1.2.3