summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguy Decoux <ts@moulon.inra.fr>2009-02-28 20:08:24 +0100
committerguy Decoux <ts@moulon.inra.fr>2009-02-28 20:08:24 +0100
commita181d44ee4b78d7e016cf5b9e8fd5591723615bd (patch)
treeb78f0d2b978a9df55acd5dfd222ceebfcbc50c03
parentddd4bfbddf5d2972f5eaf47bc6b89d154203f45f (diff)
downloadmmap-ruby-a181d44ee4b78d7e016cf5b9e8fd5591723615bd.zip
mmap-ruby-a181d44ee4b78d7e016cf5b9e8fd5591723615bd.tar.gz
mmap-0.1.8
-rw-r--r--Changes7
-rw-r--r--README.en3
-rwxr-xr-xdocs/b.rb108
-rw-r--r--docs/mmap.rb320
-rw-r--r--extconf.rb22
-rw-r--r--mmap.c116
-rw-r--r--mmap.html529
-rw-r--r--mmap.rd126
-rw-r--r--tests/mmapt.rb15
-rw-r--r--tests/runit_.rb44
10 files changed, 835 insertions, 455 deletions
diff --git a/Changes b/Changes
index 8da5335..683bacc 100644
--- a/Changes
+++ b/Changes
@@ -37,3 +37,10 @@
* added "a" for ::new
* experimental EXP_INCR_SIZE (4096) ("increment" => 4096)
* tests for RUNIT/Test::Unit
+
+-- 0.1.8
+
+* test for madvise(2)
+* don't test size for MAP_ANON
+* added syntax Mmap(nil, length)
+* documentation : make rd2; make rdoc
diff --git a/README.en b/README.en
index 17d411f..a1e88d9 100644
--- a/README.en
+++ b/README.en
@@ -9,6 +9,9 @@
* Documentation
+ make rd2
+ make rdoc
+
See mmap.rd, mmap.html
* Tests : if you have rubyunit
diff --git a/docs/b.rb b/docs/b.rb
new file mode 100755
index 0000000..2b7adfb
--- /dev/null
+++ b/docs/b.rb
@@ -0,0 +1,108 @@
+#!/usr/bin/ruby
+
+def yield_or_not(primary)
+ text = primary.sub(/\{\s*\|([^|]+)\|[^}]*\}/, '')
+ if text != primary
+ "def #{text}yield #$1\nend"
+ else
+ "def #{text}end"
+ end
+end
+
+def normalize(text)
+ norm = text.gsub(/\(\(\|([^|]+)\|\)\)/, '<em>\\1</em>')
+ norm.gsub(/\(\(\{/, '<tt>').gsub!(/\}\)\)/, '</tt>')
+ norm.gsub!(/\(\(<([^|>]+)[^>]*>\)\)/, '<em>\\1</em>')
+ norm.gsub!(/^\s*:\s/, ' * ')
+ norm
+end
+
+def intern_def(text, names, fout)
+ fout.puts "##{normalize(text.join('#'))}"
+ fout.puts yield_or_not(names[0])
+ if names.size > 1
+ n = names[0].chomp.sub(/\(.*/, '')
+ names[1 .. -1].each do |na|
+ nd = na.chomp.sub(/\(.*/, '')
+ if nd != n
+ fout.puts "#same than <em>#{n}</em>"
+ fout.puts yield_or_not(na)
+ end
+ end
+ end
+end
+
+def output_def(text, names, keywords, fout)
+ if ! names.empty?
+ keywords.each do |k|
+ fout.puts k
+ intern_def(text, names, fout)
+ fout.puts "end" if k != ""
+ end
+ end
+end
+
+def loop_file(file, fout)
+ text, keywords, names = [], [""], []
+ comment = false
+ rep, indent, vide = '', -1, nil
+ IO.foreach(file) do |line|
+ if /^#\^/ =~ line
+ comment = ! comment
+ next
+ end
+ if comment
+ fout.puts "# #{normalize(line)}"
+ next
+ end
+ case line
+ when /^\s*$/
+ vide = true
+ text.push line
+ when /^#\^/
+ comment = ! comment
+ when /^##/
+ line[0] = ?\s
+ fout.puts line
+ when /^#\s*(.+?)\s*$/
+ keyword = $1
+ output_def(text, names, keywords, fout)
+ text, names = [], []
+ keywords = keyword.split(/\s*##\s*/)
+ if keywords.size == 1
+ fout.puts keywords[0]
+ keywords = [""]
+ end
+ when /^#/
+ when /^---/
+ name = $'
+ if vide
+ output_def(text, names, keywords, fout)
+ text, names = [], []
+ rep, indent, vide = '', -1, false
+ end
+ names.push name
+ else
+ vide = false
+ if line.sub!(/^(\s*): /, '* ')
+ indent += ($1 <=> rep)
+ rep = $1
+ else
+ line.sub!(/^#{rep}/, '')
+ end
+ if indent >= 0
+ line = (' ' * indent) + line
+ else
+ line.sub!(/\A\s*/, '')
+ end
+ text.push line
+ end
+ end
+end
+
+File.open("#{ARGV[0]}.rb", "w") do |fout|
+ loop_file("../#{ARGV[0]}.rd", fout)
+ Dir['*.rd'].each do |file|
+ loop_file(file, fout)
+ end
+end
diff --git a/docs/mmap.rb b/docs/mmap.rb
new file mode 100644
index 0000000..ba00571
--- /dev/null
+++ b/docs/mmap.rb
@@ -0,0 +1,320 @@
+# The Mmap class implement memory-mapped file objects
+#
+# === WARNING
+# === The variables $' and $` are not available with gsub! and sub!
+class Mmap
+include Comparable
+include Enumerable
+class << self
+
+#disable paging of all pages mapped. <em>flag</em> can be
+#<em>Mmap::MCL_CURRENT</em> or <em>Mmap::MCL_FUTURE</em>
+#
+def lockall(flag)
+end
+
+#create a new Mmap object
+#
+#* <em>file</em>
+# Pathname of the file, if <em>nil</em> is given an anonymous map
+# is created <em>Mmanp::MAP_ANON</em>
+#
+#* <em>mode</em>
+# Mode to open the file, it can be "r", "w", "rw", "a"
+#
+#* <em>protection</em>
+# specify the nature of the mapping
+#
+# * <em>Mmap::MAP_SHARED</em>
+# Creates a mapping that's shared with all other processes
+# mapping the same areas of the file.
+# The default value is <em>Mmap::MAP_SHARED</em>
+#
+# * <em>Mmap::MAP_PRIVATE</em>
+# Creates a private copy-on-write mapping, so changes to the
+# contents of the mmap object will be private to this process
+#
+#* <em>options</em>
+# Hash. If one of the options <em>length</em> or <em>offset</em>
+# is specified it will not possible to modify the size of
+# the mapped file.
+#
+# * <em>length</em>
+# Maps <em>length</em> bytes from the file
+#
+# * <em>offset</em>
+# The mapping begin at <em>offset</em>
+#
+# * <em>advice</em>
+# The type of the access (see #madvise)
+#
+#
+def new(file, mode = "r", protection = Mmap::MAP_SHARED, options = {})
+end
+
+#reenable paging
+#
+def unlockall
+end
+end
+
+#add <em>count</em> bytes to the file (i.e. pre-extend the file)
+#
+def extend(count)
+end
+
+#<em>advice</em> can have the value <em>Mmap::MADV_NORMAL</em>,
+#<em>Mmap::MADV_RANDOM</em>, <em>Mmap::MADV_SEQUENTIAL</em>,
+#<em>Mmap::MADV_WILLNEED</em>, <em>Mmap::MADV_DONTNEED</em>
+#
+def madvise(advice)
+end
+
+#change the mode, value must be "r", "w" or "rw"
+#
+def mprotect(mode)
+end
+
+#disable paging
+#
+def mlock
+end
+
+#flush the file
+#
+def msync
+end
+#same than <em> msync</em>
+def flush
+end
+
+#reenable paging
+#
+def munlock
+end
+
+#terminate the association
+#
+#=== Other methods with the same syntax than for the class String
+#
+#
+def munmap
+end
+
+#
+def self == other
+end
+
+#
+def self > other
+end
+
+#
+def self >= other
+end
+
+#
+def self < other
+end
+
+#
+def self <= other
+end
+
+#
+def self === other
+end
+
+#
+def self << other
+end
+
+#
+def self =~ other
+end
+
+#
+def self[nth]
+end
+
+#
+def self[start..last]
+end
+
+#
+def self[start, length]
+end
+
+#
+def self[nth] = val
+end
+
+#
+def self[start..last] = val
+end
+
+#
+def self[start, len] = val
+end
+
+#
+def self <=> other
+end
+
+#
+def <<(other)
+end
+
+#
+def casecmp(other) >= 1.7.1
+end
+
+#
+def concat(other)
+end
+
+#
+def capitalize!
+end
+
+#
+def chop!
+end
+
+#
+def chomp!([rs])
+end
+
+#
+def count(o1 [, o2, ...])
+end
+
+#
+def crypt(salt)
+end
+
+#
+def delete!(str)
+end
+
+#
+def downcase!
+end
+
+#
+def each_byte
+yield char
+end
+
+#
+def each([rs])
+yield line
+end
+
+#
+def each_line([rs])
+yield line
+end
+
+#
+def empty?
+end
+
+#
+def freeze
+end
+
+#
+def frozen
+end
+
+#
+def gsub!(pattern, replace)
+end
+
+#
+def gsub!(pattern)
+yield str
+end
+
+#
+def include?(other)
+end
+
+#
+def index(substr[, pos])
+end
+
+#
+def insert(index, str) >= 1.7.1
+end
+
+#
+def length
+end
+
+#
+def reverse!
+end
+
+#
+def rindex(substr[, pos])
+end
+
+#
+def scan(pattern)
+end
+
+#
+def scan(pattern)
+yield str
+end
+
+#
+def size
+end
+
+#
+def slice
+end
+
+#
+def slice!
+end
+
+#
+def split([sep[, limit]])
+end
+
+#
+def squeeze!([str])
+end
+
+#
+def strip!
+end
+
+#
+def sub!(pattern, replace)
+end
+
+#
+def sub!(pattern)
+yield str
+end
+
+#
+def sum([bits])
+end
+
+#
+def swapcase!
+end
+
+#
+def tr!(search, replace)
+end
+
+#
+def tr_s!(search, replace)
+end
diff --git a/extconf.rb b/extconf.rb
index 73d0ce7..07c59ad 100644
--- a/extconf.rb
+++ b/extconf.rb
@@ -14,7 +14,29 @@ unknown: $(DLLIB)
\t@echo "main() {}" > /tmp/a.c
\t$(CC) -static /tmp/a.c $(OBJS) $(CPPFLAGS) $(DLDFLAGS) -lruby #{CONFIG["LIBS"]} $(LIBS) $(LOCAL_LIBS)
\t@-rm /tmp/a.c a.out
+
+%.html: %.rd
+\trd2 $< > ${<:%.rd=%.html}
+
EOT
+ make.print "HTML = mmap.html"
+ docs = Dir['docs/*.rd']
+ docs.each {|x| make.print " \\\n\t#{x.sub(/\.rd$/, '.html')}" }
+ make.print "\n\nRDOC = mmap.rd"
+ docs.each {|x| make.print " \\\n\t#{x}" }
+ make.puts
+ make.print <<-EOF
+
+rdoc: docs/doc/index.html
+
+docs/doc/index.html: $(RDOC)
+\t@-(cd docs; b.rb mmap; rdoc mmap.rb)
+
+rd2: html
+
+html: $(HTML)
+
+ EOF
ensure
make.close
end
diff --git a/mmap.c b/mmap.c
index 8b7f489..83df09a 100644
--- a/mmap.c
+++ b/mmap.c
@@ -8,6 +8,17 @@
#include <intern.h>
#include "version.h"
+#ifndef MADV_NORMAL
+#ifdef POSIX_MADV_NORMAL
+#define MADV_NORMAL POSIX_MADV_NORMAL
+#define MADV_RANDOM POSIX_MADV_RANDOM
+#define MADV_SEQUENTIAL POSIX_MADV_SEQUENTIAL
+#define MADV_WILLNEED POSIX_MADV_WILLNEED
+#define MADV_DONTNEED POSIX_MADV_DONTNEED
+#define madvise posix_madvise
+#endif
+#endif
+
#include <re.h>
#define BEG(no) regs->beg[no]
@@ -40,8 +51,7 @@ typedef struct {
MMAP_RETTYPE addr;
int smode, pmode, vscope;
int advice, frozen, lock;
- size_t len, real;
- size_t size, incr;
+ size_t len, real, incr;
off_t offset;
char *path;
} mm_mmap;
@@ -201,9 +211,11 @@ mm_expandf(t_mm, len)
if (t_mm->addr == MAP_FAILED) {
rb_raise(rb_eArgError, "mmap failed");
}
+#ifdef MADV_NORMAL
if (t_mm->advice && madvise(t_mm->addr, len, t_mm->advice) == -1) {
rb_raise(rb_eArgError, "madvise(%d)", errno);
}
+#endif
if (t_mm->lock && mlock(t_mm->addr, len) == -1) {
rb_raise(rb_eArgError, "mlock(%d)", errno);
}
@@ -253,9 +265,9 @@ mm_i_options(arg, obj)
key = rb_obj_as_string(key);
options = RSTRING(key)->ptr;
if (strcmp(options, "length") == 0) {
- t_mm->size = NUM2INT(value);
- if (t_mm->size <= 0) {
- rb_raise(rb_eArgError, "Invalid value for length %d", t_mm->size);
+ t_mm->len = NUM2INT(value);
+ if (t_mm->len <= 0) {
+ rb_raise(rb_eArgError, "Invalid value for length %d", t_mm->len);
}
t_mm->frozen |= MM_FIXED;
}
@@ -309,7 +321,7 @@ mm_s_new(argc, argv, obj)
VALUE res, fname, vmode, scope, options;
mm_mmap *t_mm;
char *path, *mode;
- size_t size;
+ size_t size = 0;
off_t offset;
options = Qnil;
@@ -321,7 +333,7 @@ mm_s_new(argc, argv, obj)
vscope = 0;
#ifdef MAP_ANON
if (NIL_P(fname)) {
- vscope = MAP_ANON;
+ vscope = MAP_ANON | MAP_SHARED;
path = 0;
}
else {
@@ -338,40 +350,40 @@ mm_s_new(argc, argv, obj)
Check_SafeStr(fname);
path = RSTRING(fname)->ptr;
#endif
- perm = 0666;
- if (NIL_P(vmode)) {
- mode = "r";
- }
- else if (TYPE(vmode) == T_ARRAY && RARRAY(vmode)->len >= 2) {
- VALUE tmp = RARRAY(vmode)->ptr[0];
- mode = STR2CSTR(tmp);
- perm = NUM2INT(RARRAY(vmode)->ptr[1]);
- }
- else {
- mode = STR2CSTR(vmode);
- }
- if (strcmp(mode, "r") == 0) {
- smode = O_RDONLY;
- pmode = PROT_READ;
- }
- else if (strcmp(mode, "w") == 0) {
- smode = O_WRONLY;
- pmode = PROT_WRITE;
- }
- else if (strcmp(mode, "rw") == 0 || strcmp(mode, "wr") == 0) {
- smode = O_RDWR;
- pmode = PROT_READ | PROT_WRITE;
- }
- else if (strcmp(mode, "a") == 0) {
- smode = O_RDWR | O_CREAT;
- pmode = PROT_READ | PROT_WRITE;
- }
- else {
- rb_raise(rb_eArgError, "Invalid mode %s", mode);
- }
vscope |= NIL_P(scope) ? MAP_SHARED : NUM2INT(scope);
size = 0;
+ perm = 0666;
if (path) {
+ if (NIL_P(vmode)) {
+ mode = "r";
+ }
+ else if (TYPE(vmode) == T_ARRAY && RARRAY(vmode)->len >= 2) {
+ VALUE tmp = RARRAY(vmode)->ptr[0];
+ mode = STR2CSTR(tmp);
+ perm = NUM2INT(RARRAY(vmode)->ptr[1]);
+ }
+ else {
+ mode = STR2CSTR(vmode);
+ }
+ if (strcmp(mode, "r") == 0) {
+ smode = O_RDONLY;
+ pmode = PROT_READ;
+ }
+ else if (strcmp(mode, "w") == 0) {
+ smode = O_WRONLY;
+ pmode = PROT_WRITE;
+ }
+ else if (strcmp(mode, "rw") == 0 || strcmp(mode, "wr") == 0) {
+ smode = O_RDWR;
+ pmode = PROT_READ | PROT_WRITE;
+ }
+ else if (strcmp(mode, "a") == 0) {
+ smode = O_RDWR | O_CREAT;
+ pmode = PROT_READ | PROT_WRITE;
+ }
+ else {
+ rb_raise(rb_eArgError, "Invalid mode %s", mode);
+ }
if ((fd = open(path, smode, perm)) == -1) {
rb_raise(rb_eArgError, "Can't open %s", path);
}
@@ -382,6 +394,9 @@ mm_s_new(argc, argv, obj)
}
else {
fd = -1;
+ if (!NIL_P(vmode) && TYPE(vmode) != T_STRING) {
+ size = NUM2INT(vmode);
+ }
}
#if RUBY_VERSION_CODE >= 172
Data_Get_Struct(obj, mm_mmap, t_mm);
@@ -393,11 +408,11 @@ mm_s_new(argc, argv, obj)
offset = 0;
if (options != Qnil) {
rb_iterate(rb_each, options, mm_i_options, res);
- if ((t_mm->size + t_mm->offset) > st.st_size) {
+ if (path && (t_mm->len + t_mm->offset) > st.st_size) {
rb_raise(rb_eArgError, "invalid value for length (%d) or offset (%d)",
- t_mm->size, t_mm->offset);
+ t_mm->len, t_mm->offset);
}
- if (t_mm->size) size = t_mm->size;
+ if (t_mm->len) size = t_mm->len;
offset = t_mm->offset;
}
init = 0;
@@ -409,6 +424,9 @@ mm_s_new(argc, argv, obj)
rb_warning("Ignoring offset for an anonymous map");
offset = 0;
}
+ smode = O_RDWR;
+ pmode = PROT_READ | PROT_WRITE;
+ t_mm->frozen |= MM_FIXED;
}
else if (size == 0 && (smode & O_RDWR)) {
if (lseek(fd, t_mm->incr - 1, SEEK_END) == -1) {
@@ -425,9 +443,11 @@ mm_s_new(argc, argv, obj)
if (addr == MAP_FAILED || !addr) {
rb_raise(rb_eArgError, "mmap failed (%x)", addr);
}
+#ifdef MADV_NORMAL
if (t_mm->advice && madvise(addr, size, t_mm->advice) == -1) {
rb_raise(rb_eArgError, "madvise(%d)", errno);
}
+#endif
t_mm->addr = addr;
t_mm->len = size;
if (!init) t_mm->real = size;
@@ -526,6 +546,7 @@ mm_mprotect(obj, a)
return obj;
}
+#ifdef MADV_NORMAL
static VALUE
mm_madvise(obj, a)
VALUE obj, a;
@@ -539,6 +560,7 @@ mm_madvise(obj, a)
t_mm->advice = NUM2INT(a);
return Qnil;
}
+#endif
#define StringMmap(b, bp, bl) \
do { \
@@ -992,7 +1014,13 @@ mm_slice_bang(argc, argv, str)
}
buf[i] = rb_str_new(0,0);
result = mm_aref_m(argc, buf, str);
- mm_aset_m(argc+1, buf, str);
+#if RUBY_VERSION_CODE >= 172
+ if (!NIL_P(result)) {
+#endif
+ mm_aset_m(argc+1, buf, str);
+#if RUBY_VERSION_CODE >= 172
+ }
+#endif
return result;
}
@@ -1599,11 +1627,13 @@ Init_mmap()
rb_define_const(mm_cMap, "PROT_NONE", INT2FIX(PROT_NONE));
rb_define_const(mm_cMap, "MAP_SHARED", INT2FIX(MAP_SHARED));
rb_define_const(mm_cMap, "MAP_PRIVATE", INT2FIX(MAP_PRIVATE));
+#ifdef MADV_NORMAL
rb_define_const(mm_cMap, "MADV_NORMAL", INT2FIX(MADV_NORMAL));
rb_define_const(mm_cMap, "MADV_RANDOM", INT2FIX(MADV_RANDOM));
rb_define_const(mm_cMap, "MADV_SEQUENTIAL", INT2FIX(MADV_SEQUENTIAL));
rb_define_const(mm_cMap, "MADV_WILLNEED", INT2FIX(MADV_WILLNEED));
rb_define_const(mm_cMap, "MADV_DONTNEED", INT2FIX(MADV_DONTNEED));
+#endif
#ifdef MAP_DENYWRITE
rb_define_const(mm_cMap, "MAP_DENYWRITE", INT2FIX(MAP_DENYWRITE));
#endif
@@ -1653,8 +1683,10 @@ Init_mmap()
rb_define_method(mm_cMap, "flush", mm_msync, -1);
rb_define_method(mm_cMap, "mprotect", mm_mprotect, 1);
rb_define_method(mm_cMap, "protect", mm_mprotect, 1);
+#ifdef MADV_NORMAL
rb_define_method(mm_cMap, "madvise", mm_madvise, 1);
rb_define_method(mm_cMap, "advise", mm_madvise, 1);
+#endif
rb_define_method(mm_cMap, "mlock", mm_mlock, 0);
rb_define_method(mm_cMap, "lock", mm_mlock, 0);
rb_define_method(mm_cMap, "munlock", mm_munlock, 0);
diff --git a/mmap.html b/mmap.html
index cae24b2..3eaf01a 100644
--- a/mmap.html
+++ b/mmap.html
@@ -1,347 +1,188 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
-<TITLE>mmap.rd</TITLE>
-</HEAD>
-<BODY>
-<H1><A NAME="label:0">Mmap
-</A></H1><!-- RDLabel: "Mmap" -->
-<P>
-<A HREF="ftp://moulon.inra.fr/pub/ruby/">Download</A>
-</P>
-<P>
-The Mmap class implement memory-mapped file objects
-</P>
-<H3><A NAME="label:1">WARNING
-</A></H3><!-- RDLabel: "WARNING" -->
-<P>
-<EM>The variables $' and $` are not available with gsub! and sub!</EM>
-</P>
-<H2><A NAME="label:2">SuperClass
-</A></H2><!-- RDLabel: "SuperClass" -->
-<P>
-Object
-</P>
-<H2><A NAME="label:3">Included Modules
-</A></H2><!-- RDLabel: "Included Modules" -->
-<UL>
-<LI>Comparable
-<LI>Enumerable
-</UL>
-<H2><A NAME="label:4">Class Methods
-</A></H2><!-- RDLabel: "Class Methods" -->
-<DL>
-<DT><A NAME="lockall"><CODE>lockall(<var>flag</var>)</CODE></A><!-- RDLabel: "lockall" -->
-<DD>
-<P>
-disable paging of all pages mapped. <VAR>flag</VAR> can be
-<VAR>Mmap::MCL_CURRENT</VAR> or <VAR>Mmap::MCL_FUTURE</VAR>
-</P>
-</DD>
-<DT><A NAME="new"><CODE>new(<var>file</var>, [<var>mode</var> [, <var>protection</var> [, <var>options</var>]]])</CODE></A><!-- RDLabel: "new" -->
-<DD>
-<P>
-create a new object
-</P>
-
-<DL>
-<DT><A NAME="label:7"><VAR>file</VAR>
-</A><!-- RDLabel: "file" -->
-<DD>
-<P>
-Pathname of the file, if <VAR>nil</VAR> is given an anonymous map
-is created <VAR>Mmanp::MAP_ANON</VAR>
-</P>
-</DD>
-<DT><A NAME="label:8"><VAR>mode</VAR>
-</A><!-- RDLabel: "mode" -->
-<DD>
-<P>
-Mode to open the file, it can be "r", "w" or "rw"
-</P>
-</DD>
-<DT><A NAME="label:9"><VAR>protection</VAR>
-</A><!-- RDLabel: "protection" -->
-<DD>
-<P>
-specify the nature of the mapping
-</P>
-
-<DL>
-<DT><A NAME="label:11"><VAR>Mmap::MAP_SHARED</VAR>
-</A><!-- RDLabel: "Mmap::MAP_SHARED" -->
-<DD>
-<P>
-Creates a mapping that's shared with all other processes
+<?xml version="1.0" ?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>mmap.rd</title>
+</head>
+<body>
+<h1><a name="label:0" id="label:0">Mmap</a></h1><!-- RDLabel: "Mmap" -->
+<p><a href="ftp://moulon.inra.fr/pub/ruby/">Download</a></p>
+<p>The Mmap class implement memory-mapped file objects</p>
+<h3><a name="label:1" id="label:1">WARNING</a></h3><!-- RDLabel: "WARNING" -->
+<h3><a name="label:2" id="label:2">The variables $' and $` are not available with gsub! and sub!</a></h3><!-- RDLabel: "The variables $' and $` are not available with gsub! and sub!" -->
+<h2><a name="label:3" id="label:3">SuperClass</a></h2><!-- RDLabel: "SuperClass" -->
+<p>Object</p>
+<h2><a name="label:4" id="label:4">Included Modules</a></h2><!-- RDLabel: "Included Modules" -->
+<ul>
+<li>Comparable</li>
+<li>Enumerable</li>
+</ul>
+<h2><a name="label:5" id="label:5">Class Methods</a></h2><!-- RDLabel: "Class Methods" -->
+<dl>
+<dt><a name="label:6" id="label:6"><code>lockall(<var>flag</var>)</code></a></dt><!-- RDLabel: "lockall" -->
+<dd>
+<p>disable paging of all pages mapped. <var>flag</var> can be
+<var>Mmap::MCL_CURRENT</var> or <var>Mmap::MCL_FUTURE</var></p></dd>
+<dt><a name="label:7" id="label:7"><code>new(<var>file</var>, <var>mode</var> = "<var>r</var>", <var>protection</var> = <var>Mmap</var>::<var>MAP_SHARED</var>, <var>options</var> = {})</code></a><!-- RDLabel: "new" -->
+<dt><a name="label:8" id="label:8"><code>new(<var>nil</var>, <var>length</var>, <var>protection</var> = <var>Mmap</var>::<var>MAP_SHARED</var>, <var>options</var> = {})</code></a></dt><!-- RDLabel: "new" -->
+<dd>
+<p>create a new Mmap object</p>
+<dl>
+<dt><a name="label:9" id="label:9"><var>file</var>
+</a></dt><!-- RDLabel: "file
+" -->
+<dd>
+<p>Pathname of the file, if <var>nil</var> is given an anonymous map
+is created <var>Mmanp::MAP_ANON</var></p>
+</dd>
+<dt><a name="label:10" id="label:10"><var>mode</var>
+</a></dt><!-- RDLabel: "mode
+" -->
+<dd>
+<p>Mode to open the file, it can be "r", "w", "rw", "a"</p>
+</dd>
+<dt><a name="label:11" id="label:11"><var>protection</var>
+</a></dt><!-- RDLabel: "protection
+" -->
+<dd>
+<p>specify the nature of the mapping</p>
+<dl>
+<dt><a name="label:12" id="label:12"><var>Mmap::MAP_SHARED</var>
+</a></dt><!-- RDLabel: "Mmap::MAP_SHARED
+" -->
+<dd>
+<p>Creates a mapping that's shared with all other processes
mapping the same areas of the file.
-The default value is <VAR>Mmap::MAP_SHARED</VAR>
-</P>
-</DD>
-<DT><A NAME="label:12"><VAR>Mmap::MAP_PRIVATE</VAR>
-</A><!-- RDLabel: "Mmap::MAP_PRIVATE" -->
-<DD>
-<P>
-Creates a private copy-on-write mapping, so changes to the
-contents of the mmap object will be private to this process
-</P>
-</DD>
-</DL>
-</DD>
-<DT><A NAME="label:10"><VAR>options</VAR>
-</A><!-- RDLabel: "options" -->
-<DD>
-<P>
-Hash. If one of the options <VAR>length</VAR> or <VAR>offset</VAR>
+The default value is <var>Mmap::MAP_SHARED</var></p>
+</dd>
+<dt><a name="label:13" id="label:13"><var>Mmap::MAP_PRIVATE</var>
+</a></dt><!-- RDLabel: "Mmap::MAP_PRIVATE
+" -->
+<dd>
+<p>Creates a private copy-on-write mapping, so changes to the
+contents of the mmap object will be private to this process</p>
+</dd>
+</dl>
+</dd>
+<dt><a name="label:14" id="label:14"><var>options</var>
+</a></dt><!-- RDLabel: "options
+" -->
+<dd>
+<p>Hash. If one of the options <var>length</var> or <var>offset</var>
is specified it will not possible to modify the size of
-the mapped file.
-</P>
-
-<DL>
-<DT><A NAME="label:13"><VAR>length</VAR>
-</A><!-- RDLabel: "length" -->
-<DD>
-<P>
-Maps <VAR>length</VAR> bytes from the file
-</P>
-</DD>
-<DT><A NAME="label:14"><VAR>offset</VAR>
-</A><!-- RDLabel: "offset" -->
-<DD>
-<P>
-The mapping begin at <VAR>offset</VAR>
-</P>
-</DD>
-<DT><A NAME="label:15"><VAR>advice</VAR>
-</A><!-- RDLabel: "advice" -->
-<DD>
-<P>
-The type of the access (see #madvise)
-</P>
-</DD>
-</DL>
-</DD>
-</DL>
-</DD>
-<DT><A NAME="unlockall"><CODE>unlockall</CODE></A><!-- RDLabel: "unlockall" -->
-<DD>
-<P>
-reenable paging
-</P>
-</DD>
-</DL>
-<H2><A NAME="label:5">Methods
-</A></H2><!-- RDLabel: "Methods" -->
-<DL>
-<DT><A NAME="extend"><CODE>extend(<var>count</var>)</CODE></A><!-- RDLabel: "extend" -->
-<DD>
-<P>
-add <VAR>count</VAR> bytes to the file (i.e. pre-extend the file)
-</P>
-</DD>
-<DT><A NAME="madvise"><CODE>madvise(<var>advice</var>)</CODE></A><!-- RDLabel: "madvise" -->
-<DD>
-<P>
-<VAR>advice</VAR> can have the value <VAR>Mmap::MADV_NORMAL</VAR>,
-<VAR>Mmap::MADV_RANDOM</VAR>, <VAR>Mmap::MADV_SEQUENTIAL</VAR>,
-<VAR>Mmap::MADV_WILLNEED</VAR>, <VAR>Mmap::MADV_DONTNEED</VAR>
-</P>
-</DD>
-<DT><A NAME="mprotect"><CODE>mprotect(<var>mode</var>)</CODE></A><!-- RDLabel: "mprotect" -->
-<DD>
-<P>
-change the mode, value must be "r", "w" or "rw"
-</P>
-</DD>
-<DT><A NAME="mlock"><CODE>mlock</CODE></A><!-- RDLabel: "mlock" -->
-<DD>
-<P>
-disable paging
-</P>
-</DD>
-<DT><A NAME="msync"><CODE>msync</CODE></A><!-- RDLabel: "msync" -->
-<DT><A NAME="flush"><CODE>flush</CODE></A><!-- RDLabel: "flush" -->
-<DD>
-<P>
-flush the file
-</P>
-</DD>
-<DT><A NAME="munlock"><CODE>munlock</CODE></A><!-- RDLabel: "munlock" -->
-<DD>
-<P>
-reenable paging
-</P>
-</DD>
-<DT><A NAME="munmap"><CODE>munmap</CODE></A><!-- RDLabel: "munmap" -->
-<DD>
-<P>
-terminate the association
-</P>
-</DD>
-</DL>
-<H3><A NAME="label:6">Other methods with the same syntax than the methods of <VAR>String</VAR>
-</A></H3><!-- RDLabel: "Other methods with the same syntax than the methods ofString" -->
-<P>
-self == other
-</P>
-<P>
-self &gt; other
-</P>
-<P>
-self &gt;= other
-</P>
-<P>
-self &lt; other
-</P>
-<P>
-self &lt;= other
-</P>
-<P>
-self === other
-</P>
-<P>
-self &lt;&lt; other
-</P>
-<P>
-self =~ other
-</P>
-<P>
-self[nth]
-</P>
-<P>
-self[start..last]
-</P>
-<P>
-self[start, length]
-</P>
-<P>
-self[nth] = val
-</P>
-<P>
-self[start..last] = val
-</P>
-<P>
-self[start, len] = val
-</P>
-<P>
-self &lt;=&gt; other
-</P>
-<P>
-&lt;&lt;(other)
-</P>
-<P>
-casecmp(other) &gt;= 1.7.1
-</P>
-<P>
-concat(other)
-</P>
-<P>
-capitalize!
-</P>
-<P>
-chop!
-</P>
-<P>
-chomp!([rs])
-</P>
-<P>
-count(o1 [, o2, ...])
-</P>
-<P>
-crypt(salt)
-</P>
-<P>
-delete!(str)
-</P>
-<P>
-downcase!
-</P>
-<P>
-each_byte {|char|...}
-</P>
-<P>
-each([rs]) {|line|...}
-</P>
-<P>
-each_line([rs]) {|line|...}
-</P>
-<P>
-empty?
-</P>
-<P>
-freeze
-</P>
-<P>
-frozen
-</P>
-<P>
-gsub!(pattern, replace)
-</P>
-<P>
-gsub!(pattern) {...}
-</P>
-<P>
-include?(other)
-</P>
-<P>
-index(substr[, pos])
-</P>
-<P>
-insert(index, str) &gt;= 1.7.1
-</P>
-<P>
-length
-</P>
-<P>
-reverse!
-</P>
-<P>
-rindex(substr[, pos])
-</P>
-<P>
-scan(pattern)
-</P>
-<P>
-scan(pattern) {...}
-</P>
-<P>
-size
-</P>
-<P>
-slice
-</P>
-<P>
-slice!
-</P>
-<P>
-split([sep[, limit]])
-</P>
-<P>
-squeeze!([str])
-</P>
-<P>
-strip!
-</P>
-<P>
-sub!(pattern, replace)
-</P>
-<P>
-sub!(pattern) {...}
-</P>
-<P>
-sum([bits])
-</P>
-<P>
-swapcase!
-</P>
-<P>
-tr!(search, replace)
-</P>
-<P>
-tr_s!(search, replace)
-</P>
-<P>
-upcase!
-</P>
+the mapped file.</p>
+<dl>
+<dt><a name="label:15" id="label:15"><var>length</var>
+</a></dt><!-- RDLabel: "length
+" -->
+<dd>
+<p>Maps <var>length</var> bytes from the file</p>
+</dd>
+<dt><a name="label:16" id="label:16"><var>offset</var>
+</a></dt><!-- RDLabel: "offset
+" -->
+<dd>
+<p>The mapping begin at <var>offset</var></p>
+</dd>
+<dt><a name="label:17" id="label:17"><var>advice</var>
+</a></dt><!-- RDLabel: "advice
+" -->
+<dd>
+<p>The type of the access (see #madvise)</p>
+</dd>
+</dl>
+</dd>
+</dl></dd>
+<dt><a name="label:18" id="label:18"><code>unlockall</code></a></dt><!-- RDLabel: "unlockall" -->
+<dd>
+<p>reenable paging</p></dd>
+</dl>
+<h2><a name="label:19" id="label:19">Methods</a></h2><!-- RDLabel: "Methods" -->
+<dl>
+<dt><a name="label:20" id="label:20"><code>extend(<var>count</var>)</code></a></dt><!-- RDLabel: "extend" -->
+<dd>
+<p>add <var>count</var> bytes to the file (i.e. pre-extend the file) </p></dd>
+<dt><a name="label:21" id="label:21"><code>madvise(<var>advice</var>)</code></a></dt><!-- RDLabel: "madvise" -->
+<dd>
+<p><var>advice</var> can have the value <var>Mmap::MADV_NORMAL</var>,
+<var>Mmap::MADV_RANDOM</var>, <var>Mmap::MADV_SEQUENTIAL</var>,
+<var>Mmap::MADV_WILLNEED</var>, <var>Mmap::MADV_DONTNEED</var></p></dd>
+<dt><a name="label:22" id="label:22"><code>mprotect(<var>mode</var>)</code></a></dt><!-- RDLabel: "mprotect" -->
+<dd>
+<p>change the mode, value must be "r", "w" or "rw"</p></dd>
+<dt><a name="label:23" id="label:23"><code>mlock</code></a></dt><!-- RDLabel: "mlock" -->
+<dd>
+<p>disable paging</p></dd>
+<dt><a name="label:24" id="label:24"><code>msync</code></a><!-- RDLabel: "msync" -->
+<dt><a name="label:25" id="label:25"><code>flush</code></a></dt><!-- RDLabel: "flush" -->
+<dd>
+<p>flush the file</p></dd>
+<dt><a name="label:26" id="label:26"><code>munlock</code></a></dt><!-- RDLabel: "munlock" -->
+<dd>
+<p>reenable paging</p></dd>
+<dt><a name="label:27" id="label:27"><code>munmap</code></a></dt><!-- RDLabel: "munmap" -->
+<dd>
+<p>terminate the association</p></dd>
+</dl>
+<h3><a name="label:28" id="label:28">Other methods with the same syntax than for the class String</a></h3><!-- RDLabel: "Other methods with the same syntax than for the class String" -->
+<dl>
+<dt><a name="label:29" id="label:29"><code><var>self</var> == <var>other</var></code></a><!-- RDLabel: "self == other" -->
+<dt><a name="label:30" id="label:30"><code><var>self</var> &gt; <var>other</var></code></a><!-- RDLabel: "self > other" -->
+<dt><a name="label:31" id="label:31"><code><var>self</var> &gt;= <var>other</var></code></a><!-- RDLabel: "self >= other" -->
+<dt><a name="label:32" id="label:32"><code><var>self</var> &lt; <var>other</var></code></a><!-- RDLabel: "self < other" -->
+<dt><a name="label:33" id="label:33"><code><var>self</var> &lt;= <var>other</var></code></a><!-- RDLabel: "self <= other" -->
+<dt><a name="label:34" id="label:34"><code><var>self</var> === <var>other</var></code></a><!-- RDLabel: "self === other" -->
+<dt><a name="label:35" id="label:35"><code><var>self</var> &lt;&lt; <var>other</var></code></a><!-- RDLabel: "self << other" -->
+<dt><a name="label:36" id="label:36"><code><var>self</var> =~ <var>other</var></code></a><!-- RDLabel: "self =~ other" -->
+<dt><a name="label:37" id="label:37"><code>self[nth]</code></a><!-- RDLabel: "self[nth]" -->
+<dt><a name="label:38" id="label:38"><code>self[start..last]</code></a><!-- RDLabel: "self[start..last]" -->
+<dt><a name="label:39" id="label:39"><code>self[start, <var>length</var>]</code></a><!-- RDLabel: "self[start, length]" -->
+<dt><a name="label:40" id="label:40"><code>self[nth] = <var>val</var></code></a><!-- RDLabel: "self[nth] = val" -->
+<dt><a name="label:41" id="label:41"><code>self[start..last] = <var>val</var></code></a><!-- RDLabel: "self[start..last] = val" -->
+<dt><a name="label:42" id="label:42"><code>self[start, <var>len</var>] = <var>val</var></code></a><!-- RDLabel: "self[start, len] = val" -->
+<dt><a name="label:43" id="label:43"><code><var>self</var> &lt;=&gt; <var>other</var></code></a><!-- RDLabel: "self <=> other" -->
+<dt><a name="label:44" id="label:44"><code>&lt;&lt;(<var>other</var>)</code></a><!-- RDLabel: "<<" -->
+<dt><a name="label:45" id="label:45"><code>casecmp(<var>other</var>) &gt;= <var>1</var>.<var>7</var>.<var>1</var></code></a><!-- RDLabel: "casecmp" -->
+<dt><a name="label:46" id="label:46"><code>concat(<var>other</var>)</code></a><!-- RDLabel: "concat" -->
+<dt><a name="label:47" id="label:47"><code>capitalize!</code></a><!-- RDLabel: "capitalize!" -->
+<dt><a name="label:48" id="label:48"><code>chop!</code></a><!-- RDLabel: "chop!" -->
+<dt><a name="label:49" id="label:49"><code>chomp!([<var>rs</var>])</code></a><!-- RDLabel: "chomp!" -->
+<dt><a name="label:50" id="label:50"><code>count(<var>o1</var> [, <var>o2</var>, ...])</code></a><!-- RDLabel: "count" -->
+<dt><a name="label:51" id="label:51"><code>crypt(<var>salt</var>)</code></a><!-- RDLabel: "crypt" -->
+<dt><a name="label:52" id="label:52"><code>delete!(<var>str</var>)</code></a><!-- RDLabel: "delete!" -->
+<dt><a name="label:53" id="label:53"><code>downcase!</code></a><!-- RDLabel: "downcase!" -->
+<dt><a name="label:54" id="label:54"><code>each_byte {|<var>char</var>|...}</code></a><!-- RDLabel: "each_byte" -->
+<dt><a name="label:55" id="label:55"><code>each([<var>rs</var>]) {|<var>line</var>|...}</code></a><!-- RDLabel: "each" -->
+<dt><a name="label:56" id="label:56"><code>each_line([<var>rs</var>]) {|<var>line</var>|...}</code></a><!-- RDLabel: "each_line" -->
+<dt><a name="label:57" id="label:57"><code>empty?</code></a><!-- RDLabel: "empty?" -->
+<dt><a name="label:58" id="label:58"><code>freeze</code></a><!-- RDLabel: "freeze" -->
+<dt><a name="label:59" id="label:59"><code>frozen</code></a><!-- RDLabel: "frozen" -->
+<dt><a name="label:60" id="label:60"><code>gsub!(<var>pattern</var>, <var>replace</var>)</code></a><!-- RDLabel: "gsub!" -->
+<dt><a name="label:61" id="label:61"><code>gsub!(<var>pattern</var>) {|<var>str</var>|...}</code></a><!-- RDLabel: "gsub!" -->
+<dt><a name="label:62" id="label:62"><code>include?(<var>other</var>)</code></a><!-- RDLabel: "include?" -->
+<dt><a name="label:63" id="label:63"><code>index(<var>substr</var>[, <var>pos</var>])</code></a><!-- RDLabel: "index" -->
+<dt><a name="label:64" id="label:64"><code>insert(<var>index</var>, <var>str</var>) &gt;= <var>1</var>.<var>7</var>.<var>1</var></code></a><!-- RDLabel: "insert" -->
+<dt><a name="label:65" id="label:65"><code>length</code></a><!-- RDLabel: "length" -->
+<dt><a name="label:66" id="label:66"><code>reverse!</code></a><!-- RDLabel: "reverse!" -->
+<dt><a name="label:67" id="label:67"><code>rindex(<var>substr</var>[, <var>pos</var>])</code></a><!-- RDLabel: "rindex" -->
+<dt><a name="label:68" id="label:68"><code>scan(<var>pattern</var>)</code></a><!-- RDLabel: "scan" -->
+<dt><a name="label:69" id="label:69"><code>scan(<var>pattern</var>) {|<var>str</var>| ...}</code></a><!-- RDLabel: "scan" -->
+<dt><a name="label:70" id="label:70"><code>size</code></a><!-- RDLabel: "size" -->
+<dt><a name="label:71" id="label:71"><code>slice</code></a><!-- RDLabel: "slice" -->
+<dt><a name="label:72" id="label:72"><code>slice!</code></a><!-- RDLabel: "slice!" -->
+<dt><a name="label:73" id="label:73"><code>split([<var>sep</var>[, <var>limit</var>]])</code></a><!-- RDLabel: "split" -->
+<dt><a name="label:74" id="label:74"><code>squeeze!([<var>str</var>])</code></a><!-- RDLabel: "squeeze!" -->
+<dt><a name="label:75" id="label:75"><code>strip!</code></a><!-- RDLabel: "strip!" -->
+<dt><a name="label:76" id="label:76"><code>sub!(<var>pattern</var>, <var>replace</var>)</code></a><!-- RDLabel: "sub!" -->
+<dt><a name="label:77" id="label:77"><code>sub!(<var>pattern</var>) {|<var>str</var>| ...}</code></a><!-- RDLabel: "sub!" -->
+<dt><a name="label:78" id="label:78"><code>sum([<var>bits</var>])</code></a><!-- RDLabel: "sum" -->
+<dt><a name="label:79" id="label:79"><code>swapcase!</code></a><!-- RDLabel: "swapcase!" -->
+<dt><a name="label:80" id="label:80"><code>tr!(<var>search</var>, <var>replace</var>)</code></a><!-- RDLabel: "tr!" -->
+<dt><a name="label:81" id="label:81"><code>tr_s!(<var>search</var>, <var>replace</var>)</code></a><!-- RDLabel: "tr_s!" -->
+<dt><a name="label:82" id="label:82"><code>upcase!</code></a><!-- RDLabel: "upcase!" -->
+</dl>
-</BODY>
-</HTML>
+</body>
+</html>
diff --git a/mmap.rd b/mmap.rd
index 43c7f3d..81fd8d8 100644
--- a/mmap.rd
+++ b/mmap.rd
@@ -3,10 +3,12 @@
((<Download|URL:ftp://moulon.inra.fr/pub/ruby/>))
+#^
The Mmap class implement memory-mapped file objects
=== WARNING
-((*The variables $' and $` are not available with gsub! and sub!*))
+=== The variables $' and $` are not available with gsub! and sub!
+#^
== SuperClass
@@ -16,15 +18,19 @@ Object
* Comparable
* Enumerable
-
+# class Mmap
+# include Comparable
+# include Enumerable
+# class << self
== Class Methods
--- lockall(flag)
disable paging of all pages mapped. ((|flag|)) can be
((|Mmap::MCL_CURRENT|)) or ((|Mmap::MCL_FUTURE|))
---- new(file, [mode [, protection [, options]]])
- create a new object
+--- new(file, mode = "r", protection = Mmap::MAP_SHARED, options = {})
+--- new(nil, length, protection = Mmap::MAP_SHARED, options = {})
+ create a new Mmap object
: ((|file|))
Pathname of the file, if ((|nil|)) is given an anonymous map
@@ -63,6 +69,7 @@ Object
--- unlockall
reenable paging
+# end
== Methods
--- extend(count)
@@ -89,114 +96,115 @@ Object
--- munmap
terminate the association
-=== Other methods with the same syntax than the methods of ((|String|))
+=== Other methods with the same syntax than for the class String
+
-self == other
+--- self == other
-self > other
+--- self > other
-self >= other
+--- self >= other
-self < other
+--- self < other
-self <= other
+--- self <= other
-self === other
+--- self === other
-self << other
+--- self << other
-self =~ other
+--- self =~ other
-self[nth]
+--- self[nth]
-self[start..last]
+--- self[start..last]
-self[start, length]
+--- self[start, length]
-self[nth] = val
+--- self[nth] = val
-self[start..last] = val
+--- self[start..last] = val
-self[start, len] = val
+--- self[start, len] = val
-self <=> other
+--- self <=> other
-<<(other)
+--- <<(other)
-casecmp(other) >= 1.7.1
+--- casecmp(other) >= 1.7.1
-concat(other)
+--- concat(other)
-capitalize!
+--- capitalize!
-chop!
+--- chop!
-chomp!([rs])
+--- chomp!([rs])
-count(o1 [, o2, ...])
+--- count(o1 [, o2, ...])
-crypt(salt)
+--- crypt(salt)
-delete!(str)
+--- delete!(str)
-downcase!
+--- downcase!
-each_byte {|char|...}
+--- each_byte {|char|...}
-each([rs]) {|line|...}
+--- each([rs]) {|line|...}
-each_line([rs]) {|line|...}
+--- each_line([rs]) {|line|...}
-empty?
+--- empty?
-freeze
+--- freeze
-frozen
+--- frozen
-gsub!(pattern, replace)
+--- gsub!(pattern, replace)
-gsub!(pattern) {...}
+--- gsub!(pattern) {|str|...}
-include?(other)
+--- include?(other)
-index(substr[, pos])
+--- index(substr[, pos])
-insert(index, str) >= 1.7.1
+--- insert(index, str) >= 1.7.1
-length
+--- length
-reverse!
+--- reverse!
-rindex(substr[, pos])
+--- rindex(substr[, pos])
-scan(pattern)
+--- scan(pattern)
-scan(pattern) {...}
+--- scan(pattern) {|str| ...}
-size
+--- size
-slice
+--- slice
-slice!
+--- slice!
-split([sep[, limit]])
+--- split([sep[, limit]])
-squeeze!([str])
+--- squeeze!([str])
-strip!
+--- strip!
-sub!(pattern, replace)
+--- sub!(pattern, replace)
-sub!(pattern) {...}
+--- sub!(pattern) {|str| ...}
-sum([bits])
+--- sum([bits])
-swapcase!
+--- swapcase!
-tr!(search, replace)
+--- tr!(search, replace)
-tr_s!(search, replace)
+--- tr_s!(search, replace)
-upcase!
+--- upcase!
=end
diff --git a/tests/mmapt.rb b/tests/mmapt.rb
index a7a049c..c6a1fdc 100644
--- a/tests/mmapt.rb
+++ b/tests/mmapt.rb
@@ -2,17 +2,12 @@
$LOAD_PATH.unshift *%w{.. . tests}
require 'mmap'
require 'ftools'
-begin
- require 'test/unit'
- Inh = Test::Unit
-rescue LoadError
- require 'runit/testcase'
- require 'runit/cui/testrunner'
- Inh = RUNIT
-end
+require 'runit_'
$mmap, $str = nil, nil
+Inh = defined?(RUNIT) ? RUNIT : Test::Unit
+
class TestMmap < Inh::TestCase
def internal_init
$mmap.unmap if $mmap
@@ -70,7 +65,7 @@ class TestMmap < Inh::TestCase
eval "$mmap#{access}"
rescue IndexError, RangeError
else
- assert_fail("*must* fail with IndexError")
+ flunk("*must* fail with IndexError")
end
else
eval "$mmap#{access}"
@@ -114,7 +109,7 @@ class TestMmap < Inh::TestCase
eval "$mmap#{access}"
rescue IndexError, RangeError
else
- assert_fail("*must* fail with IndexError")
+ flunk("*must* fail with IndexError")
end
else
eval "$mmap#{access}"
diff --git a/tests/runit_.rb b/tests/runit_.rb
new file mode 100644
index 0000000..0479592
--- /dev/null
+++ b/tests/runit_.rb
@@ -0,0 +1,44 @@
+begin
+ require 'test/unit'
+rescue LoadError
+ require 'runit/testcase'
+ require 'runit/cui/testrunner'
+
+ module RUNIT
+ module Assert
+ def assert_raises(error, message = nil)
+ begin
+ yield
+ rescue error
+ assert(true, message)
+ rescue
+ assert_fail("must fail with #{error} : #{string}")
+ else
+ assert_fail("*must* fail : #{string}")
+ end
+ end
+ def flunk(message = "")
+ assert_fail(message)
+ end
+ end
+ end
+end
+
+
+if RUBY_VERSION > "1.7"
+ class Array
+ alias indices select
+ end
+ class Hash
+ alias indexes select
+ end
+ module BDB
+ class Common
+ alias indexes select
+ end
+
+ class Recnum
+ alias indices select
+ end
+ end
+end