From 9a643db7074054fb1af20497a5e36119a833b0c3 Mon Sep 17 00:00:00 2001
From: guy Decoux <ts@moulon.inra.fr>
Date: Sat, 28 Feb 2009 20:04:27 +0100
Subject: mmap-0.1.4

---
 Changes        |   6 ++
 README.en      |   8 ++-
 extconf.rb     |   6 ++
 mmap.c         |  79 +++++++++++++++++++++++-
 tests/mmapt.rb | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 281 insertions(+), 4 deletions(-)
 create mode 100644 tests/mmapt.rb

diff --git a/Changes b/Changes
index 019dad4..713506f 100644
--- a/Changes
+++ b/Changes
@@ -11,3 +11,9 @@
 * added #insert, #casecmp (>= 171)
 * corrected NEW2LONG
 
+-- 0.1.4
+
+* added #lstrip!, #rstrip! for 1.7.1
+* corrected strip!
+* corrected mm_bang_i (reverse!, etc)
+* added a small test (make test)
diff --git a/README.en b/README.en
index 69d7d1a..17d411f 100644
--- a/README.en
+++ b/README.en
@@ -11,7 +11,13 @@
 
     See mmap.rd, mmap.html
 
- This extension module is copyrighted free software by Guy Decoux
+ * Tests : if you have rubyunit
+
+   make test
+ 
+ * Copying
+
+  This extension module is copyrighted free software by Guy Decoux
 
  You can redistribute it and/or modify it under the same term as
  Ruby.
diff --git a/extconf.rb b/extconf.rb
index 32dbd06..73d0ce7 100644
--- a/extconf.rb
+++ b/extconf.rb
@@ -2,6 +2,12 @@ require "mkmf"
 create_makefile "mmap"
 begin
    make = open("Makefile", "a")
+   make.puts "\ntest: $(DLLIB)"
+   Dir.foreach('tests') do |x|
+      next if /^\./ =~ x || /(_\.rb|~)$/ =~ x
+      next if FileTest.directory?(x)
+      make.print "\truby tests/#{x}\n"
+   end
    make.print <<-EOT
 
 unknown: $(DLLIB)
diff --git a/mmap.c b/mmap.c
index b7faae1..37d400b 100644
--- a/mmap.c
+++ b/mmap.c
@@ -907,6 +907,8 @@ mm_concat(str1, str2)
     return str1;
 }
 
+#if RUBY_VERSION_CODE < 171
+
 static VALUE
 mm_strip_bang(str)
     VALUE str;
@@ -940,6 +942,69 @@ mm_strip_bang(str)
     return str;
 }
 
+#else
+
+static VALUE
+mm_lstrip_bang(str)
+    VALUE str;
+{
+    char *s, *t, *e;
+    mm_mmap *t_mm;
+
+    GetMmap(str, t_mm, MM_MODIFY);
+    s = (char *)t_mm->addr;
+    e = t = s + t_mm->real;
+    while (s < t && ISSPACE(*s)) s++;
+
+    if (t_mm->real != (t - s) && (t_mm->frozen & MM_FIXED)) {
+	rb_raise(rb_eTypeError, "try to change the size of a fixed map");
+    }
+    t_mm->real = t - s;
+    if (s > (char *)t_mm->addr) { 
+	memmove(t_mm->addr, s, t_mm->real);
+	((char *)t_mm->addr)[t_mm->real] = '\0';
+	return str;
+    }
+    return Qnil;
+}
+
+static VALUE
+mm_rstrip_bang(str)
+    VALUE str;
+{
+    char *s, *t, *e;
+    mm_mmap *t_mm;
+
+    GetMmap(str, t_mm, MM_MODIFY);
+    s = (char *)t_mm->addr;
+    e = t = s + t_mm->real;
+    t--;
+    while (s <= t && ISSPACE(*t)) t--;
+    t++;
+    if (t_mm->real != (t - s) && (t_mm->frozen & MM_FIXED)) {
+	rb_raise(rb_eTypeError, "try to change the size of a fixed map");
+    }
+    t_mm->real = t - s;
+    if (t < e) {
+	((char *)t_mm->addr)[t_mm->real] = '\0';
+	return str;
+    }
+    return Qnil;
+}
+
+static VALUE
+mm_strip_bang(str)
+    VALUE str;
+{
+    VALUE l = mm_lstrip_bang(str);
+    VALUE r = mm_str_rstrip_bang(str);
+
+    if (NIL_P(l) && NIL_P(r)) return Qnil;
+    return str;
+}
+
+#endif
+
 #define MmapStr(b, recycle)						\
 do {									\
     recycle = 0;							\
@@ -1079,7 +1144,7 @@ mm_bang_i(obj, flag, id, argc, argv)
     if (res == Qnil) return res;
     GetMmap(obj, t_mm, 0);
     t_mm->real = RSTRING(str)->len;
-    return res;
+    return (flag & MM_ORIGIN)?res:obj;
 
 }
 
