mirror of
https://github.com/ruby/ruby.git
synced 2025-09-18 10:03:59 +02:00
merges r23557 and r23563 from trunk into ruby_1_9_1.
-- * thread.c (rb_exec_recursive_paired): new function for proper handling of recursive arrays. [EXPERIMENTAL] [ruby-core:23402] * array.c (rb_ary_equal, rb_ary_eql, rb_ary_cmp): use above. * hash.c (hash_equal): ditto. -- * test/ruby/test_hash.rb (TestHash::test_equal2): recursive hashes are handled properly now. ref: [ruby-core:23402] * test/ruby/test_m17n.rb (TestM17N#test_sprintf_p): test fixed git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@23759 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7340277cfb
commit
0ddc830573
8 changed files with 99 additions and 29 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
Mon May 25 06:25:38 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* test/ruby/test_hash.rb (TestHash::test_equal2): recursive hashes
|
||||||
|
are handled properly now. ref: [ruby-core:23402]
|
||||||
|
|
||||||
|
* test/ruby/test_m17n.rb (TestM17N#test_sprintf_p): test fixed
|
||||||
|
|
||||||
|
Sun May 24 22:48:17 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* thread.c (rb_exec_recursive_paired): new function for proper
|
||||||
|
handling of recursive arrays. [EXPERIMENTAL] [ruby-core:23402]
|
||||||
|
|
||||||
|
* array.c (rb_ary_equal, rb_ary_eql, rb_ary_cmp): use above.
|
||||||
|
|
||||||
|
* hash.c (hash_equal): ditto.
|
||||||
|
|
||||||
Sun May 24 22:39:33 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun May 24 22:39:33 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* error.c (syserr_initialize): errno is int.
|
* error.c (syserr_initialize): errno is int.
|
||||||
|
|
12
array.c
12
array.c
|
@ -2656,7 +2656,7 @@ recursive_equal(VALUE ary1, VALUE ary2, int recur)
|
||||||
{
|
{
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
if (recur) return Qfalse;
|
if (recur) return Qtrue; /* Subtle! */
|
||||||
for (i=0; i<RARRAY_LEN(ary1); i++) {
|
for (i=0; i<RARRAY_LEN(ary1); i++) {
|
||||||
if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
|
if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
|
@ -2689,7 +2689,7 @@ rb_ary_equal(VALUE ary1, VALUE ary2)
|
||||||
return rb_equal(ary2, ary1);
|
return rb_equal(ary2, ary1);
|
||||||
}
|
}
|
||||||
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
|
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
|
||||||
return rb_exec_recursive(recursive_equal, ary1, ary2);
|
return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -2697,7 +2697,7 @@ recursive_eql(VALUE ary1, VALUE ary2, int recur)
|
||||||
{
|
{
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
if (recur) return Qfalse;
|
if (recur) return Qtrue; /* Subtle! */
|
||||||
for (i=0; i<RARRAY_LEN(ary1); i++) {
|
for (i=0; i<RARRAY_LEN(ary1); i++) {
|
||||||
if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
|
if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
|
@ -2719,7 +2719,7 @@ rb_ary_eql(VALUE ary1, VALUE ary2)
|
||||||
if (ary1 == ary2) return Qtrue;
|
if (ary1 == ary2) return Qtrue;
|
||||||
if (TYPE(ary2) != T_ARRAY) return Qfalse;
|
if (TYPE(ary2) != T_ARRAY) return Qfalse;
|
||||||
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
|
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
|
||||||
return rb_exec_recursive(recursive_eql, ary1, ary2);
|
return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -2786,7 +2786,7 @@ recursive_cmp(VALUE ary1, VALUE ary2, int recur)
|
||||||
{
|
{
|
||||||
long i, len;
|
long i, len;
|
||||||
|
|
||||||
if (recur) return Qnil;
|
if (recur) return Qundef; /* Subtle! */
|
||||||
len = RARRAY_LEN(ary1);
|
len = RARRAY_LEN(ary1);
|
||||||
if (len > RARRAY_LEN(ary2)) {
|
if (len > RARRAY_LEN(ary2)) {
|
||||||
len = RARRAY_LEN(ary2);
|
len = RARRAY_LEN(ary2);
|
||||||
|
@ -2828,7 +2828,7 @@ rb_ary_cmp(VALUE ary1, VALUE ary2)
|
||||||
|
|
||||||
ary2 = to_ary(ary2);
|
ary2 = to_ary(ary2);
|
||||||
if (ary1 == ary2) return INT2FIX(0);
|
if (ary1 == ary2) return INT2FIX(0);
|
||||||
v = rb_exec_recursive(recursive_cmp, ary1, ary2);
|
v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
|
||||||
if (v != Qundef) return v;
|
if (v != Qundef) return v;
|
||||||
len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
|
len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
|
||||||
if (len == 0) return INT2FIX(0);
|
if (len == 0) return INT2FIX(0);
|
||||||
|
|
4
hash.c
4
hash.c
|
@ -1428,7 +1428,7 @@ recursive_eql(VALUE hash, VALUE dt, int recur)
|
||||||
{
|
{
|
||||||
struct equal_data *data;
|
struct equal_data *data;
|
||||||
|
|
||||||
if (recur) return Qfalse;
|
if (recur) return Qtrue; /* Subtle! */
|
||||||
data = (struct equal_data*)dt;
|
data = (struct equal_data*)dt;
|
||||||
data->result = Qtrue;
|
data->result = Qtrue;
|
||||||
rb_hash_foreach(hash, eql_i, (st_data_t)data);
|
rb_hash_foreach(hash, eql_i, (st_data_t)data);
|
||||||
|
@ -1465,7 +1465,7 @@ hash_equal(VALUE hash1, VALUE hash2, int eql)
|
||||||
|
|
||||||
data.tbl = RHASH(hash2)->ntbl;
|
data.tbl = RHASH(hash2)->ntbl;
|
||||||
data.eql = eql;
|
data.eql = eql;
|
||||||
return rb_exec_recursive(recursive_eql, hash1, (VALUE)&data);
|
return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -335,6 +335,7 @@ VALUE rb_thread_local_aset(VALUE, ID, VALUE);
|
||||||
void rb_thread_atfork(void);
|
void rb_thread_atfork(void);
|
||||||
void rb_thread_atfork_before_exec(void);
|
void rb_thread_atfork_before_exec(void);
|
||||||
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
|
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
|
||||||
|
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE);
|
||||||
/* file.c */
|
/* file.c */
|
||||||
VALUE rb_file_s_expand_path(int, VALUE *);
|
VALUE rb_file_s_expand_path(int, VALUE *);
|
||||||
VALUE rb_file_expand_path(VALUE, VALUE);
|
VALUE rb_file_expand_path(VALUE, VALUE);
|
||||||
|
|
|
@ -770,7 +770,9 @@ class TestHash < Test::Unit::TestCase
|
||||||
|
|
||||||
h1 = {}; h1[h1] = h1; h1.rehash
|
h1 = {}; h1[h1] = h1; h1.rehash
|
||||||
h2 = {}; h2[h2] = h2; h2.rehash
|
h2 = {}; h2[h2] = h2; h2.rehash
|
||||||
assert(h1 != h2)
|
# assert(h1 != h2)
|
||||||
|
# recursive hashes are handled properly now. [ruby-core:23402]
|
||||||
|
assert(h1 == h2)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_eql
|
def test_eql
|
||||||
|
|
|
@ -770,7 +770,7 @@ class TestM17N < Test::Unit::TestCase
|
||||||
#assert_strenc("\"\xC2\xA1\"", 'Windows-31J', s("%p") % s("\xc2\xa1"))
|
#assert_strenc("\"\xC2\xA1\"", 'Windows-31J', s("%p") % s("\xc2\xa1"))
|
||||||
assert_strenc("\"\xC2\xA1\"", 'UTF-8', u("%p") % u("\xc2\xa1"))
|
assert_strenc("\"\xC2\xA1\"", 'UTF-8', u("%p") % u("\xc2\xa1"))
|
||||||
|
|
||||||
assert_strenc('"\xC2\xA1"', 'US-ASCII', "%10p" % a("\xc2\xa1"))
|
assert_strenc('"\xC2\xA1"', 'ASCII-8BIT', "%10p" % a("\xc2\xa1"))
|
||||||
assert_strenc(" \"\xC2\xA1\"", 'EUC-JP', "%10p" % e("\xc2\xa1"))
|
assert_strenc(" \"\xC2\xA1\"", 'EUC-JP', "%10p" % e("\xc2\xa1"))
|
||||||
#assert_strenc(" \"\xC2\xA1\"", 'Windows-31J', "%10p" % s("\xc2\xa1"))
|
#assert_strenc(" \"\xC2\xA1\"", 'Windows-31J', "%10p" % s("\xc2\xa1"))
|
||||||
assert_strenc(" \"\xC2\xA1\"", 'UTF-8', "%10p" % u("\xc2\xa1"))
|
assert_strenc(" \"\xC2\xA1\"", 'UTF-8', "%10p" % u("\xc2\xa1"))
|
||||||
|
|
87
thread.c
87
thread.c
|
@ -3279,26 +3279,39 @@ rb_barrier_destroy(VALUE self)
|
||||||
static ID recursive_key;
|
static ID recursive_key;
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
recursive_check(VALUE hash, VALUE obj)
|
recursive_check(VALUE hash, VALUE obj, VALUE paired_obj)
|
||||||
{
|
{
|
||||||
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
|
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE list = rb_hash_aref(hash, ID2SYM(rb_frame_this_func()));
|
VALUE sym = ID2SYM(rb_frame_this_func());
|
||||||
|
VALUE list = rb_hash_aref(hash, sym);
|
||||||
|
VALUE pair_list;
|
||||||
|
|
||||||
if (NIL_P(list) || TYPE(list) != T_HASH)
|
if (NIL_P(list) || TYPE(list) != T_HASH)
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
if (NIL_P(rb_hash_lookup(list, obj)))
|
pair_list = rb_hash_lookup2(list, obj, Qundef);
|
||||||
|
if (pair_list == Qundef)
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
|
if (paired_obj) {
|
||||||
|
if (TYPE(pair_list) != T_HASH) {
|
||||||
|
if (pair_list != paired_obj)
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (NIL_P(rb_hash_lookup(pair_list, paired_obj)))
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
recursive_push(VALUE hash, VALUE obj)
|
recursive_push(VALUE hash, VALUE obj, VALUE paired_obj)
|
||||||
{
|
{
|
||||||
VALUE list, sym;
|
VALUE list, sym, pair_list;
|
||||||
|
|
||||||
sym = ID2SYM(rb_frame_this_func());
|
sym = ID2SYM(rb_frame_this_func());
|
||||||
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
|
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
|
||||||
|
@ -3313,61 +3326,99 @@ recursive_push(VALUE hash, VALUE obj)
|
||||||
list = rb_hash_new();
|
list = rb_hash_new();
|
||||||
rb_hash_aset(hash, sym, list);
|
rb_hash_aset(hash, sym, list);
|
||||||
}
|
}
|
||||||
rb_hash_aset(list, obj, Qtrue);
|
if (!paired_obj) {
|
||||||
|
rb_hash_aset(list, obj, Qtrue);
|
||||||
|
}
|
||||||
|
else if ((pair_list = rb_hash_lookup2(list, obj, Qundef)) == Qundef) {
|
||||||
|
rb_hash_aset(list, obj, paired_obj);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (TYPE(pair_list) != T_HASH){
|
||||||
|
VALUE other_paired_obj = pair_list;
|
||||||
|
pair_list = rb_hash_new();
|
||||||
|
rb_hash_aset(pair_list, other_paired_obj, Qtrue);
|
||||||
|
rb_hash_aset(list, obj, pair_list);
|
||||||
|
}
|
||||||
|
rb_hash_aset(pair_list, paired_obj, Qtrue);
|
||||||
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recursive_pop(VALUE hash, VALUE obj)
|
recursive_pop(VALUE hash, VALUE obj, VALUE paired_obj)
|
||||||
{
|
{
|
||||||
VALUE list, sym;
|
VALUE list, sym, pair_list, symname, thrname;
|
||||||
|
|
||||||
sym = ID2SYM(rb_frame_this_func());
|
sym = ID2SYM(rb_frame_this_func());
|
||||||
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
|
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
|
||||||
VALUE symname;
|
|
||||||
VALUE thrname;
|
|
||||||
symname = rb_inspect(sym);
|
symname = rb_inspect(sym);
|
||||||
thrname = rb_inspect(rb_thread_current());
|
thrname = rb_inspect(rb_thread_current());
|
||||||
|
|
||||||
rb_raise(rb_eTypeError, "invalid inspect_tbl hash for %s in %s",
|
rb_raise(rb_eTypeError, "invalid inspect_tbl hash for %s in %s",
|
||||||
StringValuePtr(symname), StringValuePtr(thrname));
|
StringValuePtr(symname), StringValuePtr(thrname));
|
||||||
}
|
}
|
||||||
list = rb_hash_aref(hash, sym);
|
list = rb_hash_aref(hash, sym);
|
||||||
if (NIL_P(list) || TYPE(list) != T_HASH) {
|
if (NIL_P(list) || TYPE(list) != T_HASH) {
|
||||||
VALUE symname = rb_inspect(sym);
|
symname = rb_inspect(sym);
|
||||||
VALUE thrname = rb_inspect(rb_thread_current());
|
thrname = rb_inspect(rb_thread_current());
|
||||||
rb_raise(rb_eTypeError, "invalid inspect_tbl list for %s in %s",
|
rb_raise(rb_eTypeError, "invalid inspect_tbl list for %s in %s",
|
||||||
StringValuePtr(symname), StringValuePtr(thrname));
|
StringValuePtr(symname), StringValuePtr(thrname));
|
||||||
}
|
}
|
||||||
|
if (paired_obj) {
|
||||||
|
pair_list = rb_hash_lookup2(list, obj, Qundef);
|
||||||
|
if (pair_list == Qundef) {
|
||||||
|
symname = rb_inspect(sym);
|
||||||
|
thrname = rb_inspect(rb_thread_current());
|
||||||
|
rb_raise(rb_eTypeError, "invalid inspect_tbl pair_list for %s in %s",
|
||||||
|
StringValuePtr(symname), StringValuePtr(thrname));
|
||||||
|
}
|
||||||
|
if (TYPE(pair_list) == T_HASH) {
|
||||||
|
rb_hash_delete(pair_list, paired_obj);
|
||||||
|
if (!RHASH_EMPTY_P(pair_list)) {
|
||||||
|
return; /* keep hash until is empty */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
rb_hash_delete(list, obj);
|
rb_hash_delete(list, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
static VALUE
|
||||||
rb_exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg)
|
exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE pairid, VALUE arg)
|
||||||
{
|
{
|
||||||
VALUE hash = rb_thread_local_aref(rb_thread_current(), recursive_key);
|
VALUE hash = rb_thread_local_aref(rb_thread_current(), recursive_key);
|
||||||
VALUE objid = rb_obj_id(obj);
|
VALUE objid = rb_obj_id(obj);
|
||||||
|
|
||||||
if (recursive_check(hash, objid)) {
|
if (recursive_check(hash, objid, pairid)) {
|
||||||
return (*func) (obj, arg, Qtrue);
|
return (*func) (obj, arg, Qtrue);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE result = Qundef;
|
VALUE result = Qundef;
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
hash = recursive_push(hash, objid);
|
hash = recursive_push(hash, objid, pairid);
|
||||||
PUSH_TAG();
|
PUSH_TAG();
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
if ((state = EXEC_TAG()) == 0) {
|
||||||
result = (*func) (obj, arg, Qfalse);
|
result = (*func) (obj, arg, Qfalse);
|
||||||
}
|
}
|
||||||
POP_TAG();
|
POP_TAG();
|
||||||
recursive_pop(hash, objid);
|
recursive_pop(hash, objid, pairid);
|
||||||
if (state)
|
if (state)
|
||||||
JUMP_TAG(state);
|
JUMP_TAG(state);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg)
|
||||||
|
{
|
||||||
|
return exec_recursive(func, obj, 0, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_exec_recursive_paired(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE paired_obj, VALUE arg)
|
||||||
|
{
|
||||||
|
return exec_recursive(func, obj, rb_obj_id(paired_obj), arg);
|
||||||
|
}
|
||||||
|
|
||||||
/* tracer */
|
/* tracer */
|
||||||
|
|
||||||
static rb_event_hook_t *
|
static rb_event_hook_t *
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#define RUBY_VERSION "1.9.1"
|
#define RUBY_VERSION "1.9.1"
|
||||||
#define RUBY_RELEASE_DATE "2009-05-22"
|
#define RUBY_RELEASE_DATE "2009-05-22"
|
||||||
#define RUBY_PATCHLEVEL 157
|
#define RUBY_PATCHLEVEL 158
|
||||||
#define RUBY_VERSION_MAJOR 1
|
#define RUBY_VERSION_MAJOR 1
|
||||||
#define RUBY_VERSION_MINOR 9
|
#define RUBY_VERSION_MINOR 9
|
||||||
#define RUBY_VERSION_TEENY 1
|
#define RUBY_VERSION_TEENY 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue