diff options
-rw-r--r-- | Changes | 6 | ||||
-rw-r--r-- | README.en | 8 | ||||
-rw-r--r-- | extconf.rb | 6 | ||||
-rw-r--r-- | mmap.c | 79 | ||||
-rw-r--r-- | tests/mmapt.rb | 186 |
5 files changed, 281 insertions, 4 deletions
@@ -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) @@ -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. @@ -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) @@ -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) |