summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog31
-rw-r--r--array.c14
-rw-r--r--compar.c19
-rw-r--r--enum.c25
-rw-r--r--eval.c62
-rw-r--r--ext/pty/pty.c3
-rw-r--r--intern.h2
-rw-r--r--range.c6
-rw-r--r--sample/test.rb27
-rw-r--r--time.c28
10 files changed, 149 insertions, 68 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b659eb6a0..cf2ed3a8a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Tue May 20 00:09:41 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/pty/pty.c (pty_finalize_syswait): join (using Thread#value)
+ before detach pid. [ruby-talk:71519]
+
+Mon May 19 23:02:10 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (PUSH_FRAME): save outer ruby_block. [ruby-list:37677],
+ [ruby-dev:20202]
+
+ * eval.c (BEGIN_CALLARGS): restore outer block by using
+ ruby_block->outer.
+
+ * eval.c (block_pass): do not alter block->prev, but block->outer.
+
+ * array.c (get_inspect_tbl): warning on wrong condition.
+
Mon May 19 16:13:57 2003 Minero Aoki <aamine@loveruby.net>
* class.c: add #include "version.h".
@@ -6,6 +23,19 @@ Mon May 19 16:13:57 2003 Minero Aoki <aamine@loveruby.net>
* string.c: ditto.
+Mon May 19 15:33:27 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (localjump_xvalue): renamed exitstatus to exit_value
+ since it's not exit "status" after all.
+
+ * eval.c (localjump_error): add reason to LocalJumpError.
+
+ * compar.c (rb_cmpint): raise error via rb_cmperr(), if cmp value
+ is nil. now take new 2 arguments.
+
+ * time.c (time_cmp): 2003-05-16 fix was incomplete.
+ (ruby-bugs-ja:PR#458)
+
Mon May 19 14:42:50 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* object.c (rb_mod_cmp): stupid comparison fixed.
@@ -76,6 +106,7 @@ Fri May 16 23:55:50 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
Fri May 16 12:40:40 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (block_pass): chain previous block to the pushing block.
+ [ruby-list:37677]
* time.c (time_cmp): does not compare with numbers for
interchangeability. (ruby-bugs-ja:PR#458)
diff --git a/array.c b/array.c
index c557ab2d15..d53bf496d2 100644
--- a/array.c
+++ b/array.c
@@ -935,10 +935,12 @@ get_inspect_tbl(create)
{
VALUE inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key);
- if (create && NIL_P(inspect_tbl)) {
- tbl_init:
- inspect_tbl = rb_ary_new();
- rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl);
+ if (NIL_P(inspect_tbl)) {
+ if (create) {
+ tbl_init:
+ inspect_tbl = rb_ary_new();
+ rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl);
+ }
}
else if (TYPE(inspect_tbl) != T_ARRAY) {
rb_warn("invalid inspect_tbl value");
@@ -1084,7 +1086,7 @@ sort_1(a, b)
VALUE *a, *b;
{
VALUE retval = rb_yield(rb_assoc_new(*a, *b));
- return rb_cmpint(retval);
+ return rb_cmpint(retval, *a, *b);
}
static int
@@ -1104,7 +1106,7 @@ sort_2(ap, bp)
}
retval = rb_funcall(a, id_cmp, 1, b);
- return rb_cmpint(retval);
+ return rb_cmpint(retval, a, b);
}
static VALUE
diff --git a/compar.c b/compar.c
index bb90125bff..d6cca36137 100644
--- a/compar.c
+++ b/compar.c
@@ -17,9 +17,12 @@ VALUE rb_mComparable;
static ID cmp;
int
-rb_cmpint(val)
- VALUE val;
+rb_cmpint(val, a, b)
+ VALUE val, a, b;
{
+ if (NIL_P(val)) {
+ rb_cmperr(a, b);
+ }
if (FIXNUM_P(val)) return FIX2INT(val);
if (TYPE(val) == T_BIGNUM) {
if (RBIGNUM(val)->sign) return 1;
@@ -43,7 +46,7 @@ rb_cmperr(x, y)
else {
classname = rb_obj_classname(y);
}
- rb_raise(rb_eArgError, "comparison of %s to %s failed",
+ rb_raise(rb_eArgError, "comparison of %s with %s failed",
rb_obj_classname(x), classname);
}
@@ -60,7 +63,7 @@ cmp_equal(x, y)
c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return Qnil;
if (c == INT2FIX(0)) return Qtrue;
- if (rb_cmpint(c) == 0) return Qtrue;
+ if (rb_cmpint(c, x, y) == 0) return Qtrue;
return Qfalse;
}
@@ -71,7 +74,7 @@ cmp_gt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return cmperr();
- if (rb_cmpint(c) > 0) return Qtrue;
+ if (rb_cmpint(c, x, y) > 0) return Qtrue;
return Qfalse;
}
@@ -82,7 +85,7 @@ cmp_ge(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return cmperr();
- if (rb_cmpint(c) >= 0) return Qtrue;
+ if (rb_cmpint(c, x, y) >= 0) return Qtrue;
return Qfalse;
}
@@ -93,7 +96,7 @@ cmp_lt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return cmperr();
- if (rb_cmpint(c) < 0) return Qtrue;
+ if (rb_cmpint(c, x, y) < 0) return Qtrue;
return Qfalse;
}
@@ -104,7 +107,7 @@ cmp_le(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return cmperr();
- if (rb_cmpint(c) <= 0) return Qtrue;
+ if (rb_cmpint(c, x, y) <= 0) return Qtrue;
return Qfalse;
}
diff --git a/enum.c b/enum.c
index 6b76f4f710..ddefbd6c2c 100644
--- a/enum.c
+++ b/enum.c
@@ -156,23 +156,23 @@ collect_all(i, ary)
}
static VALUE
-enum_to_a(obj)
+enum_collect(obj)
VALUE obj;
{
VALUE ary = rb_ary_new();
- rb_iterate(rb_each, obj, collect_all, ary);
+ rb_iterate(rb_each, obj, rb_block_given_p() ? collect_i : collect_all, ary);
return ary;
}
static VALUE
-enum_collect(obj)
+enum_to_a(obj)
VALUE obj;
{
VALUE ary = rb_ary_new();
- rb_iterate(rb_each, obj, rb_block_given_p() ? collect_i : collect_all, ary);
+ rb_iterate(rb_each, obj, collect_all, ary);
return ary;
}
@@ -264,7 +264,7 @@ sort_by_cmp(a, b)
VALUE retval;
retval = rb_funcall(RARRAY(*a)->ptr[0], id_cmp, 1, RARRAY(*b)->ptr[0]);
- return rb_cmpint(retval);
+ return rb_cmpint(retval, *a, *b);
}
static VALUE
@@ -274,7 +274,12 @@ enum_sort_by(obj)
VALUE ary;
long i;
- ary = rb_ary_new2((TYPE(obj) == T_ARRAY) ? RARRAY(obj)->len : 2000);
+ if (TYPE(obj) == T_ARRAY) {
+ ary = rb_ary_new2(RARRAY(obj)->len);
+ }
+ else {
+ ary = rb_ary_new();
+ }
rb_iterate(rb_each, obj, sort_by_i, ary);
if (RARRAY(ary)->len > 1) {
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), sort_by_cmp);
@@ -374,7 +379,7 @@ min_i(i, memo)
}
else {
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
- if (rb_cmpint(cmp) < 0) {
+ if (rb_cmpint(cmp, i, memo->u1.value) < 0) {
memo->u1.value = i;
}
}
@@ -393,7 +398,7 @@ min_ii(i, memo)
}
else {
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
- if (rb_cmpint(cmp) < 0) {
+ if (rb_cmpint(cmp, i, memo->u1.value) < 0) {
memo->u1.value = i;
}
}
@@ -425,7 +430,7 @@ max_i(i, memo)
}
else {
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
- if (rb_cmpint(cmp) > 0) {
+ if (rb_cmpint(cmp, i, memo->u1.value) > 0) {
memo->u1.value = i;
}
}
@@ -444,7 +449,7 @@ max_ii(i, memo)
}
else {
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
- if (rb_cmpint(cmp) > 0) {
+ if (rb_cmpint(cmp, i, memo->u1.value) > 0) {
memo->u1.value = i;
}
}
diff --git a/eval.c b/eval.c
index c1538301b7..0bc1fea016 100644
--- a/eval.c
+++ b/eval.c
@@ -628,6 +628,7 @@ struct BLOCK {
struct RVarmap *dyna_vars;
VALUE orig_thread;
VALUE wrapper;
+ struct BLOCK *outer;
struct BLOCK *prev;
};
@@ -658,6 +659,7 @@ new_blktag()
_block.frame.node = ruby_current_node;\
_block.scope = ruby_scope; \
_block.prev = ruby_block; \
+ _block.outer = ruby_block; \
_block.iter = ruby_iter->iter; \
_block.vmode = scope_vmode; \
_block.flags = BLOCK_D_SCOPE; \
@@ -1477,20 +1479,45 @@ rb_eval_string_wrap(str, state)
}
static void
-localjump_error(mesg, status)
+localjump_error(mesg, status, reason)
const char *mesg;
VALUE status;
+ int reason;
{
VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);
- rb_iv_set(exc, "@status", status);
+ VALUE id;
+
+ rb_iv_set(exc, "@exit_value", status);
+ switch (reason) {
+ case TAG_BREAK:
+ id = rb_intern("break"); break;
+ case TAG_REDO:
+ id = rb_intern("redo"); break;
+ case TAG_RETRY:
+ id = rb_intern("retry"); break;
+ case TAG_NEXT:
+ id = rb_intern("next"); break;
+ case TAG_RETURN:
+ id = rb_intern("return"); break;
+ default:
+ id = rb_intern("noreason"); break;
+ }
+ rb_iv_set(exc, "@reason", ID2SYM(id));
rb_exc_raise(exc);
}
static VALUE
-localjump_exitstatus(exc)
+localjump_xvalue(exc)
+ VALUE exc;
+{
+ return rb_iv_get(exc, "@exit_value");
+}
+
+static VALUE
+localjump_reason(exc)
VALUE exc;
{
- return rb_iv_get(exc, "@status");
+ return rb_iv_get(exc, "@reason");
}
static void
@@ -1505,19 +1532,19 @@ jump_tag_but_local_jump(state)
case 0:
break;
case TAG_RETURN:
- localjump_error("unexpected return", val);
+ localjump_error("unexpected return", val, state);
break;
case TAG_NEXT:
- localjump_error("unexpected next", val);
+ localjump_error("unexpected next", val, state);
break;
case TAG_BREAK:
- localjump_error("unexpected break", val);
+ localjump_error("unexpected break", val, state);
break;
case TAG_REDO:
- localjump_error("unexpected redo", Qnil);
+ localjump_error("unexpected redo", Qnil, state);
break;
case TAG_RETRY:
- localjump_error("retry outside of rescue clause", Qnil);
+ localjump_error("retry outside of rescue clause", Qnil, state);
break;
default:
JUMP_TAG(state);
@@ -1897,7 +1924,7 @@ copy_node_scope(node, rval)
#define BEGIN_CALLARGS do {\
struct BLOCK *tmp_block = ruby_block;\
if (ruby_iter->iter == ITER_PRE) {\
- ruby_block = ruby_block->prev;\
+ ruby_block = ruby_block->outer;\
}\
PUSH_ITER(ITER_NOT)
@@ -3967,7 +3994,7 @@ rb_yield_0(val, self, klass, pcall, avalue)
static unsigned serial = 1;
if (!rb_block_given_p()) {
- localjump_error("no block given", Qnil);
+ localjump_error("no block given", Qnil, 0);
}
PUSH_VARS();
@@ -6805,7 +6832,7 @@ proc_invoke(proc, args, pcall, self)
break;
case TAG_RETRY:
if (pcall || orphan) {
- localjump_error("retry from proc-closure", Qnil);
+ localjump_error("retry from proc-closure", Qnil, state);
}
/* fall through */
case TAG_BREAK:
@@ -6813,7 +6840,7 @@ proc_invoke(proc, args, pcall, self)
result = prot_tag->retval;
}
else if (orphan) {
- localjump_error("break from proc-closure", prot_tag->retval);
+ localjump_error("break from proc-closure", prot_tag->retval, state);
}
else {
ruby_block->tag->dst = incoming_state;
@@ -6822,7 +6849,7 @@ proc_invoke(proc, args, pcall, self)
break;
case TAG_RETURN:
if (orphan) { /* orphan procedure */
- localjump_error("return from proc-closure", prot_tag->retval);
+ localjump_error("return from proc-closure", prot_tag->retval, state);
}
/* fall through */
default:
@@ -6988,7 +7015,7 @@ block_pass(self, node)
/* PUSH BLOCK from data */
old_block = ruby_block;
_block = *data;
- _block.prev = old_block;
+ _block.outer = ruby_block;
ruby_block = &_block;
PUSH_ITER(ITER_PRE);
ruby_frame->iter = ITER_PRE;
@@ -7035,7 +7062,7 @@ block_pass(self, node)
goto retry;
case TAG_RETURN:
if (orphan) {
- localjump_error("return from proc-closure", prot_tag->retval);
+ localjump_error("return from proc-closure", prot_tag->retval, state);
}
default:
JUMP_TAG(state);
@@ -7445,7 +7472,8 @@ void
Init_Proc()
{
rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
- rb_define_method(rb_eLocalJumpError, "exitstatus", localjump_exitstatus, 0);
+ rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
+ rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError);
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 3189b9ae65..cea0de50a2 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -300,6 +300,7 @@ pty_finalize_syswait(info)
struct pty_info *info;
{
rb_thread_kill(info->thread);
+ rb_funcall(info->thread, rb_intern("value"), 0);
rb_detach_process(info->child_pid);
return Qnil;
}
@@ -438,9 +439,9 @@ pty_getpty(argc, argv, self)
thinfo.thread = rb_thread_create(pty_syswait, (void*)&info);
thinfo.child_pid = info.child_pid;
+ rb_thread_schedule();
if (rb_block_given_p()) {
-
rb_ensure(rb_yield, res, pty_finalize_syswait, (VALUE)&thinfo);
return Qnil;
}
diff --git a/intern.h b/intern.h
index 6776216c40..0b73d7461d 100644
--- a/intern.h
+++ b/intern.h
@@ -121,7 +121,7 @@ void rb_define_private_method _((VALUE, const char*, VALUE (*)(ANYARGS), int));
void rb_define_singleton_method _((VALUE, const char*, VALUE(*)(ANYARGS), int));
VALUE rb_singleton_class _((VALUE));
/* compar.c */
-int rb_cmpint _((VALUE));
+int rb_cmpint _((VALUE, VALUE, VALUE));
NORETURN(void rb_cmperr _((VALUE, VALUE)));
/* enum.c */
/* error.c */
diff --git a/range.c b/range.c
index e0d17f46c2..5d398b5e6b 100644
--- a/range.c
+++ b/range.c
@@ -126,7 +126,7 @@ r_lt(a, b)
VALUE r = rb_funcall(a, id_cmp, 1, b);
if (NIL_P(r)) return Qfalse;
- if (rb_cmpint(r) < 0) return Qtrue;
+ if (rb_cmpint(r, a, b) < 0) return Qtrue;
return Qfalse;
}
@@ -137,7 +137,7 @@ r_le(a, b)
VALUE r = rb_funcall(a, id_cmp, 1, b);
if (NIL_P(r)) return Qfalse;
- if (rb_cmpint(r) <= 0) return Qtrue;
+ if (rb_cmpint(r, a, b) <= 0) return Qtrue;
return Qfalse;
}
@@ -149,7 +149,7 @@ r_gt(a,b)
VALUE r = rb_funcall(a, id_cmp, 1, b);
if (NIL_P(r)) return Qfalse;
- if (rb_cmpint(r) > 0) return Qtrue;
+ if (rb_cmpint(r, a, b) > 0) return Qtrue;
return Qfalse;
}
diff --git a/sample/test.rb b/sample/test.rb
index d49e7a3e28..c2263013d2 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -962,6 +962,28 @@ IterTest.new([[8]]).each8 {|x| test_ok(x == [8])}
IterTest.new([[0,0]]).each0 {|x| test_ok(x == [0,0])}
IterTest.new([[8,8]]).each8 {|x| test_ok(x == [8,8])}
+def m
+ test_ok(block_given?)
+end
+m{p 'test'}
+
+def m
+ test_ok(block_given?,&proc)
+end
+m{p 'test'}
+
+class C
+ include Enumerable
+ def initialize
+ @a = [1,2,3]
+ end
+ def each(&block)
+ @a.each(&block)
+ end
+end
+
+test_ok(C.new.collect{|n| n} == [1,2,3])
+
test_check "float"
test_ok(2.6.floor == 2)
test_ok((-2.6).floor == -3)
@@ -1526,6 +1548,11 @@ include Const2
STDERR.print "intentionally redefines TEST3, TEST4\n" if $VERBOSE
test_ok([TEST1,TEST2,TEST3,TEST4] == [1,2,6,8])
+
+test_ok((String <=> Object) == -1)
+test_ok((Object <=> String) == 1)
+test_ok((Array <=> String) == nil)
+
test_check "clone"
foo = Object.new
def foo.test
diff --git a/time.c b/time.c
index cb5d5088a9..7348906cdb 100644
--- a/time.c
+++ b/time.c
@@ -704,31 +704,15 @@ time_cmp(time1, time2)
long i;
GetTimeval(time1, tobj1);
- switch (TYPE(time2)) {
- case T_FIXNUM:
- i = FIX2LONG(time2);
- if (tobj1->tv.tv_sec == i) {
- if (tobj1->tv.tv_usec == 0)
- return INT2FIX(0);
- if (tobj1->tv.tv_usec > 0)
- return INT2FIX(1);
+ if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
+ GetTimeval(time2, tobj2);
+ if (tobj1->tv.tv_sec == tobj2->tv.tv_sec) {
+ if (tobj1->tv.tv_usec == tobj2->tv.tv_usec) return INT2FIX(0);
+ if (tobj1->tv.tv_usec > tobj2->tv.tv_usec) return INT2FIX(1);
return INT2FIX(-1);
}
- if (tobj1->tv.tv_sec > i) return INT2FIX(1);
+ if (tobj1->tv.tv_sec > tobj2->tv.tv_sec) return INT2FIX(1);
return INT2FIX(-1);
-
- case T_DATA:
- if (RDATA(time2)->dfree == time_free) {
- GetTimeval(time2, tobj2);
- if (tobj1->tv.tv_sec == tobj2->tv.tv_sec) {
- if (tobj1->tv.tv_usec == tobj2->tv.tv_usec) return INT2FIX(0);
- if (tobj1->tv.tv_usec > tobj2->tv.tv_usec) return INT2FIX(1);
- return INT2FIX(-1);
- }
- if (tobj1->tv.tv_sec > tobj2->tv.tv_sec) return INT2FIX(1);
- return INT2FIX(-1);
- }
- break;
}
return Qnil;