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

* 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
This commit is contained in:
matz 2004-10-05 01:37:46 +00:00
parent 889a620b76
commit c800d0b75d
7 changed files with 133 additions and 87 deletions

View file

@ -1,3 +1,15 @@
Tue Oct 5 09:53:22 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <nobu@ruby-lang.org> Mon Oct 4 14:03:40 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* io.c (rb_file_open_internal, rb_io_reopen): fname might be altered * 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 <nobu@ruby-lang.org>
Sat Oct 2 00:42:20 2004 Yukihiro Matsumoto <matz@ruby-lang.org> Sat Oct 2 00:42:20 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 * string.c (rb_str_sum): should use bignums when bits is greater
than or equals to sizeof(long)*CHAR_BITS. [ruby-dev:24395] than or equals to sizeof(long)*CHAR_BITS. [ruby-dev:24395]

80
array.c
View file

@ -979,27 +979,41 @@ rb_ary_fetch(argc, argv, ary)
/* /*
* call-seq: * 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 <i>self</i> such that is * Returns the index of the first object in <i>self</i> such that is
* <code>==</code> to <i>obj</i>. Returns <code>nil</code> if * <code>==</code> to <i>obj</i>. If a block is given instead of an
* no match is found. * argument, returns first object for which <em>block</em> is true.
* Returns <code>nil</code> if no match is found.
* *
* a = [ "a", "b", "c" ] * a = [ "a", "b", "c" ]
* a.index("b") #=> 1 * a.index("b") #=> 1
* a.index("z") #=> nil * a.index("z") #=> nil
* a.index{|x|x=="b") #=> 1
*/ */
static VALUE static VALUE
rb_ary_index(ary, val) rb_ary_index(argc, argv, ary)
int argc;
VALUE *argv;
VALUE ary; VALUE ary;
VALUE val;
{ {
VALUE val;
long i; long i;
for (i=0; i<RARRAY(ary)->len; i++) { if (rb_scan_args(argc, argv, "01", &val) == 0) {
if (rb_equal(RARRAY(ary)->ptr[i], val)) for (i=0; i<RARRAY(ary)->len; i++) {
return LONG2NUM(i); if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
return LONG2NUM(i);
}
}
}
else {
for (i=0; i<RARRAY(ary)->len; i++) {
if (rb_equal(RARRAY(ary)->ptr[i], val))
return LONG2NUM(i);
}
} }
return Qnil; return Qnil;
} }
@ -1008,29 +1022,43 @@ rb_ary_index(ary, val)
* call-seq: * call-seq:
* array.rindex(obj) -> int or nil * array.rindex(obj) -> int or nil
* *
* Returns the index of the last object in <i>array</i> * Returns the index of the last object in <i>array</i>
* <code>==</code> to <i>obj</i>. Returns <code>nil</code> if * <code>==</code> to <i>obj</i>. If a block is given instead of an
* no match is found. * argument, returns first object for which <em>block</em> is
* true. Returns <code>nil</code> if no match is found.
* *
* a = [ "a", "b", "b", "b", "c" ] * a = [ "a", "b", "b", "b", "c" ]
* a.rindex("b") #=> 3 * a.rindex("b") #=> 3
* a.rindex("z") #=> nil * a.rindex("z") #=> nil
* a.rindex{|x|x=="b") #=> 3
*/ */
static VALUE static VALUE
rb_ary_rindex(ary, val) rb_ary_rindex(argc, argv, ary)
int argc;
VALUE *argv;
VALUE ary; VALUE ary;
VALUE val;
{ {
VALUE val;
long i = RARRAY(ary)->len; long i = RARRAY(ary)->len;
while (i--) { if (rb_scan_args(argc, argv, "01", &val) == 0) {
if (i > RARRAY(ary)->len) { while (i--) {
i = RARRAY(ary)->len; if (RTEST(rb_yield(RARRAY(ary)->ptr[i])))
continue; 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; return Qnil;
} }
@ -3120,8 +3148,8 @@ Init_Array()
rb_define_method(rb_cArray, "length", rb_ary_length, 0); rb_define_method(rb_cArray, "length", rb_ary_length, 0);
rb_define_alias(rb_cArray, "size", "length"); rb_define_alias(rb_cArray, "size", "length");
rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0); 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, "index", rb_ary_index, -1);
rb_define_method(rb_cArray, "rindex", rb_ary_rindex, 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, "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_m, 0);
rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0); rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);

3
enum.c
View file

@ -393,6 +393,9 @@ sort_by_i(i, ary)
NODE *memo; NODE *memo;
v = rb_yield(i); v = rb_yield(i);
if (RBASIC(ary)->klass) {
rb_raise(rb_eRuntimeError, "sort_by reentered");
}
memo = rb_node_newnode(NODE_MEMO, v, i, 0); memo = rb_node_newnode(NODE_MEMO, v, i, 0);
rb_ary_push(ary, (VALUE)memo); rb_ary_push(ary, (VALUE)memo);
return Qnil; return Qnil;

61
io.c
View file

@ -1194,8 +1194,8 @@ io_read(argc, argv, io)
StringValue(str); StringValue(str);
rb_str_modify(str); rb_str_modify(str);
rb_str_resize(str,len); rb_str_resize(str,len);
FL_SET(str, FL_FREEZE);
} }
FL_SET(str, FL_FREEZE);
if (len == 0) return str; if (len == 0) return str;
READ_CHECK(fptr->f); READ_CHECK(fptr->f);
@ -2283,37 +2283,26 @@ rb_io_binmode(io)
return io; return io;
} }
char* static char*
rb_io_flags_mode(flags, mode) rb_io_flags_mode(flags)
int 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) { switch (flags & FMODE_READWRITE) {
case FMODE_READABLE: case FMODE_READABLE:
*p++ = 'r'; return MODE_BINMODE("r", "rb");
break;
case FMODE_WRITABLE: case FMODE_WRITABLE:
*p++ = 'w'; return MODE_BINMODE("w", "wb");
break;
case FMODE_READWRITE: case FMODE_READWRITE:
*p++ = 'r'; return MODE_BINMODE("r+", "rb+");
*p++ = '+';
break;
} }
*p++ = '\0'; rb_raise(rb_eArgError, "illegal access mode %o", flags);
#ifdef O_BINARY return NULL; /* not reached */
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;
} }
int int
@ -2483,12 +2472,15 @@ rb_fopen(fname, mode)
const char *mode; const char *mode;
{ {
FILE *file; 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 (!file) {
if (errno == EMFILE || errno == ENFILE) { if (errno == EMFILE || errno == ENFILE) {
rb_gc(); rb_gc();
file = fopen(fname, mode); file = fopen(fname, mbuf);
} }
if (!file) { if (!file) {
rb_sys_fail(fname); rb_sys_fail(fname);
@ -2550,13 +2542,11 @@ rb_file_open_internal(io, fname, mode)
const char *fname, *mode; const char *fname, *mode;
{ {
OpenFile *fptr; OpenFile *fptr;
char mbuf[MODENUM_MAX];
MakeOpenFile(io, fptr); MakeOpenFile(io, fptr);
fptr->mode = rb_io_mode_flags(mode); fptr->mode = rb_io_mode_flags(mode);
fptr->path = strdup(fname); 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; return io;
} }
@ -2748,13 +2738,13 @@ pipe_open(argc, argv, pname, mode)
int modef = rb_io_mode_flags(mode); int modef = rb_io_mode_flags(mode);
int pid = 0; int pid = 0;
OpenFile *fptr; OpenFile *fptr;
FILE *fpr, *fpw;
VALUE port, arg0; VALUE port, arg0;
#if defined(HAVE_FORK) #if defined(HAVE_FORK)
int status; int status;
struct popen_arg arg; struct popen_arg arg;
volatile int doexec; volatile int doexec;
#elif defined(_WIN32) #elif defined(_WIN32)
FILE *fpr, *fpw;
int openmode = rb_io_mode_modenum(mode); int openmode = rb_io_mode_modenum(mode);
char *prog = NULL; char *prog = NULL;
#endif #endif
@ -2861,7 +2851,7 @@ pipe_open(argc, argv, pname, mode)
fptr->f = PIPE_FDOPEN(0); fptr->f = PIPE_FDOPEN(0);
} }
if (modef & FMODE_WRITABLE) { if (modef & FMODE_WRITABLE) {
fpw = PIPE_FDOPEN(1); FILE *fpw = PIPE_FDOPEN(1);
if (fptr->f) fptr->f2 = fpw; if (fptr->f) fptr->f2 = fpw;
else fptr->f = fpw; else fptr->f = fpw;
} }
@ -3376,11 +3366,7 @@ rb_io_reopen(argc, argv, file)
} }
if (!NIL_P(nmode)) { if (!NIL_P(nmode)) {
strncpy(mode, StringValuePtr(nmode), sizeof(mode)); fptr->mode = rb_io_mode_flags(StringValuePtr(nmode));
mode[sizeof(mode) - 1] = 0;
}
else {
rb_io_flags_mode(fptr->mode, mode);
} }
if (fptr->path) { if (fptr->path) {
@ -3389,9 +3375,8 @@ rb_io_reopen(argc, argv, file)
} }
fptr->path = strdup(RSTRING(fname)->ptr); fptr->path = strdup(RSTRING(fname)->ptr);
fptr->mode = rb_io_mode_flags(mode);
if (!fptr->f) { 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) { if (fptr->f2) {
fclose(fptr->f2); fclose(fptr->f2);
fptr->f2 = 0; fptr->f2 = 0;

View file

@ -16,6 +16,7 @@ require "matrix.rb"
class Integer class Integer
remove_method(:gcd2)
def gcd2(int) def gcd2(int)
a = self.abs a = self.abs
b = int.abs b = int.abs
@ -116,6 +117,7 @@ end
class Rational class Rational
Unify = true Unify = true
remove_method(:inspect)
def inspect def inspect
format "%s/%s", numerator.inspect, denominator.inspect format "%s/%s", numerator.inspect, denominator.inspect
end end
@ -228,6 +230,7 @@ class Rational
end end
module Math module Math
remove_method(:sqrt)
def sqrt(a) def sqrt(a)
if a.kind_of?(Complex) if a.kind_of?(Complex)
abs = sqrt(a.real*a.real + a.image*a.image) abs = sqrt(a.real*a.real + a.image*a.image)

View file

@ -99,11 +99,13 @@ class PStore
content = nil content = nil
unless read_only unless read_only
file = File.open(@filename, File::RDWR | File::CREAT) file = File.open(@filename, File::RDWR | File::CREAT)
file.binmode
file.flock(File::LOCK_EX) file.flock(File::LOCK_EX)
commit_new(file) if FileTest.exist?(new_file) commit_new(file) if FileTest.exist?(new_file)
content = file.read() content = file.read()
else else
file = File.open(@filename, File::RDONLY) file = File.open(@filename, File::RDONLY)
file.binmode
file.flock(File::LOCK_SH) file.flock(File::LOCK_SH)
content = (File.read(new_file) rescue file.read()) content = (File.read(new_file) rescue file.read())
end end

View file

@ -779,7 +779,8 @@ marshal_dump(argc, argv)
} }
struct load_arg { struct load_arg {
char *ptr, *end; VALUE src;
long offset;
st_table *symbols; st_table *symbols;
VALUE data; VALUE data;
VALUE proc; VALUE proc;
@ -794,18 +795,20 @@ r_byte(arg)
{ {
int c; int c;
if (!arg->end) { if (TYPE(arg->src) == T_STRING) {
VALUE src = (VALUE)arg->ptr; 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); VALUE v = rb_funcall2(src, s_getc, 0, 0);
if (NIL_P(v)) rb_eof_error(); if (NIL_P(v)) rb_eof_error();
c = (unsigned char)FIX2INT(v); 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; return c;
} }
@ -869,8 +872,18 @@ r_bytes0(len, arg)
VALUE str; VALUE str;
if (len == 0) return rb_str_new(0, 0); if (len == 0) return rb_str_new(0, 0);
if (!arg->end) { if (TYPE(arg->src) == T_STRING) {
VALUE src = (VALUE)arg->ptr; 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); VALUE n = LONG2NUM(len);
str = rb_funcall2(src, s_read, 1, &n); str = rb_funcall2(src, s_read, 1, &n);
if (NIL_P(str)) goto too_short; if (NIL_P(str)) goto too_short;
@ -878,14 +891,6 @@ r_bytes0(len, arg)
if (RSTRING(str)->len != len) goto too_short; if (RSTRING(str)->len != len) goto too_short;
if (OBJ_TAINTED(str)) arg->taint = Qtrue; 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; return str;
} }
@ -1391,20 +1396,18 @@ marshal_load(argc, argv)
if (rb_respond_to(port, rb_intern("to_str"))) { if (rb_respond_to(port, rb_intern("to_str"))) {
arg.taint = OBJ_TAINTED(port); /* original taintedness */ arg.taint = OBJ_TAINTED(port); /* original taintedness */
StringValue(port); /* possible conversion */ 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)) { else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) {
if (rb_respond_to(port, s_binmode)) { if (rb_respond_to(port, s_binmode)) {
rb_funcall2(port, s_binmode, 0, 0); rb_funcall2(port, s_binmode, 0, 0);
} }
arg.taint = Qtrue; arg.taint = Qtrue;
arg.ptr = (char *)port;
arg.end = 0;
} }
else { else {
rb_raise(rb_eTypeError, "instance of IO needed"); rb_raise(rb_eTypeError, "instance of IO needed");
} }
arg.src = port;
arg.offset = 0;
major = r_byte(&arg); major = r_byte(&arg);
minor = r_byte(&arg); minor = r_byte(&arg);