@@ -1424,7 +1489,7 @@ Init_mmap()
     rb_define_method(mm_cMap, "unlock", mm_munlock, 0);
 
     rb_define_method(mm_cMap, "extend", mm_extend, 1);
-    rb_define_method(mm_cMap, "freeze", mm_freeze, 1);
+    rb_define_method(mm_cMap, "freeze", mm_freeze, 0);
     rb_define_method(mm_cMap, "clone", mm_undefined, -1);
     rb_define_method(mm_cMap, "dup", mm_undefined, -1);
     rb_define_method(mm_cMap, "<=>", mm_cmp, 1);
@@ -1497,10 +1562,18 @@ Init_mmap()
     rb_define_method(mm_cMap, "chop", mm_undefined, -1);
     rb_define_method(mm_cMap, "chomp", mm_undefined, -1);
     rb_define_method(mm_cMap, "strip", mm_undefined, -1);
+#if RUBY_VERSION_CODE >= 171
+    rb_define_method(mm_cMap, "lstrip", mm_undefined, -1);
+    rb_define_method(mm_cMap, "rstrip", mm_undefined, -1);
+#endif
 
     rb_define_method(mm_cMap, "sub!", mm_sub_bang, -1);
     rb_define_method(mm_cMap, "gsub!", mm_gsub_bang, -1);
-    rb_define_method(mm_cMap, "strip!", mm_strip_bang, -1);
+    rb_define_method(mm_cMap, "strip!", mm_strip_bang, 0);
+#if RUBY_VERSION_CODE >= 171
+    rb_define_method(mm_cMap, "lstrip!", mm_lstrip_bang, 0);
+    rb_define_method(mm_cMap, "rstrip!", mm_rstrip_bang, 0);
+#endif
     rb_define_method(mm_cMap, "chop!", mm_chop_bang, 0);
     rb_define_method(mm_cMap, "chomp!", mm_chomp_bang, -1);
 
