summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--array.c80
-rw-r--r--enum.c3
-rw-r--r--io.c61
-rw-r--r--lib/mathn.rb3
-rw-r--r--lib/pstore.rb2
-rw-r--r--marshal.c49
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 <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>
* 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>
+ * 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 <i>self</i> such that is
- * <code>==</code> to <i>obj</i>. Returns <code>nil</code> if
- * no match is found.
+ * Returns the index of the first object in <i>self</i> such that is
+ * <code>==</code> to <i>obj</i>. If a block is given instead of an
+ * 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.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; i<RARRAY(ary)->len; i++) {
- if (rb_equal(RARRAY(ary)->ptr[i], val))
- return LONG2NUM(i);
+ if (rb_scan_args(argc, argv, "01", &val) == 0) {
+ for (i=0; i<RARRAY(ary)->len; 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;
}
@@ -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 <i>array</i>
- * <code>==</code> to <i>obj</i>. Returns <code>nil</code> if
- * no match is found.
+ * Returns the index of the last object in <i>array</i>
+ * <code>==</code> to <i>obj</i>. If a block is given instead of an
+ * 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.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;
- }
- *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';
- }
+ return MODE_BINMODE("r+", "rb+");
}
-#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);