summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changes7
-rw-r--r--mmap.c162
-rw-r--r--tests/mmapt.rb37
3 files changed, 147 insertions, 59 deletions
diff --git a/Changes b/Changes
index 713506f..f6c66fa 100644
--- a/Changes
+++ b/Changes
@@ -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
diff --git a/mmap.c b/mmap.c
index 37d400b..5d33fba 100644
--- a/mmap.c
+++ b/mmap.c
@@ -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