From aa92750f27e519c225d9bb50e59ed063857e0c04 Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 6 Dec 2004 15:31:26 +0000 Subject: * process.c (proc_setgroups): [ruby-dev:25081] * re.c (rb_reg_eqq): document fix. [ruby-talk:122541] * io.c (io_fread): take VALUE argument. * ext/socket/socket.c (sock_connect): use rb_str_new4(). [ruby-dev:25052] * eval.c (rb_yield_0): [ruby-dev:25051] * io.c (io_write): remove rb_str_locktmp(). [ruby-dev:25050] * io.c (io_fwrite): takes VALUE string as an argument. [ruby-dev:25050] * ext/socket/socket.c (sock_connect): remove rb_str_locktmp(). [ruby-dev:25050] * ext/socket/socket.c (udp_connect): [ruby-dev:25045] * ext/socket/socket.c (udp_bind): ditto. * ext/socket/socket.c (udp_send): ditto. * ext/socket/socket.c (bsock_send): ditto. * ext/socket/socket.c (s_recvfrom): ditto. * hash.c (rb_hash_hash): should provide "hash" method where "eql?" is redefined. [ruby-talk:122482] * ext/socket/socket.c (bsock_setsockopt): [ruby-dev:25039] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7482 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 44 +++++++++++++++++++++++++++++++++++ eval.c | 17 ++++++++++---- ext/socket/socket.c | 26 +++++++++++---------- hash.c | 44 +++++++++++++++++++++++++++++++++++ io.c | 62 ++++++++++++++++++++++++------------------------- lib/debug.rb | 2 +- process.c | 4 ++-- re.c | 4 ++-- sample/test.rb | 31 +++++++++++++++++++++++++ test/socket/test_tcp.rb | 4 +++- 10 files changed, 184 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6647c4dbdd..500887744a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Tue Dec 7 00:27:37 2004 Yukihiro Matsumoto + + * process.c (proc_setgroups): [ruby-dev:25081] + Mon Dec 6 23:07:57 2004 Tanaka Akira * configure.in: check -lsocket for socketpair and shutdown. @@ -35,6 +39,10 @@ Mon Dec 6 19:40:40 2004 WATANABE Hirofumi * Makefile.in (.y.c): simplify the rule. +Mon Dec 6 18:08:10 2004 Yukihiro Matsumoto + + * re.c (rb_reg_eqq): document fix. [ruby-talk:122541] + Mon Dec 6 17:49:30 2004 NAKAMURA Usaku * eval.c (run_trap_eval): add prototype for Microsoft compiler. @@ -62,6 +70,15 @@ Mon Dec 6 17:15:17 2004 Nobuyoshi Nakada * test/socket/test_udp.rb (TestUDPSocket#test_bind): UDPSocket#bind dumps core. [ruby-dev:25057] +Mon Dec 6 09:59:23 2004 Yukihiro Matsumoto + + * io.c (io_fread): take VALUE argument. + + * ext/socket/socket.c (sock_connect): use rb_str_new4(). + [ruby-dev:25052] + + * eval.c (rb_yield_0): [ruby-dev:25051] + Mon Dec 6 01:32:31 2004 GOTOU Yuuzou * ext/openssl/ossl_pkey_rsa.c (ossl_rsa_public_encrypt, @@ -88,6 +105,29 @@ Sun Dec 5 00:54:32 2004 WATANABE Hirofumi * mkconfig.rb: setup library paths before requiring library. [ruby-core:03892] +Sat Dec 4 22:54:15 2004 Yukihiro Matsumoto + + * io.c (io_write): remove rb_str_locktmp(). [ruby-dev:25050] + + * io.c (io_fwrite): takes VALUE string as an argument. + [ruby-dev:25050] + + * ext/socket/socket.c (sock_connect): remove rb_str_locktmp(). + [ruby-dev:25050] + + * ext/socket/socket.c (udp_connect): [ruby-dev:25045] + + * ext/socket/socket.c (udp_bind): ditto. + + * ext/socket/socket.c (udp_send): ditto. + + * ext/socket/socket.c (bsock_send): ditto. + + * ext/socket/socket.c (s_recvfrom): ditto. + + * hash.c (rb_hash_hash): should provide "hash" method where "eql?" + is redefined. [ruby-talk:122482] + Sat Dec 4 21:29:05 2004 Minero Aoki * lib/fileutils.rb: (In previous commit) new method chown. @@ -124,6 +164,10 @@ Sat Dec 4 14:28:56 2004 Dave Thomas The lines before :section: are removed, and identical lines at the end are also removed if present. +Sat Dec 4 00:35:08 2004 Yukihiro Matsumoto + + * ext/socket/socket.c (bsock_setsockopt): [ruby-dev:25039] + Fri Dec 3 12:25:21 2004 Nobuyoshi Nakada * st.h: fix prototype for C++. diff --git a/eval.c b/eval.c index 896e549b62..1643c45062 100644 --- a/eval.c +++ b/eval.c @@ -694,6 +694,7 @@ struct BLOCK { #define BLOCK_D_SCOPE 1 #define BLOCK_LAMBDA 2 +#define BLOCK_FROM_METHOD 4 static struct BLOCK *ruby_block; static unsigned long block_unique = 0; @@ -1006,8 +1007,7 @@ static VALUE rb_yield_0 _((VALUE, VALUE, VALUE, int, int)); #define YIELD_LAMBDA_CALL 1 #define YIELD_PROC_CALL 2 -#define YIELD_PROC_BLOCK 4 -#define YIELD_PUBLIC_DEF 8 +#define YIELD_PUBLIC_DEF 4 #define YIELD_FUNC_AVALUE 1 #define YIELD_FUNC_SVALUE 2 @@ -4575,6 +4575,12 @@ break_jump(retval) static VALUE bmcall _((VALUE, VALUE)); static VALUE method_arity _((VALUE)); +static VALUE +kk() +{ + return rb_proc_new(rb_yield, Qnil); +} + static VALUE rb_yield_0(val, self, klass, flags, avalue) VALUE val, self, klass; /* OK */ @@ -4721,7 +4727,7 @@ rb_yield_0(val, self, klass, flags, avalue) if (val == Qundef && node->nd_state != YIELD_FUNC_SVALUE) val = Qnil; } - if ((flags&YIELD_PROC_BLOCK) && RTEST(block->block_obj)) { + if ((block->flags&BLOCK_FROM_METHOD) && RTEST(block->block_obj)) { struct BLOCK *data, _block; Data_Get_Struct(block->block_obj, struct BLOCK, data); _block = *data; @@ -8200,10 +8206,8 @@ proc_invoke(proc, args, self, klass) if (klass != ruby_frame->last_class) klass = rb_obj_class(proc); bvar = rb_block_proc(); - pcall |= YIELD_PROC_BLOCK; } - PUSH_VARS(); ruby_wrapper = data->wrapper; ruby_dyna_vars = data->dyna_vars; @@ -9197,6 +9201,7 @@ method_proc(method) bdata->body->nd_file = mdata->body->nd_file; nd_set_line(bdata->body, nd_line(mdata->body)); bdata->body->nd_state = YIELD_FUNC_SVALUE; + bdata->flags |= BLOCK_FROM_METHOD; return proc; } @@ -9367,6 +9372,8 @@ Init_Proc() rb_define_method(rb_cProc, "to_proc", proc_to_self, 0); rb_define_method(rb_cProc, "binding", proc_binding, 0); + rb_define_global_function("kk", kk, 0); + rb_define_global_function("proc", rb_block_proc, 0); rb_define_global_function("lambda", proc_lambda, 0); diff --git a/ext/socket/socket.c b/ext/socket/socket.c index de49c7398c..9f8e747841 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -285,7 +285,6 @@ bsock_setsockopt(sock, lev, optname, val) rb_secure(2); level = NUM2INT(lev); option = NUM2INT(optname); - GetOpenFile(sock, fptr); switch (TYPE(val)) { case T_FIXNUM: @@ -306,6 +305,7 @@ bsock_setsockopt(sock, lev, optname, val) break; } + GetOpenFile(sock, fptr); if (setsockopt(fptr->fd, level, option, v, vlen) < 0) rb_sys_fail(fptr->path); @@ -379,13 +379,13 @@ bsock_send(argc, argv, sock) rb_secure(4); rb_scan_args(argc, argv, "21", &mesg, &flags, &to); + StringValue(mesg); + if (!NIL_P(to)) StringValue(to); GetOpenFile(sock, fptr); fd = fptr->fd; rb_thread_fd_writable(fd); - StringValue(mesg); retry: if (!NIL_P(to)) { - StringValue(to); n = sendto(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags), (struct sockaddr*)RSTRING(to)->ptr, RSTRING(to)->len); } @@ -461,6 +461,7 @@ s_recvfrom(sock, argc, argv, from) if (flg == Qnil) flags = 0; else flags = NUM2INT(flg); + buflen = NUM2INT(len); GetOpenFile(sock, fptr); if (rb_io_read_pending(fptr)) { @@ -468,16 +469,17 @@ s_recvfrom(sock, argc, argv, from) } fd = fptr->fd; - buflen = NUM2INT(len); str = rb_tainted_str_new(0, buflen); retry: - rb_str_locktmp(str); rb_thread_wait_fd(fd); + rb_io_check_closed(fptr); + if (RSTRING(str)->len != buflen) { + rb_raise(rb_eRuntimeError, "buffer string modified"); + } TRAP_BEG; slen = recvfrom(fd, RSTRING(str)->ptr, buflen, flags, (struct sockaddr*)buf, &alen); TRAP_END; - rb_str_unlocktmp(str); if (slen < 0) { if (rb_io_wait_readable(fd)) { @@ -1459,8 +1461,8 @@ udp_connect(sock, host, port) VALUE ret; rb_secure(3); - GetOpenFile(sock, fptr); arg.res = sock_addrinfo(host, port, SOCK_DGRAM, 0); + GetOpenFile(sock, fptr); arg.fd = fptr->fd; ret = rb_ensure(udp_connect_internal, (VALUE)&arg, RUBY_METHOD_FUNC(freeaddrinfo), (VALUE)arg.res); @@ -1476,8 +1478,8 @@ udp_bind(sock, host, port) struct addrinfo *res0, *res; rb_secure(3); - GetOpenFile(sock, fptr); res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0); + GetOpenFile(sock, fptr); for (res = res0; res; res = res->ai_next) { if (bind(fptr->fd, res->ai_addr, res->ai_addrlen) < 0) { continue; @@ -1507,9 +1509,9 @@ udp_send(argc, argv, sock) rb_secure(4); rb_scan_args(argc, argv, "4", &mesg, &flags, &host, &port); - GetOpenFile(sock, fptr); - res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0); StringValue(mesg); + res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0); + GetOpenFile(sock, fptr); for (res = res0; res; res = res->ai_next) { retry: n = sendto(fptr->fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags), @@ -1979,13 +1981,13 @@ sock_connect(sock, addr) { OpenFile *fptr; int fd, n; + volatile VALUE tmpaddr; StringValue(addr); + addr = rb_str_new4(addr); GetOpenFile(sock, fptr); fd = fptr->fd; - rb_str_locktmp(addr); n = ruby_connect(fd, (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len, 0); - rb_str_unlocktmp(addr); if (n < 0) { rb_sys_fail("connect(2)"); } diff --git a/hash.c b/hash.c index f3cf068fa2..16f6325955 100644 --- a/hash.c +++ b/hash.c @@ -1497,6 +1497,49 @@ rb_hash_eql(hash1, hash2) return hash_equal(hash1, hash2, Qtrue); } + +rb_hash_hash_i(key, value, hp) + VALUE key, value; + long *hp; +{ + long h = *hp; + VALUE n; + + h = (h << 1) | (h<0 ? 1 : 0); + n = rb_hash(key); + h ^= NUM2LONG(n); + h = (h << 1) | (h<0 ? 1 : 0); + n = rb_hash(value); + h ^= NUM2LONG(n); + + *hp = h; + return ST_CONTINUE; +} + +/* + * call-seq: + * hash.hash -> fixnum + * + * Compute a hash-code for this hash. Two hashes with the same content + * will have the same hash code (and will compare using eql?). + */ + +static VALUE +rb_hash_hash(hash) + VALUE hash; +{ + long h; + VALUE n; + + h = RHASH(hash)->tbl->num_entries; + rb_hash_foreach(hash, rb_hash_hash_i, (VALUE)&h); + h = (h << 1) | (h<0 ? 1 : 0); + n = rb_hash(RHASH(hash)->ifnone); + h ^= NUM2LONG(n); + + return LONG2FIX(h); +} + static int rb_hash_invert_i(key, value, hash) VALUE key, value; @@ -2430,6 +2473,7 @@ Init_Hash() rb_define_method(rb_cHash,"==", rb_hash_equal, 1); rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1); + rb_define_method(rb_cHash,"hash", rb_hash_hash, 0); rb_define_method(rb_cHash,"[]", rb_hash_aref, 1); rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1); rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2); diff --git a/io.c b/io.c index 1a721ef946..d40e21cc20 100644 --- a/io.c +++ b/io.c @@ -456,14 +456,14 @@ rb_io_wait_writable(f) } /* writing functions */ -long -io_fwrite(ptr, len, fptr) - const char *ptr; - long len; +static long +io_fwrite(str, fptr) + VALUE str; OpenFile *fptr; { - long n, r; + long len, n, r, offset = 0; + len = RSTRING(str)->len; if ((n = len) <= 0) return n; if (fptr->wbuf == NULL && !(fptr->mode & FMODE_SYNC)) { fptr->wbuf_off = 0; @@ -473,14 +473,14 @@ io_fwrite(ptr, len, fptr) } if ((fptr->mode & FMODE_SYNC) || (fptr->wbuf && fptr->wbuf_capa <= fptr->wbuf_len + len) || - ((fptr->mode & FMODE_LINEBUF) && memchr(ptr, '\n', len))) { + ((fptr->mode & FMODE_LINEBUF) && memchr(RSTRING(str)->ptr+offset, '\n', len))) { /* xxx: use writev to avoid double write if available */ if (fptr->wbuf_len+len <= fptr->wbuf_capa) { if (fptr->wbuf_capa < fptr->wbuf_off+fptr->wbuf_len+len) { MEMMOVE(fptr->wbuf, fptr->wbuf+fptr->wbuf_off, char, fptr->wbuf_len); fptr->wbuf_off = 0; } - MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, ptr, char, len); + MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING(str)->ptr+offset, char, len); fptr->wbuf_len += len; n = 0; } @@ -493,17 +493,18 @@ io_fwrite(ptr, len, fptr) } retry: TRAP_BEG; - r = write(fptr->fd, ptr, n); + r = write(fptr->fd, RSTRING(str)->ptr+offset, n); TRAP_END; /* xxx: signal handler may modify given string. */ if (r == n) return len; if (0 <= r) { - ptr += r; + offset += r; n -= r; errno = EAGAIN; } if (rb_io_wait_writable(fptr->fd)) { rb_io_check_closed(fptr); - goto retry; + if (offset < RSTRING(str)->len) + goto retry; } return -1L; } @@ -513,7 +514,7 @@ io_fwrite(ptr, len, fptr) MEMMOVE(fptr->wbuf, fptr->wbuf+fptr->wbuf_off, char, fptr->wbuf_len); fptr->wbuf_off = 0; } - MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, ptr, char, len); + MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING(str)->ptr+offset, char, len); fptr->wbuf_len += len; return len; } @@ -530,7 +531,7 @@ rb_io_fwrite(ptr, len, f) of.f = f; of.mode = FMODE_WRITABLE; of.path = NULL; - return io_fwrite(ptr, len, &of); + return io_fwrite(rb_str_new(ptr, len), &of); } /* @@ -572,9 +573,7 @@ io_write(io, str) GetOpenFile(io, fptr); rb_io_check_writable(fptr); - rb_str_locktmp(str); - n = io_fwrite(RSTRING(str)->ptr, RSTRING(str)->len, fptr); - rb_str_unlocktmp(str); + n = io_fwrite(str, fptr); if (n == -1L) rb_sys_fail(fptr->path); return LONG2FIX(n); @@ -1048,19 +1047,20 @@ read_buffered_data(char *ptr, long len, OpenFile *fptr) return n; } -long -io_fread(ptr, len, fptr) - char *ptr; - long len; +static long +io_fread(str, offset, fptr) + VALUE str; + long offset; OpenFile *fptr; { + long len = RSTRING(str)->len - offset; long n = len; int c; while (n > 0) { - c = read_buffered_data(ptr, n, fptr); + c = read_buffered_data(RSTRING(str)->ptr+offset, n, fptr); if (c > 0) { - ptr += c; + offset += c; if ((n -= c) <= 0) break; } rb_thread_wait_fd(fptr->fd); @@ -1069,7 +1069,8 @@ io_fread(ptr, len, fptr) if (c < 0) { break; } - *ptr++ = c; + RSTRING(str)->ptr[offset++] = c; + if (offset > RSTRING(str)->len) break; n--; } return len - n; @@ -1082,11 +1083,16 @@ rb_io_fread(ptr, len, f) FILE *f; { OpenFile of; + VALUE str; + long n; of.fd = fileno(f); of.f = f; of.mode = FMODE_READABLE; - return io_fread(ptr, len, &of); + str = rb_str_new(ptr, len); + n = io_fread(str, 0, &of); + MEMCPY(ptr, RSTRING(str)->ptr, char, n); + return n; } #ifndef S_ISREG @@ -1137,10 +1143,8 @@ read_all(fptr, siz, str) rb_str_resize(str, siz); } for (;;) { - rb_str_locktmp(str); READ_CHECK(fptr); - n = io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr); - rb_str_unlocktmp(str); + n = io_fread(str, bytes, fptr); if (n == 0 && bytes == 0) { break; } @@ -1316,13 +1320,11 @@ io_read(argc, argv, io) rb_io_check_readable(fptr); if (len == 0) return str; - rb_str_locktmp(str); READ_CHECK(fptr); if (RSTRING(str)->len != len) { rb_raise(rb_eRuntimeError, "buffer string modified"); } - n = io_fread(RSTRING(str)->ptr, len, fptr); - rb_str_unlocktmp(str); + n = io_fread(str, 0, fptr); if (n == 0) { if (!fptr->f) return Qnil; rb_str_resize(str, 0); @@ -2273,7 +2275,6 @@ rb_io_sysread(argc, argv, io) if (READ_DATA_BUFFERED(fptr)) { rb_raise(rb_eIOError, "sysread for buffered IO"); } - rb_str_locktmp(str); n = fptr->fd; rb_thread_wait_fd(fptr->fd); @@ -2285,7 +2286,6 @@ rb_io_sysread(argc, argv, io) n = read(fptr->fd, RSTRING(str)->ptr, ilen); TRAP_END; - rb_str_unlocktmp(str); if (n == -1) { rb_sys_fail(fptr->path); } diff --git a/lib/debug.rb b/lib/debug.rb index 1b12188a76..cd2025fc13 100644 --- a/lib/debug.rb +++ b/lib/debug.rb @@ -541,7 +541,7 @@ class Context stdout.print < + b[reak] [file:|class:] b[reak] [class.] set breakpoint to some position wat[ch] set watchpoint to some expression diff --git a/process.c b/process.c index c3b9647520..c40e75f810 100644 --- a/process.c +++ b/process.c @@ -2708,10 +2708,10 @@ proc_setgroups(VALUE obj, VALUE ary) groups[i] = NUM2INT(g); } else { - gr = getgrnam(RSTRING(g)->ptr); + gr = getgrnam(RSTRING(tmp)->ptr); if (gr == NULL) rb_raise(rb_eArgError, - "can't find group for %s", RSTRING(g)->ptr); + "can't find group for %s", RSTRING(tmp)->ptr); groups[i] = gr->gr_gid; } } diff --git a/re.c b/re.c index 661848c8d2..b8bb851be1 100644 --- a/re.c +++ b/re.c @@ -1555,8 +1555,8 @@ rb_reg_match(re, str) * * a = "HELLO" * case a - * when /^a-z*$/; print "Lower case\n" - * when /^A-Z*$/; print "Upper case\n" + * when /^[a-z]*$/; print "Lower case\n" + * when /^[A-Z]*$/; print "Upper case\n" * else; print "Mixed case\n" * end * diff --git a/sample/test.rb b/sample/test.rb index aed9e51b6e..37afe6e7b8 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -1365,6 +1365,37 @@ end ITER_TEST4.new.foo(44){55} +class ITER_TEST5 + def tt(aa) + aa + end + + def uu(a) + class << self + define_method(:tt) do |sym| + super(sym) + end + end + end + + def xx(*x) + x.size + end +end + +a = ITER_TEST5.new +a.uu(12) +test_ok(a.tt(1) == 1) + +class ITER_TEST6 < ITER_TEST5 + def xx(*a) + a << 12 + super + end +end + +test_ok(ITER_TEST6.new.xx([24]) == 2) + test_check "float" test_ok(2.6.floor == 2) test_ok((-2.6).floor == -3) diff --git a/test/socket/test_tcp.rb b/test/socket/test_tcp.rb index 9320164096..65100cf360 100644 --- a/test/socket/test_tcp.rb +++ b/test/socket/test_tcp.rb @@ -20,6 +20,8 @@ class TestTCPSocket < Test::Unit::TestCase s.replace "a" if s.length == 0x10000 } } - assert_raise(SocketError) {s.recvfrom(0x10000)} + assert_raise(RuntimeError) { + open("/tmp/n", "w"){|f| f.puts(data = s.recvfrom(0x10000))} + } end end if defined?(TCPSocket) -- cgit v1.2.3