From c800d0b75d23e2ac8c10674ff41cc25b0c793ddd Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 5 Oct 2004 01:37:46 +0000 Subject: [PATCH] * io.c (rb_fopen): mode string copy at the lowest level. * io.c (rb_io_flags_mode): requires output buffer no more. no allocation needed. * array.c (rb_ary_index): takes a block to compare items in an array. [ruby-talk:113069] [Ruby2] * array.c (rb_ary_rindex): ditto. * marshal.c (r_byte): retrieve pointer from string value for each time. [ruby-dev:24404] * marshal.c (r_bytes0): ditto. * enum.c (sort_by_i): re-entrance check added. [ruby-dev:24399] * io.c (io_read): should freeze all reading buffer. [ruby-dev:24400] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6996 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 22 ++++++++++++++ array.c | 80 ++++++++++++++++++++++++++++++++++----------------- enum.c | 3 ++ io.c | 61 +++++++++++++++------------------------ lib/mathn.rb | 3 ++ lib/pstore.rb | 2 ++ marshal.c | 49 ++++++++++++++++--------------- 7 files changed, 133 insertions(+), 87 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2bbf8b975..337fdf706f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Tue Oct 5 09:53:22 2004 Yukihiro Matsumoto + + * io.c (rb_fopen): mode string copy at the lowest level. + + * io.c (rb_io_flags_mode): requires output buffer no more. no + allocation needed. + + * array.c (rb_ary_index): takes a block to compare items in an + array. [ruby-talk:113069] [Ruby2] + + * array.c (rb_ary_rindex): ditto. + Mon Oct 4 14:03:40 2004 Nobuyoshi Nakada * io.c (rb_file_open_internal, rb_io_reopen): fname might be altered @@ -30,6 +42,16 @@ Sat Oct 2 20:34:05 2004 Nobuyoshi Nakada Sat Oct 2 00:42:20 2004 Yukihiro Matsumoto + * marshal.c (r_byte): retrieve pointer from string value for each + time. [ruby-dev:24404] + + * marshal.c (r_bytes0): ditto. + + * enum.c (sort_by_i): re-entrance check added. [ruby-dev:24399] + + * io.c (io_read): should freeze all reading buffer. + [ruby-dev:24400] + * string.c (rb_str_sum): should use bignums when bits is greater than or equals to sizeof(long)*CHAR_BITS. [ruby-dev:24395] diff --git a/array.c b/array.c index 0166e6dc88..19c16c52e1 100644 --- a/array.c +++ b/array.c @@ -979,27 +979,41 @@ rb_ary_fetch(argc, argv, ary) /* * call-seq: - * array.index(obj) -> int or nil + * array.index(obj) -> int or nil + * array.index {|item| block} -> int or nil * - * Returns the index of the first object in self such that is - * == to obj. Returns nil if - * no match is found. + * Returns the index of the first object in self such that is + * == to obj. If a block is given instead of an + * argument, returns first object for which block is true. + * Returns nil if no match is found. * * a = [ "a", "b", "c" ] - * a.index("b") #=> 1 - * a.index("z") #=> nil + * a.index("b") #=> 1 + * a.index("z") #=> nil + * a.index{|x|x=="b") #=> 1 */ static VALUE -rb_ary_index(ary, val) +rb_ary_index(argc, argv, ary) + int argc; + VALUE *argv; VALUE ary; - VALUE val; { + VALUE val; long i; - for (i=0; ilen; i++) { - if (rb_equal(RARRAY(ary)->ptr[i], val)) - return LONG2NUM(i); + if (rb_scan_args(argc, argv, "01", &val) == 0) { + for (i=0; ilen; i++) { + if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) { + return LONG2NUM(i); + } + } + } + else { + for (i=0; ilen; i++) { + if (rb_equal(RARRAY(ary)->ptr[i], val)) + return LONG2NUM(i); + } } return Qnil; } @@ -1008,29 +1022,43 @@ rb_ary_index(ary, val) * call-seq: * array.rindex(obj) -> int or nil * - * Returns the index of the last object in array - * == to obj. Returns nil if - * no match is found. + * Returns the index of the last object in array + * == to obj. If a block is given instead of an + * argument, returns first object for which block is + * true. Returns nil if no match is found. * * a = [ "a", "b", "b", "b", "c" ] - * a.rindex("b") #=> 3 - * a.rindex("z") #=> nil + * a.rindex("b") #=> 3 + * a.rindex("z") #=> nil + * a.rindex{|x|x=="b") #=> 3 */ static VALUE -rb_ary_rindex(ary, val) +rb_ary_rindex(argc, argv, ary) + int argc; + VALUE *argv; VALUE ary; - VALUE val; { + VALUE val; long i = RARRAY(ary)->len; - while (i--) { - if (i > RARRAY(ary)->len) { - i = RARRAY(ary)->len; - continue; + if (rb_scan_args(argc, argv, "01", &val) == 0) { + while (i--) { + if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) + return LONG2NUM(i); + if (i > RARRAY(ary)->len) { + i = RARRAY(ary)->len; + } + } + } + else { + while (i--) { + if (rb_equal(RARRAY(ary)->ptr[i], val)) + return LONG2NUM(i); + if (i > RARRAY(ary)->len) { + i = RARRAY(ary)->len; + } } - if (rb_equal(RARRAY(ary)->ptr[i], val)) - return LONG2NUM(i); } return Qnil; } @@ -3120,8 +3148,8 @@ Init_Array() rb_define_method(rb_cArray, "length", rb_ary_length, 0); rb_define_alias(rb_cArray, "size", "length"); rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0); - rb_define_method(rb_cArray, "index", rb_ary_index, 1); - rb_define_method(rb_cArray, "rindex", rb_ary_rindex, 1); + rb_define_method(rb_cArray, "index", rb_ary_index, -1); + rb_define_method(rb_cArray, "rindex", rb_ary_rindex, -1); rb_define_method(rb_cArray, "join", rb_ary_join_m, -1); rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0); rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0); diff --git a/enum.c b/enum.c index a329665923..66b9263c85 100644 --- a/enum.c +++ b/enum.c @@ -393,6 +393,9 @@ sort_by_i(i, ary) NODE *memo; v = rb_yield(i); + if (RBASIC(ary)->klass) { + rb_raise(rb_eRuntimeError, "sort_by reentered"); + } memo = rb_node_newnode(NODE_MEMO, v, i, 0); rb_ary_push(ary, (VALUE)memo); return Qnil; diff --git a/io.c b/io.c index 9f34783d0b..b5dddd114b 100644 --- a/io.c +++ b/io.c @@ -1194,8 +1194,8 @@ io_read(argc, argv, io) StringValue(str); rb_str_modify(str); rb_str_resize(str,len); - FL_SET(str, FL_FREEZE); } + FL_SET(str, FL_FREEZE); if (len == 0) return str; READ_CHECK(fptr->f); @@ -2283,37 +2283,26 @@ rb_io_binmode(io) return io; } -char* -rb_io_flags_mode(flags, mode) +static char* +rb_io_flags_mode(flags) int flags; - char *mode; { - char *p = mode; +#ifdef O_BINARY +# define MODE_BINMODE(a,b) ((mode & O_BINARY) ? (a) : (b)) +#else +# define MODE_BINMODE(a,b) (a) +#endif switch (flags & FMODE_READWRITE) { case FMODE_READABLE: - *p++ = 'r'; - break; + return MODE_BINMODE("r", "rb"); case FMODE_WRITABLE: - *p++ = 'w'; - break; + return MODE_BINMODE("w", "wb"); case FMODE_READWRITE: - *p++ = 'r'; - *p++ = '+'; - break; + return MODE_BINMODE("r+", "rb+"); } - *p++ = '\0'; -#ifdef O_BINARY - if (flags & FMODE_BINMODE) { - if (mode[1] == '+') { - mode[1] = 'b'; mode[2] = '+'; mode[3] = '\0'; - } - else { - mode[1] = 'b'; mode[2] = '\0'; - } - } -#endif - return mode; + rb_raise(rb_eArgError, "illegal access mode %o", flags); + return NULL; /* not reached */ } int @@ -2483,12 +2472,15 @@ rb_fopen(fname, mode) const char *mode; { FILE *file; + char mbuf[MODENUM_MAX]; - file = fopen(fname, mode); + strncpy(mbuf, mode, sizeof(mbuf) - 1); + mbuf[sizeof(mbuf) - 1] = 0; + file = fopen(fname, mbuf); if (!file) { if (errno == EMFILE || errno == ENFILE) { rb_gc(); - file = fopen(fname, mode); + file = fopen(fname, mbuf); } if (!file) { rb_sys_fail(fname); @@ -2550,13 +2542,11 @@ rb_file_open_internal(io, fname, mode) const char *fname, *mode; { OpenFile *fptr; - char mbuf[MODENUM_MAX]; MakeOpenFile(io, fptr); - fptr->mode = rb_io_mode_flags(mode); fptr->path = strdup(fname); - fptr->f = rb_fopen(fptr->path, rb_io_flags_mode(fptr->mode, mbuf)); + fptr->f = rb_fopen(fptr->path, rb_io_flags_mode(fptr->mode)); return io; } @@ -2748,13 +2738,13 @@ pipe_open(argc, argv, pname, mode) int modef = rb_io_mode_flags(mode); int pid = 0; OpenFile *fptr; - FILE *fpr, *fpw; VALUE port, arg0; #if defined(HAVE_FORK) int status; struct popen_arg arg; volatile int doexec; #elif defined(_WIN32) + FILE *fpr, *fpw; int openmode = rb_io_mode_modenum(mode); char *prog = NULL; #endif @@ -2861,7 +2851,7 @@ pipe_open(argc, argv, pname, mode) fptr->f = PIPE_FDOPEN(0); } if (modef & FMODE_WRITABLE) { - fpw = PIPE_FDOPEN(1); + FILE *fpw = PIPE_FDOPEN(1); if (fptr->f) fptr->f2 = fpw; else fptr->f = fpw; } @@ -3376,11 +3366,7 @@ rb_io_reopen(argc, argv, file) } if (!NIL_P(nmode)) { - strncpy(mode, StringValuePtr(nmode), sizeof(mode)); - mode[sizeof(mode) - 1] = 0; - } - else { - rb_io_flags_mode(fptr->mode, mode); + fptr->mode = rb_io_mode_flags(StringValuePtr(nmode)); } if (fptr->path) { @@ -3389,9 +3375,8 @@ rb_io_reopen(argc, argv, file) } fptr->path = strdup(RSTRING(fname)->ptr); - fptr->mode = rb_io_mode_flags(mode); if (!fptr->f) { - fptr->f = rb_fopen(fptr->path, mode); + fptr->f = rb_fopen(fptr->path, rb_io_flags_mode(fptr->mode)); if (fptr->f2) { fclose(fptr->f2); fptr->f2 = 0; diff --git a/lib/mathn.rb b/lib/mathn.rb index 2257a4074a..aa2da885f3 100644 --- a/lib/mathn.rb +++ b/lib/mathn.rb @@ -16,6 +16,7 @@ require "matrix.rb" class Integer + remove_method(:gcd2) def gcd2(int) a = self.abs b = int.abs @@ -116,6 +117,7 @@ end class Rational Unify = true + remove_method(:inspect) def inspect format "%s/%s", numerator.inspect, denominator.inspect end @@ -228,6 +230,7 @@ class Rational end module Math + remove_method(:sqrt) def sqrt(a) if a.kind_of?(Complex) abs = sqrt(a.real*a.real + a.image*a.image) diff --git a/lib/pstore.rb b/lib/pstore.rb index c4c6dd56a5..dc4d976a4c 100644 --- a/lib/pstore.rb +++ b/lib/pstore.rb @@ -99,11 +99,13 @@ class PStore content = nil unless read_only file = File.open(@filename, File::RDWR | File::CREAT) + file.binmode file.flock(File::LOCK_EX) commit_new(file) if FileTest.exist?(new_file) content = file.read() else file = File.open(@filename, File::RDONLY) + file.binmode file.flock(File::LOCK_SH) content = (File.read(new_file) rescue file.read()) end diff --git a/marshal.c b/marshal.c index 91eadb4cd7..71c6d16699 100644 --- a/marshal.c +++ b/marshal.c @@ -779,7 +779,8 @@ marshal_dump(argc, argv) } struct load_arg { - char *ptr, *end; + VALUE src; + long offset; st_table *symbols; VALUE data; VALUE proc; @@ -794,18 +795,20 @@ r_byte(arg) { int c; - if (!arg->end) { - VALUE src = (VALUE)arg->ptr; + if (TYPE(arg->src) == T_STRING) { + if (RSTRING(arg->src)->len > arg->offset) { + c = (unsigned char)RSTRING(arg->src)->ptr[arg->offset++]; + } + else { + rb_raise(rb_eArgError, "marshal data too short"); + } + } + else { + VALUE src = arg->src; VALUE v = rb_funcall2(src, s_getc, 0, 0); if (NIL_P(v)) rb_eof_error(); c = (unsigned char)FIX2INT(v); } - else if (arg->ptr < arg->end) { - c = *(unsigned char*)arg->ptr++; - } - else { - rb_raise(rb_eArgError, "marshal data too short"); - } return c; } @@ -869,8 +872,18 @@ r_bytes0(len, arg) VALUE str; if (len == 0) return rb_str_new(0, 0); - if (!arg->end) { - VALUE src = (VALUE)arg->ptr; + if (TYPE(arg->src) == T_STRING) { + if (RSTRING(arg->src)->len > arg->offset) { + str = rb_str_new(RSTRING(arg->src)->ptr+arg->offset, len); + arg->offset += len; + } + else { + too_short: + rb_raise(rb_eArgError, "marshal data too short"); + } + } + else { + VALUE src = arg->src; VALUE n = LONG2NUM(len); str = rb_funcall2(src, s_read, 1, &n); if (NIL_P(str)) goto too_short; @@ -878,14 +891,6 @@ r_bytes0(len, arg) if (RSTRING(str)->len != len) goto too_short; if (OBJ_TAINTED(str)) arg->taint = Qtrue; } - else { - if (arg->ptr + len > arg->end) { - too_short: - rb_raise(rb_eArgError, "marshal data too short"); - } - str = rb_str_new(arg->ptr, len); - arg->ptr += len; - } return str; } @@ -1391,20 +1396,18 @@ marshal_load(argc, argv) if (rb_respond_to(port, rb_intern("to_str"))) { arg.taint = OBJ_TAINTED(port); /* original taintedness */ StringValue(port); /* possible conversion */ - arg.ptr = RSTRING(port)->ptr; - arg.end = arg.ptr + RSTRING(port)->len; } else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) { if (rb_respond_to(port, s_binmode)) { rb_funcall2(port, s_binmode, 0, 0); } arg.taint = Qtrue; - arg.ptr = (char *)port; - arg.end = 0; } else { rb_raise(rb_eTypeError, "instance of IO needed"); } + arg.src = port; + arg.offset = 0; major = r_byte(&arg); minor = r_byte(&arg);