* ext/pty/pty.c (pty_finalize_syswait): join (using Thread#value)

before detach pid. [ruby-talk:71519]

* 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.

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


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3823 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-05-19 15:45:46 +00:00
Родитель e08bc0a22a
Коммит 7e35911e10
10 изменённых файлов: 156 добавлений и 75 удалений

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

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

14
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

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

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

39
enum.c
Просмотреть файл

@ -155,17 +155,6 @@ collect_all(i, ary)
return Qnil;
}
static VALUE
enum_to_a(obj)
VALUE obj;
{
VALUE ary = rb_ary_new();
rb_iterate(rb_each, obj, collect_all, ary);
return ary;
}
static VALUE
enum_collect(obj)
VALUE obj;
@ -177,6 +166,17 @@ enum_collect(obj)
return ary;
}
static VALUE
enum_to_a(obj)
VALUE obj;
{
VALUE ary = rb_ary_new();
rb_iterate(rb_each, obj, collect_all, ary);
return ary;
}
static VALUE
inject_i(i, memo)
VALUE i;
@ -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;
}
}

62
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, "@status");
return rb_iv_get(exc, "@exit_value");
}
static VALUE
localjump_reason(exc)
VALUE exc;
{
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);

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

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

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

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

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

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

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

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

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