diff --git a/tests/mmapt.rb b/tests/mmapt.rb
new file mode 100644
index 0000000..1c515a6
--- /dev/null
+++ b/tests/mmapt.rb
@@ -0,0 +1,186 @@
+#!/usr/bin/ruby
+$LOAD_PATH.unshift *%w{.. . tests}
+require 'mmap'
+require 'runit/testcase'
+require 'runit/cui/testrunner'
+
+$mmap, $str = nil, nil
+
+class TestMmap < RUNIT::TestCase
+   def internal_init
+      $mmap.unmap if $mmap
+      mmap = open("tmp/mmap", "w")
+      $str = <<-EOT
+
+ some randomly generated text
+
+ well, in reality not really, really random
+      EOT
+      mmap.print $str
+      mmap.close
+      assert_kind_of(Mmap, $mmap = Mmap.new("tmp/mmap", "rw"), "<open>")
+   end
+
+   def test_00_init
+      internal_init
+      assert_equal($mmap.length, $str.length, "<lenght>")
+   end
+
+   def test_01_aref
+      max = $str.size * 2
+      72.times do
+	 ran1 = rand(max)
+	 assert_equal($mmap[ran1], $str[ran1], "<aref>");
+	 assert_equal($mmap[-ran1], $str[-ran1], "<aref>");
+	 ran2 = rand(max)
+	 assert_equal($mmap[ran1, ran2], $str[ran1, ran2], "<double aref>");
+	 assert_equal($mmap[-ran1, ran2], $str[-ran1, ran2], "<double aref>");
+	 assert_equal($mmap[ran1, -ran2], $str[ran1, -ran2], "<double aref>");
+	 assert_equal($mmap[-ran1, -ran2], $str[-ran1, -ran2], "<double aref>");
+	 assert_equal($mmap[ran1 .. ran2], $str[ran1 .. ran2], "<double aref>");
+	 assert_equal($mmap[-ran1 .. ran2], $str[-ran1 .. ran2], "<double aref>");
+	 assert_equal($mmap[ran1 .. -ran2], $str[ran1 .. -ran2], "<double aref>");
+	 assert_equal($mmap[-ran1 .. -ran2], $str[-ran1 .. -ran2], "<double aref>");
+      end
+      assert_equal($mmap[/random/], $str[/random/], "<aref regexp>")
+      assert_equal($mmap[/real/], $str[/real/], "<aref regexp>")
+      assert_equal($mmap[/none/], $str[/none/], "<aref regexp>")
+   end
+
+   def internal_aset(a, b = nil, c = true)
+      access = if b
+		  repl = ''
+		  rand(12).times do
+	              repl << (65 + rand(25))
+                  end
+		  if c 
+		     "[a, b] = '#{repl}'"
+		  else
+		     "[a .. b] = '#{repl}'"
+		  end
+	       else
+		  "[a] = #{(65 + rand(25))}"
+	       end
+      begin
+	 eval "$str#{access}"
+      rescue IndexError, RangeError
+	 begin
+	    eval "$mmap#{access}"
+	 rescue IndexError, RangeError
+	 else
+	    assert_fail("*must* fail with IndexError")
+	 end
+      else
+	 eval "$mmap#{access}"
+      end
+      assert_equal($mmap.to_str, $str, "<internal aset>")
+   end
+
+   def test_02_aset
+      max = $str.size * 2
+      72.times do
+	 ran1 = rand(max)
+	 internal_aset(ran1)
+	 internal_aset(-ran1)
+	 ran2 = rand(max)
+	 internal_aset(ran1, ran2)
+	 internal_aset(ran1, -ran2)
+	 internal_aset(-ran1, ran2)
+	 internal_aset(-ran1, -ran2)
+	 internal_aset(ran1, ran2, false)
+	 internal_aset(ran1, -ran2, false)
+	 internal_aset(-ran1, ran2, false)
+	 internal_aset(-ran1, -ran2, false)
+      end
+      internal_init
+   end
+
+   def internal_slice(a, b = nil, c = true)
+      access = if b
+		  if c 
+		     ".slice!(a, b)"
+		  else
+		     ".slice!(a .. b)"
+		  end
+	       else
+		  ".slice!(a)"
+	       end
+      begin
+	 eval "$str#{access}"
+      rescue IndexError, RangeError
+	 begin
+	    eval "$mmap#{access}"
+	 rescue IndexError, RangeError
+	 else
+	    assert_fail("*must* fail with IndexError")
+	 end
+      else
+	 eval "$mmap#{access}"
+      end
+      assert_equal($mmap.to_str, $str, "<internal aset>")
+   end
+
+   def test_03_slice
+      max = $str.size * 2
+      72.times do
+	 ran1 = rand(max)
+	 internal_slice(ran1)
+	 internal_slice(-ran1)
+	 ran2 = rand(max)
+	 internal_slice(ran1, ran2)
+	 internal_slice(ran1, -ran2)
+	 internal_slice(-ran1, ran2)
+	 internal_slice(-ran1, -ran2)
+	 internal_slice(ran1, ran2, false)
+	 internal_slice(ran1, -ran2, false)
+	 internal_slice(-ran1, ran2, false)
+	 internal_slice(-ran1, -ran2, false)
+      end
+      internal_init
+   end
+
+   def test_04_reg
+      assert_equal($mmap.scan(/random/), $str.scan(/random/), "<scan>")
+      assert_equal($mmap.index("really"), $str.index("really"), "<index>")
+      assert_equal($mmap.rindex("really"), $str.rindex("really"), "<rindex>")
+      ('a' .. 'z').each do |i|
+	 assert_equal($mmap.index(i), $str.index(i), "<index>")
+	 assert_equal($mmap.rindex(i), $str.rindex(i), "<rindex>")
+      end
+      assert_equal($mmap.sub!(/real/, 'XXXX'), $str.sub!(/real/, 'XXXX'), "<sub!>")
+      assert_equal($mmap.to_str, $str, "<after sub!>")
+      assert_equal($mmap.gsub!(/real/, 'XXXX'), $str.gsub!(/real/, 'XXXX'), "<sub!>")
+      assert_equal($mmap.to_str, $str, "<after gsub!>")
+      assert_equal($mmap.gsub!(/YYYY/, 'XXXX'), $str.gsub!(/YYYY/, 'XXXX'), "<sub!>")
+      assert_equal($mmap.to_str, $str, "<after gsub!>")
+      assert_equal($mmap.split(/\w+/), $str.split(/\w+/), "<split>")
+      assert_equal($mmap.split(/\W+/), $str.split(/\W+/), "<split>")
+      assert_equal($mmap.crypt("abc"), $str.crypt("abc"), "<crypt>")
+      internal_init
+   end
+
+   def internal_modify idmod, *args
+      if res = $str.method(idmod)[*args]
+	 assert_equal($mmap.method(idmod)[*args].to_str, res, "<#{idmod}>")
+      else
+	 assert_equal($mmap.method(idmod)[*args], res, "<#{idmod}>")
+      end
+   end
+
+   def test_05_modify
+      internal_modify(:reverse!)
+      internal_modify(:upcase!)
+      internal_modify(:downcase!)
+      internal_modify(:capitalize!)
+      internal_modify(:swapcase!)
+      internal_modify(:strip!)
+      internal_modify(:chop!)
+      internal_modify(:chomp!)
+      internal_modify(:tr!, 'abcdefghi', '123456789')
+      internal_modify(:tr_s!, 'jklmnopqr', '123456789')
+   end
+
+
+end
+
+RUNIT::CUI::TestRunner.run(TestMmap.suite)
-- 
cgit v1.1-2-g2b99