* 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
Родитель 889a620b76
Коммит c800d0b75d
7 изменённых файлов: 133 добавлений и 87 удалений

Просмотреть файл

@ -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]

80
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);

3
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;

61
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;

Просмотреть файл

@ -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)

Просмотреть файл

@ -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

Просмотреть файл

@ -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);