diff options
| author | guy Decoux <ts@moulon.inra.fr> | 2009-02-28 20:04:27 +0100 | 
|---|---|---|
| committer | guy Decoux <ts@moulon.inra.fr> | 2009-02-28 20:04:27 +0100 | 
| commit | 9bc1a9681b8530dbf6299cebd778fde23999630b (patch) | |
| tree | 1a34130f2652931a8f9b2b7fa9d556a2a115cb17 | |
| parent | 9a643db7074054fb1af20497a5e36119a833b0c3 (diff) | |
| download | mmap-ruby-9bc1a9681b8530dbf6299cebd778fde23999630b.zip mmap-ruby-9bc1a9681b8530dbf6299cebd778fde23999630b.tar.gz  | |
mmap-0.1.5
| -rw-r--r-- | Changes | 7 | ||||
| -rw-r--r-- | mmap.c | 162 | ||||
| -rw-r--r-- | tests/mmapt.rb | 37 | 
3 files changed, 147 insertions, 59 deletions
@@ -17,3 +17,10 @@  * corrected strip!  * corrected mm_bang_i (reverse!, etc)  * added a small test (make test) + +-- 0.1.5 + +* added str[/a(a)/, 1] for 1.7.1 +* corrected mm_aset (mm_update(str, ...)) +* corrected ==, ===, eql? +* corrected mm_sub_bang, mm_gsub_bang (to_str)
\ No newline at end of file @@ -53,6 +53,8 @@ mm_free(t_mm)  	if (t_mm->path != (char *)-1) {  	    if (t_mm->real < t_mm->len && t_mm->vscope != MAP_PRIVATE &&  		truncate(t_mm->path, t_mm->real) == -1) { +		free(t_mm->path); +		free(t_mm);  		rb_raise(rb_eTypeError, "truncate");  	    }  	    free(t_mm->path); @@ -118,19 +120,28 @@ mm_str(obj, modify)      VALUE ret;      GetMmap(obj, t_mm, modify & ~MM_ORIGIN); +#if RUBY_VERSION_CODE >= 171 +    ret = rb_obj_alloc(rb_cString); +    if (rb_obj_tainted(obj)) { +	OBJ_TAINT(ret); +    } +#else      if (rb_obj_tainted(obj)) {  	ret = rb_tainted_str_new2("");      }      else {  	ret = rb_str_new2("");      } +#endif      if (modify & MM_MODIFY) {  	if (t_mm->frozen & MM_FROZEN) rb_error_frozen("mmap");  	if (!OBJ_TAINTED(ret) && rb_safe_level() >= 4)  	    rb_raise(rb_eSecurityError, "Insecure: can't modify mmap");      }      if (t_mm->frozen & MM_FROZEN) ret = rb_obj_freeze(ret); +#if RUBY_VERSION_CODE < 171      free(RSTRING(ret)->ptr); +#endif      RSTRING(ret)->ptr = t_mm->addr;      RSTRING(ret)->len = t_mm->real;      if (modify & MM_ORIGIN) @@ -181,7 +192,7 @@ mm_i_options(arg, obj)  }  static VALUE -mm_map(argc, argv, obj) +mm_s_new(argc, argv, obj)      VALUE obj, *argv;      int argc;  { @@ -406,7 +417,7 @@ mm_mprotect(obj, a)      if ((pmode & PROT_WRITE) && (t_mm->frozen & MM_FROZEN))   	rb_error_frozen("mmap");      if ((ret = mprotect(t_mm->addr, t_mm->len, pmode)) != 0) { -	rb_raise(rb_eArgError, "msync(%d)", ret); +	rb_raise(rb_eArgError, "mprotect(%d)", ret);      }      t_mm->pmode = pmode;      if (pmode & PROT_READ) { @@ -439,22 +450,20 @@ mm_madvise(obj, a)      return Qnil;  } -#define StringMmap(b, bp, bl)						\ -    do {								\ -        if (TYPE(b) == T_DATA && rb_obj_is_kind_of(b, mm_cMap)) {	\ -	    mm_mmap *b_mm;						\ -									\ -	    GetMmap(b, b_mm, 0);					\ -	    bp = b_mm->addr;						\ -	    bl = b_mm->real;						\ -	}								\ -	else {								\ -	    if (TYPE(b) != T_STRING) b = rb_str_to_str(b);		\ -	    bp = RSTRING(b)->ptr;					\ -	    bl = RSTRING(b)->len;					\ -	}								\ -    } while (0); - +#define StringMmap(b, bp, bl)						   \ +do {									   \ +    if (TYPE(b) == T_DATA && RDATA(b)->dfree == (RUBY_DATA_FUNC)mm_free) { \ +	mm_mmap *b_mm;							   \ +	GetMmap(b, b_mm, 0);						   \ +	bp = b_mm->addr;						   \ +	bl = b_mm->real;						   \ +    }									   \ +    else {								   \ +	if (TYPE(b) != T_STRING) b = rb_str_to_str(b);			   \ +	bp = RSTRING(b)->ptr;						   \ +	bl = RSTRING(b)->len;						   \ +    }									   \ +} while (0);  static void  mm_update(str, beg, len, val) @@ -512,7 +521,7 @@ mm_match(x, y)      long start;      x = mm_str(x, MM_ORIGIN); -    if (TYPE(y) == T_DATA && rb_obj_is_kind_of(y, mm_cMap)) { +    if (TYPE(y) == T_DATA && RDATA(y)->dfree == (RUBY_DATA_FUNC)mm_free) {  	y = mm_to_str(y);      }      switch (TYPE(y)) { @@ -592,7 +601,7 @@ mm_sub_bang(argc, argv, obj)  	iter = 1;      }      else if (argc == 2) { -	repl = rb_obj_as_string(argv[1]);; +	repl = rb_str_to_str(argv[1]);  	if (OBJ_TAINTED(repl)) tainted = 1;      }      else { @@ -634,7 +643,7 @@ mm_sub_bang(argc, argv, obj)  	}  	memcpy(RSTRING(str)->ptr + start,  	       RSTRING(repl)->ptr, RSTRING(repl)->len); -	RSTRING(str)->len += RSTRING(repl)->len - plen; +	t_mm->real += RSTRING(repl)->len - plen;  	if (tainted) OBJ_TAINT(obj);  	res = obj; @@ -661,7 +670,7 @@ mm_gsub_bang(argc, argv, obj)  	iter = 1;      }      else if (argc == 2) { -	repl = rb_obj_as_string(argv[1]); +	repl = rb_str_to_str(argv[1]);  	if (OBJ_TAINTED(repl)) tainted = 1;      }      else { @@ -727,6 +736,39 @@ mm_gsub_bang(argc, argv, obj)  static VALUE mm_index __((int, VALUE *, VALUE)); +#if RUBY_VERSION_CODE >= 171 + +static VALUE +mm_subpat_set(obj, re, offset, val) +    VALUE obj, re; +    int offset; +    VALUE val; +{ +    VALUE str, match; +    int start, end, len; +    mm_mmap *t_mm; +     +    str = mm_str(obj, MM_MODIFY | MM_ORIGIN); +    if (rb_reg_search(re, str, 0, 0) < 0) { +	rb_raise(rb_eIndexError, "regexp not matched"); +    } +    match = rb_backref_get(); +    if (offset >= RMATCH(match)->regs->num_regs) { +	rb_raise(rb_eIndexError, "index %d out of regexp", offset); +    } + +    start = RMATCH(match)->BEG(offset); +    if (start == -1) { +	rb_raise(rb_eIndexError, "regexp group %d not matched", offset); +    } +    end = RMATCH(match)->END(offset); +    len = end - start; +    GetMmap(str, t_mm, MM_MODIFY); +    mm_update(t_mm, start, len, val); +} + +#endif +  static VALUE  mm_aset(str, indx, val)      VALUE str; @@ -759,18 +801,22 @@ mm_aset(str, indx, val)  	return val;        case T_REGEXP: +#if RUBY_VERSION_CODE >= 171 +	  mm_subpat_set(str, 0, indx, val); +#else           {  	    VALUE args[2];  	    args[0] = indx;  	    args[1] = val;  	    mm_sub_bang(2, args, str);  	} +#endif  	return val;        case T_STRING:  	beg = mm_index(1, &indx, str);  	if (beg != -1) { -	    mm_update(str, beg, RSTRING(indx)->len, val); +	    mm_update(t_mm, beg, RSTRING(indx)->len, val);  	}  	return val; @@ -800,10 +846,17 @@ mm_aset_m(argc, argv, str)      if (argc == 3) {  	long beg, len; -	if (TYPE(argv[2]) != T_STRING) argv[2] = rb_str_to_str(argv[2]); -	beg = NUM2INT(argv[0]); -	len = NUM2INT(argv[1]); -	mm_update(t_mm, beg, len, argv[2]); +#if RUBY_VERSION_CODE >= 171 +	if (TYPE(argv[0]) == T_REGEXP) { +	    mm_subpat_set(str, argv[0], NUM2INT(argv[1]), argv[2]); +	} +	else +#endif +	{ +	    beg = NUM2INT(argv[0]); +	    len = NUM2INT(argv[1]); +	    mm_update(t_mm, beg, len, argv[2]); +	}  	return argv[2];      }      if (argc != 2) { @@ -997,7 +1050,7 @@ mm_strip_bang(str)      VALUE str;  {      VALUE l = mm_lstrip_bang(str); -    VALUE r = mm_str_rstrip_bang(str); +    VALUE r = mm_rstrip_bang(str);      if (NIL_P(l) && NIL_P(r)) return Qnil;      return str; @@ -1005,16 +1058,16 @@ mm_strip_bang(str)  #endif -#define MmapStr(b, recycle)						\ -do {									\ -    recycle = 0;							\ -    if (TYPE(b) == T_DATA && rb_obj_is_kind_of(b, mm_cMap) == Qtrue) {	\ -	recycle = 1;							\ -	b = mm_str(b, MM_ORIGIN);					\ -    }									\ -    else {								\ -	b = rb_str_to_str(b);						\ -    }									\ +#define MmapStr(b, recycle)						    \ +do {									    \ +    recycle = 0;							    \ +    if (TYPE(b) == T_DATA &&  RDATA(b)->dfree == (RUBY_DATA_FUNC)mm_free) { \ +	recycle = 1;							    \ +	b = mm_str(b, MM_ORIGIN);					    \ +    }									    \ +    else {								    \ +	b = rb_str_to_str(b);						    \ +    }									    \  } while (0); @@ -1057,13 +1110,34 @@ mm_equal(a, b)      VALUE a, b;  {      VALUE result; -    int recycle = 0; +    if (a == b) return Qtrue; +    if (TYPE(b) != T_DATA || RDATA(b)->dfree != (RUBY_DATA_FUNC)mm_free) +	return Qfalse; +      a = mm_str(a, MM_ORIGIN); -    MmapStr(b, recycle); +    b = mm_str(b, MM_ORIGIN);      result = rb_funcall2(a, rb_intern("=="), 1, &b);      rb_gc_force_recycle(a); -    if (recycle) rb_gc_force_recycle(b); +    rb_gc_force_recycle(b); +    return result; +} + +static VALUE +mm_eql(a, b) +    VALUE a, b; +{ +    VALUE result; +     +    if (a == b) return Qtrue; +    if (TYPE(b) != T_DATA || RDATA(b)->dfree != (RUBY_DATA_FUNC)mm_free) +	return Qfalse; + +    a = mm_str(a, MM_ORIGIN); +    b = mm_str(b, MM_ORIGIN); +    result = rb_funcall2(a, rb_intern("eql?"), 1, &b); +    rb_gc_force_recycle(a); +    rb_gc_force_recycle(b);      return result;  } @@ -1468,7 +1542,7 @@ Init_mmap()      rb_include_module(mm_cMap, rb_mComparable);      rb_include_module(mm_cMap, rb_mEnumerable); -    rb_define_singleton_method(mm_cMap, "new", mm_map, -1); +    rb_define_singleton_method(mm_cMap, "new", mm_s_new, -1);      rb_define_singleton_method(mm_cMap, "mlockall", mm_mlockall, 1);      rb_define_singleton_method(mm_cMap, "lockall", mm_mlockall, 1);      rb_define_singleton_method(mm_cMap, "munlockall", mm_munlockall, 0); @@ -1495,7 +1569,7 @@ Init_mmap()      rb_define_method(mm_cMap, "<=>", mm_cmp, 1);      rb_define_method(mm_cMap, "==", mm_equal, 1);      rb_define_method(mm_cMap, "===", mm_equal, 1); -    rb_define_method(mm_cMap, "eql?", mm_equal, 1); +    rb_define_method(mm_cMap, "eql?", mm_eql, 1);      rb_define_method(mm_cMap, "hash", mm_hash, 0);  #if RUBY_VERSION_CODE >= 171      rb_define_method(mm_cMap, "casecmp", mm_casecmp, 1); @@ -1524,7 +1598,7 @@ Init_mmap()      rb_define_method(mm_cMap, "to_i", mm_undefined, -1);      rb_define_method(mm_cMap, "to_f", mm_undefined, -1); -    rb_define_method(mm_cMap, "to_s", mm_undefined, 0); +    rb_define_method(mm_cMap, "to_s", rb_any_to_s, 0);      rb_define_method(mm_cMap, "to_str", mm_to_str, 0);      rb_define_method(mm_cMap, "inspect", mm_inspect, 0);      rb_define_method(mm_cMap, "dump", mm_undefined, -1); diff --git a/tests/mmapt.rb b/tests/mmapt.rb index 1c515a6..15fe5e4 100644 --- a/tests/mmapt.rb +++ b/tests/mmapt.rb @@ -1,6 +1,7 @@  #!/usr/bin/ruby  $LOAD_PATH.unshift *%w{.. . tests}  require 'mmap' +require 'ftools'  require 'runit/testcase'  require 'runit/cui/testrunner' @@ -9,15 +10,10 @@ $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 +      file = "mmap.c" +      file = "../mmap.c" unless File.exist? file +      File.syscopy file, "tmp/mmap" +      $str = File.readlines("tmp/mmap", nil)[0]        assert_kind_of(Mmap, $mmap = Mmap.new("tmp/mmap", "rw"), "<open>")     end @@ -140,18 +136,18 @@ class TestMmap < RUNIT::TestCase     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>") +      assert_equal($mmap.scan(/include/), $str.scan(/include/), "<scan>") +      assert_equal($mmap.index("rb_raise"), $str.index("rb_raise"), "<index>") +      assert_equal($mmap.rindex("rb_raise"), $str.rindex("rb_raise"), "<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!>") +      $mmap.sub!(/GetMmap/, 'XXXX'); $str.sub!(/GetMmap/, 'XXXX')        assert_equal($mmap.to_str, $str, "<after sub!>") -      assert_equal($mmap.gsub!(/real/, 'XXXX'), $str.gsub!(/real/, 'XXXX'), "<sub!>") +      $mmap.gsub!(/GetMmap/, 'XXXX'); $str.gsub!(/GetMmap/, 'XXXX')        assert_equal($mmap.to_str, $str, "<after gsub!>") -      assert_equal($mmap.gsub!(/YYYY/, 'XXXX'), $str.gsub!(/YYYY/, 'XXXX'), "<sub!>") +      $mmap.gsub!(/YYYY/, 'XXXX'); $str.gsub!(/YYYY/, 'XXXX')        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>") @@ -176,10 +172,21 @@ class TestMmap < RUNIT::TestCase        internal_modify(:strip!)        internal_modify(:chop!)        internal_modify(:chomp!) +      internal_modify(:squeeze!)        internal_modify(:tr!, 'abcdefghi', '123456789')        internal_modify(:tr_s!, 'jklmnopqr', '123456789') +      internal_modify(:delete!, 'A-Z')     end +   def test_06_iterate +      internal_init +      mmap = []; $mmap.each {|l| mmap << l} +      str = []; $str.each {|l| str << l} +      assert_equal(mmap, str, "<each>") +      mmap = []; $mmap.each_byte {|l| mmap << l} +      str = []; $str.each_byte {|l| str << l} +      assert_equal(mmap, str, "<each_byte>") +   end  end  | 
