about summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-09-01 16:41:08 -0700
committerEric Wong <normalperson@yhbt.net>2010-09-01 16:51:06 -0700
commit742da1694d3202714f8f8534d907c51f1cdca514 (patch)
tree94a7fab85c89787a8d2958d504c475bf15e79534
parentbb221fa8e214605ead838b51cee443388b2c2f14 (diff)
downloadrpatricia-742da1694d3202714f8f8534d907c51f1cdca514.tar.gz
Patricia#show_nodes uses Ruby IO methods
This allows the output of Patricia#show_nodes to be redirected
to StringIO objects (or anything else that responds to printf).
Since Ruby 1.9 no longer uses stdio, this lets us go through the
normal output stream used by Ruby.
-rwxr-xr-xext/rpatricia/extconf.rb2
-rw-r--r--ext/rpatricia/rpatricia.c24
-rw-r--r--test/test_show_nodes.rb32
3 files changed, 52 insertions, 6 deletions
diff --git a/ext/rpatricia/extconf.rb b/ext/rpatricia/extconf.rb
index ac42e36..18bb7a7 100755
--- a/ext/rpatricia/extconf.rb
+++ b/ext/rpatricia/extconf.rb
@@ -1,5 +1,5 @@
 #!/usr/bin/env ruby
 require "mkmf"
 
+have_func("rb_str_set_len", "ruby.h")
 create_makefile("rpatricia")
-
diff --git a/ext/rpatricia/rpatricia.c b/ext/rpatricia/rpatricia.c
index 54ac3ed..fcb544b 100644
--- a/ext/rpatricia/rpatricia.c
+++ b/ext/rpatricia/rpatricia.c
@@ -4,7 +4,6 @@
  */
 
 #include "ruby.h"
-#include <stdio.h> /* printf */
 #include <stdlib.h>
 #include "patricia.h"
 
@@ -142,18 +141,33 @@ p_num_nodes (VALUE self)
   return INT2NUM(n);
 }
 
+/* needed for Ruby 1.8.6, in 1.8.7 and later */
+#ifndef HAVE_RB_STR_SET_LEN
+static void
+rb_str_set_len(VALUE str, long len)
+{
+  RSTRING(str)->len = len;
+  RSTRING(str)->ptr[len] = '\0';
+}
+#endif
+
 static VALUE
 p_print_nodes (VALUE self)
 {
-  int n;
-  char buff[32];
+  ID id_printf = rb_intern("printf");
+  VALUE fmt = rb_str_new2("node: %s\n");
+  VALUE buf = rb_str_buf_new(128);
+  char *cbuf;
   patricia_tree_t *tree;
   patricia_node_t *node;
   Data_Get_Struct(self, patricia_tree_t, tree);
 
   PATRICIA_WALK(tree->head, node) {
-    prefix_toa2x(node->prefix, buff, 1);
-    printf("node: %s\n", buff);
+    rb_str_resize(buf, 128);
+    cbuf = RSTRING_PTR(buf);
+    prefix_toa2x(node->prefix, cbuf, 1);
+    rb_str_set_len(buf, strlen(cbuf));
+    rb_funcall(rb_stdout, id_printf, 2, fmt, buf);
   } PATRICIA_WALK_END;
   return Qtrue;
 }
diff --git a/test/test_show_nodes.rb b/test/test_show_nodes.rb
new file mode 100644
index 0000000..b4aa3a0
--- /dev/null
+++ b/test/test_show_nodes.rb
@@ -0,0 +1,32 @@
+require 'test/unit'
+require 'rpatricia'
+require 'stringio'
+
+class TestShowNodes < Test::Unit::TestCase
+
+  def test_show_nodes
+    t = Patricia.new
+    assert_nothing_raised do
+      t.add("127.0.0.0/24")
+      t.add("192.168.1.0/24")
+      t.add("192.168.2.0/24")
+      t.add("192.168.3.100")
+      t.add("10.0.0.0/8", "pref_10")
+    end
+    begin
+      oldout = $stdout
+      $stdout = tmpout = StringIO.new
+      assert_nothing_raised { t.show_nodes }
+    ensure
+      $stdout = oldout
+    end
+    expect = [
+      "node: 10.0.0.0/8",
+      "node: 127.0.0.0/24",
+      "node: 192.168.1.0/24",
+      "node: 192.168.2.0/24",
+      "node: 192.168.3.100/32"
+    ].join("\n") << "\n"
+    assert_equal expect, tmpout.string
+  end
+end