RBTreeを1.9.1に対応させてみた

RBTree 0.2.1が1.8.xでしか動かないみたいなので,1.9.1で動くようにしてみた.
RStringやRArrayのメンバをマクロを通してアクセスするようにして,rb_inspecting_pやrb_protect_inspectを使っている所をrb_exec_recursveを使うようにした.
testは大体通ってるみたいだけど,再帰的なinspectがうまくいってない.

$ ruby19 test.rb 
Loaded suite test
Started
....................................................test.rb:200: warning: block supersedes default value argument
..............F.................
Finished in 0.020454 seconds.

  1) Failure:
test_pp(RBTreeTest) [test.rb:739]:
<"#<RBTree: {\"#<RBTree: ...>\"=>\"#<RBTree: ...>\"},\n default=\"#<RBTree: ...>\",\n cmp_proc=nil>\n"> expected but was
<"#<RBTree: {\"#<RBTree: {#<RBTree: ...>=>#<RBTree: ...>}, default=#<RBTree: ...>, cmp_proc=nil>\"=>\n   \"#<RBTree: {#<RBTree: ...>=>#<RBTree: ...>}, default=#<RBTree: ...>, cmp_proc=nil>\"},\n default=\"#<RBTree: {#<RBTree: ...>=>#<RBTree: ...>}, default=#<RBTree: ...>, cmp_proc=nil>\",\n cmp_proc=nil>\n">.

84 tests, 298 assertions, 1 failures, 0 errors, 0 skips

array.cとかを読んで適当にやっただけだからちゃんとできてるか不安だなぁ.


diff

--- orig_rbtree.c	2009-09-11 05:13:06.000000000 +0900
+++ rbtree.c	2009-09-11 06:18:26.000000000 +0900
@@ -3,8 +3,7 @@
  * Copyright (c) 2002-2004, 2007, 2009 OZAWA Takuma
  */
 #include <ruby.h>
-#include <version.h>
-#include <st.h>
+#include <ruby/st.h>
 #include <stdarg.h>
 #include "dict.h"
 
@@ -184,24 +183,24 @@
         tmp = rb_check_convert_type(argv[0], T_HASH, "Hash", "to_hash");
         if (!NIL_P(tmp)) {
             rbtree = rbtree_alloc(klass);
-            st_foreach(RHASH(tmp)->tbl, hash_to_rbtree_i, rbtree);
+            st_foreach(RHASH_TBL(tmp), hash_to_rbtree_i, rbtree);
             return rbtree;
         }
         
         tmp = rb_check_array_type(argv[0]);
         if (!NIL_P(tmp)) {
             rbtree = rbtree_alloc(klass);
-            for (i = 0; i < RARRAY(tmp)->len; i++) {
-                VALUE v = rb_check_array_type(RARRAY(tmp)->ptr[i]);
+            for (i = 0; i < RARRAY_LEN(tmp); i++) {
+                VALUE v = rb_check_array_type(RARRAY_PTR(tmp)[i]);
                 if (NIL_P(v)) {
                     continue;
                 }
-                switch(RARRAY(v)->len) {
+                switch(RARRAY_LEN(v)) {
                 case 1:
-                    rbtree_aset(rbtree, RARRAY(v)->ptr[0], Qnil);
+                    rbtree_aset(rbtree, RARRAY_PTR(v)[0], Qnil);
                     break;
                 case 2:
-                    rbtree_aset(rbtree, RARRAY(v)->ptr[0], RARRAY(v)->ptr[1]);
+                    rbtree_aset(rbtree, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);
                     break;
                 default:
                     continue;
@@ -1059,7 +1058,7 @@
 static each_return_t
 to_hash_i(dnode_t* node, void* hash)
 {
-    st_insert(RHASH(hash)->tbl, GET_KEY(node), GET_VAL(node));
+    st_insert(RHASH_TBL((VALUE)hash), GET_KEY(node), GET_VAL(node));
     return EACH_NEXT;
 }
 
@@ -1096,16 +1095,16 @@
 rbtree_begin_inspect(VALUE self)
 {
     const char* c = rb_class2name(CLASS_OF(self));
-    VALUE str = rb_str_new(0, strlen(c) + 5);
-    const size_t len = sprintf(RSTRING(str)->ptr, "#<%s: ", c);
-    RSTRING(str)->len = len;
+    VALUE str = rb_str_new(0, strlen(c) + 4);
+    sprintf(RSTRING_PTR(str), "#<%s: ", c);
     return str;
 }
 
 static VALUE
-to_s_rbtree(VALUE self, VALUE nil)
+to_s_rbtree(VALUE self, VALUE nil, int recur)
 {
-    return rb_ary_to_s(rbtree_to_a(self));
+    if (recur) return rb_str_cat2(rbtree_begin_inspect(self), "...>");
+    return rb_ary_join(rbtree_to_a(self), Qnil);
 }
 
 /*
@@ -1114,9 +1113,7 @@
 VALUE
 rbtree_to_s(VALUE self)
 {
-    if (rb_inspecting_p(self))
-        return rb_str_cat2(rbtree_begin_inspect(self), "...>");
-    return rb_protect_inspect(to_s_rbtree, self, Qnil);
+    return rb_exec_recursive(to_s_rbtree, self, Qnil);
 }
 
 static each_return_t
@@ -1125,8 +1122,8 @@
     VALUE ret = (VALUE)ret_;
     VALUE str;
 
-    if (RSTRING(ret)->ptr[0] == '-')
-        RSTRING(ret)->ptr[0] = '#';
+    if (RSTRING_PTR(ret)[0] == '-')
+        RSTRING_PTR(ret)[0] = '#';
     else
         rb_str_cat2(ret, ", ");
 
@@ -1144,14 +1141,18 @@
 }
 
 static VALUE
-inspect_rbtree(VALUE self, VALUE ret)
+inspect_rbtree(VALUE self, VALUE ret, int recur)
 {
     VALUE str;
     
+    if (recur) {
+        OBJ_INFECT(ret, self);
+        return rb_str_cat2(ret, "...>");
+    }
     rb_str_cat2(ret, "{");
-    RSTRING(ret)->ptr[0] = '-';
+    RSTRING_PTR(ret)[0] = '-';
     rbtree_for_each(self, inspect_i, (void*)ret);
-    RSTRING(ret)->ptr[0] = '#';
+    RSTRING_PTR(ret)[0] = '#';
     rb_str_cat2(ret, "}");
 
     str = rb_inspect(IFNONE(self));
@@ -1175,10 +1176,8 @@
 VALUE
 rbtree_inspect(VALUE self)
 {
-    VALUE str = rbtree_begin_inspect(self);
-    if (rb_inspecting_p(self))
-        return rb_str_cat2(str, "...>");
-    return rb_protect_inspect(inspect_rbtree, self, str);
+    volatile VALUE str = rbtree_begin_inspect(self);
+    return rb_exec_recursive(inspect_rbtree, self, str);
 }
 
 /*
@@ -1510,8 +1509,8 @@
 {
     VALUE rbtree = rbtree_alloc(klass);
     VALUE ary = rb_marshal_load(str);
-    VALUE* ptr = RARRAY(ary)->ptr;
-    long len = RARRAY(ary)->len - 1;
+    VALUE* ptr = RARRAY_PTR(ary);
+    long len = RARRAY_LEN(ary) - 1;
     long i;
     
     for (i = 0; i < len; i += 2)