ruby-changes:12089
From: yugui <ko1@a...>
Date: Sat, 20 Jun 2009 18:07:56 +0900 (JST)
Subject: [ruby-changes:12089] Ruby:r23759 (ruby_1_9_1): merges r23557 and r23563 from trunk into ruby_1_9_1.
yugui 2009-06-20 18:06:35 +0900 (Sat, 20 Jun 2009) New Revision: 23759 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23759 Log: 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 Modified files: branches/ruby_1_9_1/ChangeLog branches/ruby_1_9_1/array.c branches/ruby_1_9_1/hash.c branches/ruby_1_9_1/include/ruby/intern.h branches/ruby_1_9_1/test/ruby/test_hash.rb branches/ruby_1_9_1/test/ruby/test_m17n.rb branches/ruby_1_9_1/thread.c branches/ruby_1_9_1/version.h Index: ruby_1_9_1/array.c =================================================================== --- ruby_1_9_1/array.c (revision 23758) +++ ruby_1_9_1/array.c (revision 23759) @@ -2656,7 +2656,7 @@ { long i; - if (recur) return Qfalse; + if (recur) return Qtrue; /* Subtle! */ for (i=0; i<RARRAY_LEN(ary1); i++) { if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i))) return Qfalse; @@ -2689,7 +2689,7 @@ return rb_equal(ary2, ary1); } 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 @@ -2697,7 +2697,7 @@ { long i; - if (recur) return Qfalse; + if (recur) return Qtrue; /* Subtle! */ for (i=0; i<RARRAY_LEN(ary1); i++) { if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i))) return Qfalse; @@ -2719,7 +2719,7 @@ if (ary1 == ary2) return Qtrue; if (TYPE(ary2) != T_ARRAY) 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 @@ -2786,7 +2786,7 @@ { long i, len; - if (recur) return Qnil; + if (recur) return Qundef; /* Subtle! */ len = RARRAY_LEN(ary1); if (len > RARRAY_LEN(ary2)) { len = RARRAY_LEN(ary2); @@ -2828,7 +2828,7 @@ ary2 = to_ary(ary2); 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; len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2); if (len == 0) return INT2FIX(0); Index: ruby_1_9_1/include/ruby/intern.h =================================================================== --- ruby_1_9_1/include/ruby/intern.h (revision 23758) +++ ruby_1_9_1/include/ruby/intern.h (revision 23759) @@ -335,6 +335,7 @@ void rb_thread_atfork(void); void rb_thread_atfork_before_exec(void); VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE); +VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE); /* file.c */ VALUE rb_file_s_expand_path(int, VALUE *); VALUE rb_file_expand_path(VALUE, VALUE); Index: ruby_1_9_1/ChangeLog =================================================================== --- ruby_1_9_1/ChangeLog (revision 23758) +++ ruby_1_9_1/ChangeLog (revision 23759) @@ -1,3 +1,19 @@ +Mon May 25 06:25:38 2009 Yukihiro Matsumoto <matz@r...> + + * 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@r...> + + * 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@r...> * error.c (syserr_initialize): errno is int. Index: ruby_1_9_1/thread.c =================================================================== --- ruby_1_9_1/thread.c (revision 23758) +++ ruby_1_9_1/thread.c (revision 23759) @@ -3279,26 +3279,39 @@ static ID recursive_key; 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) { return Qfalse; } 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) return Qfalse; - if (NIL_P(rb_hash_lookup(list, obj))) + pair_list = rb_hash_lookup2(list, obj, Qundef); + if (pair_list == Qundef) 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; } } 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()); if (NIL_P(hash) || TYPE(hash) != T_HASH) { @@ -3313,61 +3326,99 @@ list = rb_hash_new(); 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; } 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()); if (NIL_P(hash) || TYPE(hash) != T_HASH) { - VALUE symname; - VALUE thrname; symname = rb_inspect(sym); thrname = rb_inspect(rb_thread_current()); - rb_raise(rb_eTypeError, "invalid inspect_tbl hash for %s in %s", StringValuePtr(symname), StringValuePtr(thrname)); } list = rb_hash_aref(hash, sym); if (NIL_P(list) || TYPE(list) != T_HASH) { - VALUE symname = rb_inspect(sym); - VALUE thrname = rb_inspect(rb_thread_current()); + symname = rb_inspect(sym); + thrname = rb_inspect(rb_thread_current()); rb_raise(rb_eTypeError, "invalid inspect_tbl list for %s in %s", 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); } -VALUE -rb_exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg) +static VALUE +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 objid = rb_obj_id(obj); - if (recursive_check(hash, objid)) { + if (recursive_check(hash, objid, pairid)) { return (*func) (obj, arg, Qtrue); } else { VALUE result = Qundef; int state; - hash = recursive_push(hash, objid); + hash = recursive_push(hash, objid, pairid); PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { result = (*func) (obj, arg, Qfalse); } POP_TAG(); - recursive_pop(hash, objid); + recursive_pop(hash, objid, pairid); if (state) JUMP_TAG(state); 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 */ static rb_event_hook_t * Index: ruby_1_9_1/hash.c =================================================================== --- ruby_1_9_1/hash.c (revision 23758) +++ ruby_1_9_1/hash.c (revision 23759) @@ -1428,7 +1428,7 @@ { struct equal_data *data; - if (recur) return Qfalse; + if (recur) return Qtrue; /* Subtle! */ data = (struct equal_data*)dt; data->result = Qtrue; rb_hash_foreach(hash, eql_i, (st_data_t)data); @@ -1465,7 +1465,7 @@ data.tbl = RHASH(hash2)->ntbl; data.eql = eql; - return rb_exec_recursive(recursive_eql, hash1, (VALUE)&data); + return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data); } /* Index: ruby_1_9_1/version.h =================================================================== --- ruby_1_9_1/version.h (revision 23758) +++ ruby_1_9_1/version.h (revision 23759) @@ -1,6 +1,6 @@ #define RUBY_VERSION "1.9.1" #define RUBY_RELEASE_DATE "2009-05-22" -#define RUBY_PATCHLEVEL 157 +#define RUBY_PATCHLEVEL 158 #define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MINOR 9 #define RUBY_VERSION_TEENY 1 Index: ruby_1_9_1/test/ruby/test_m17n.rb =================================================================== --- ruby_1_9_1/test/ruby/test_m17n.rb (revision 23758) +++ ruby_1_9_1/test/ruby/test_m17n.rb (revision 23759) @@ -770,7 +770,7 @@ #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"', '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\"", 'Windows-31J', "%10p" % s("\xc2\xa1")) assert_strenc(" \"\xC2\xA1\"", 'UTF-8', "%10p" % u("\xc2\xa1")) Index: ruby_1_9_1/test/ruby/test_hash.rb =================================================================== --- ruby_1_9_1/test/ruby/test_hash.rb (revision 23758) +++ ruby_1_9_1/test/ruby/test_hash.rb (revision 23759) @@ -770,7 +770,9 @@ h1 = {}; h1[h1] = h1; h1.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 def test_eql -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/