From fa598d05504f6dd43e29e0f93a3f25d254ebd7c0 Mon Sep 17 00:00:00 2001 From: guy Decoux Date: Sat, 28 Feb 2009 20:09:29 +0100 Subject: mmap-0.1.9 --- Changes | 5 ++ aa | 2 - b.rb | 2 +- docs/b.rb | 3 +- extconf.rb | 2 +- mmap.c | 192 +++++++++++++++++++++++++++++++++------------------- mmap.html | 210 ++++++++++++++++++++++++++++++++++++++++++--------------- mmap.rd | 75 +++++++++++++++++---- tests/mmapt.rb | 4 ++ 9 files changed, 354 insertions(+), 141 deletions(-) delete mode 100644 aa diff --git a/Changes b/Changes index 683bacc..aac511c 100644 --- a/Changes +++ b/Changes @@ -44,3 +44,8 @@ * don't test size for MAP_ANON * added syntax Mmap(nil, length) * documentation : make rd2; make rdoc + +-- 0.1.9 + +* String#slice! was modified in 1.6.8 +* added ::new(IO) diff --git a/aa b/aa deleted file mode 100644 index 9f9c530..0000000 --- a/aa +++ /dev/null @@ -1,2 +0,0 @@ -123 -abc diff --git a/b.rb b/b.rb index 2acbcf2..617cd8b 100755 --- a/b.rb +++ b/b.rb @@ -7,7 +7,7 @@ f.write("\0" * PAGESIZE) f.write("b.rb") f.write("\0" * PAGESIZE) f.close -m = Mmap.new("aa", "rw", "offset" => 0) +m = Mmap.new("aa", "w", "offset" => 0) p m.size == "b.rb".size + 2 * PAGESIZE p m.scan(/[a-z.]+/) == ["b.rb"] p m.index("b.rb") == PAGESIZE diff --git a/docs/b.rb b/docs/b.rb index 2b7adfb..0839bb3 100755 --- a/docs/b.rb +++ b/docs/b.rb @@ -11,7 +11,8 @@ end def normalize(text) norm = text.gsub(/\(\(\|([^|]+)\|\)\)/, '\\1') - norm.gsub(/\(\(\{/, '').gsub!(/\}\)\)/, '') + norm.gsub!(/\(\(\{/, '') + norm.gsub!(/\}\)\)/, '') norm.gsub!(/\(\(<([^|>]+)[^>]*>\)\)/, '\\1') norm.gsub!(/^\s*:\s/, ' * ') norm diff --git a/extconf.rb b/extconf.rb index 07c59ad..1e8f37f 100644 --- a/extconf.rb +++ b/extconf.rb @@ -30,7 +30,7 @@ unknown: $(DLLIB) rdoc: docs/doc/index.html docs/doc/index.html: $(RDOC) -\t@-(cd docs; b.rb mmap; rdoc mmap.rb) +\t@-(cd docs; $(RUBY) b.rb mmap; rdoc mmap.rb) rd2: html diff --git a/mmap.c b/mmap.c index 83df09a..df6dade 100644 --- a/mmap.c +++ b/mmap.c @@ -43,6 +43,12 @@ #define MAP_FAILED ((caddr_t)-1) #endif /* !MAP_FAILED */ +#ifndef MAP_ANON +#ifdef MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS +#endif +#endif + static VALUE mm_cMap; #define EXP_INCR_SIZE 4096 @@ -50,13 +56,21 @@ static VALUE mm_cMap; typedef struct { MMAP_RETTYPE addr; int smode, pmode, vscope; - int advice, frozen, lock; + int advice, flag; size_t len, real, incr; off_t offset; + VALUE io; char *path; } mm_mmap; static void +mm_mark(t_mm) + mm_mmap *t_mm; +{ + rb_gc_mark(t_mm->io); +} + +static void mm_free(t_mm) mm_mmap *t_mm; { @@ -80,15 +94,17 @@ mm_free(t_mm) #define MM_CHANGE (MM_MODIFY | 4) #define MM_PROTECT 8 -#define MM_FROZEN 1 -#define MM_FIXED 2 +#define MM_FROZEN (1<<0) +#define MM_FIXED (1<<1) +#define MM_ANON (1<<2) +#define MM_LOCK (1<<3) #define GetMmap(obj, t_mm, t_modify) \ Data_Get_Struct(obj, mm_mmap, t_mm); \ if (!t_mm->path) { \ rb_raise(rb_eIOError, "unmapped file"); \ } \ - if ((t_modify & MM_MODIFY) && (t_mm->frozen & MM_FROZEN)) { \ + if ((t_modify & MM_MODIFY) && (t_mm->flag & MM_FROZEN)) { \ rb_error_frozen("mmap"); \ } @@ -120,7 +136,7 @@ mm_freeze(obj) mm_mmap *t_mm; rb_obj_freeze(obj); GetMmap(obj, t_mm, 0); - t_mm->frozen |= MM_FROZEN; + t_mm->flag |= MM_FROZEN; } static VALUE @@ -133,7 +149,7 @@ mm_str(obj, modify) GetMmap(obj, t_mm, modify & ~MM_ORIGIN); if (modify & MM_MODIFY) { - if (t_mm->frozen & MM_FROZEN) rb_error_frozen("mmap"); + if (t_mm->flag & MM_FROZEN) rb_error_frozen("mmap"); if (!OBJ_TAINTED(ret) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify mmap"); } @@ -161,7 +177,7 @@ mm_str(obj, modify) RSTRING(ret)->orig = ret; #endif } - if (t_mm->frozen & MM_FROZEN) { + if (t_mm->flag & MM_FROZEN) { ret = rb_obj_freeze(ret); } return ret; @@ -186,9 +202,12 @@ mm_expandf(t_mm, len) if (t_mm->vscope == MAP_PRIVATE) { rb_raise(rb_eTypeError, "expand for a private map"); } - if (t_mm->frozen & MM_FIXED) { + if (t_mm->flag & MM_FIXED) { rb_raise(rb_eTypeError, "expand for a fixed map"); } + if (!t_mm->path || t_mm->path == (char *)-1) { + rb_raise(rb_eTypeError, "expand for an anonymous map"); + } if (munmap(t_mm->addr, t_mm->len)) { rb_raise(rb_eArgError, "munmap failed"); } @@ -216,7 +235,7 @@ mm_expandf(t_mm, len) rb_raise(rb_eArgError, "madvise(%d)", errno); } #endif - if (t_mm->lock && mlock(t_mm->addr, len) == -1) { + if ((t_mm->flag & MM_LOCK) && mlock(t_mm->addr, len) == -1) { rb_raise(rb_eArgError, "mlock(%d)", errno); } t_mm->len = len; @@ -227,7 +246,7 @@ mm_realloc(t_mm, len) mm_mmap *t_mm; long len; { - if (t_mm->frozen & MM_FROZEN) rb_error_frozen("mmap"); + if (t_mm->flag & MM_FROZEN) rb_error_frozen("mmap"); if (len > t_mm->len) { if ((len - t_mm->len) < t_mm->incr) { len = t_mm->len + t_mm->incr; @@ -269,14 +288,14 @@ mm_i_options(arg, obj) if (t_mm->len <= 0) { rb_raise(rb_eArgError, "Invalid value for length %d", t_mm->len); } - t_mm->frozen |= MM_FIXED; + t_mm->flag |= MM_FIXED; } else if (strcmp(options, "offset") == 0) { t_mm->offset = NUM2INT(value); if (t_mm->offset < 0) { rb_raise(rb_eArgError, "Invalid value for offset %d", t_mm->offset); } - t_mm->frozen |= MM_FIXED; + t_mm->flag |= MM_FIXED; } else if (strcmp(options, "advice") == 0) { t_mm->advice = NUM2INT(value); @@ -300,7 +319,7 @@ mm_s_alloc(argc, argv, obj) VALUE res; mm_mmap *t_mm; - res = Data_Make_Struct(obj, mm_mmap, 0, mm_free, t_mm); + res = Data_Make_Struct(obj, mm_mmap, mm_mark, mm_free, t_mm); t_mm->incr = EXP_INCR_SIZE; return res; } @@ -318,11 +337,12 @@ mm_s_new(argc, argv, obj) struct stat st; int fd, smode, pmode, vscope, perm, init; MMAP_RETTYPE addr; - VALUE res, fname, vmode, scope, options; + VALUE res, fname, fdv, vmode, scope, options; mm_mmap *t_mm; char *path, *mode; size_t size = 0; off_t offset; + int anonymous; options = Qnil; if (argc > 1 && TYPE(argv[argc - 1]) == T_HASH) { @@ -331,29 +351,49 @@ mm_s_new(argc, argv, obj) } rb_scan_args(argc, argv, "12", &fname, &vmode, &scope); vscope = 0; + path = 0; + fd = -1; + anonymous = 0; + fdv = Qnil; #ifdef MAP_ANON if (NIL_P(fname)) { vscope = MAP_ANON | MAP_SHARED; - path = 0; + anonymous = 1; } - else { - Check_SafeStr(fname); - path = RSTRING(fname)->ptr; + else +#endif + { + if (rb_safe_level() > 0 && OBJ_TAINTED(fname)){ + rb_raise(rb_eSecurityError, "Insecure operation"); + } + rb_secure(4); + if (rb_respond_to(fname, rb_intern("fileno"))) { + fdv = rb_funcall2(fname, rb_intern("fileno"), 0, 0); + } + if (NIL_P(fdv)) { + fname = rb_str_to_str(fname); + Check_SafeStr(fname); + path = RSTRING(fname)->ptr; + } + else { + fd = NUM2INT(fdv); + if (fd < 0) { + rb_raise(rb_eArgError, "invalid file descriptor %d", fd); + } + } if (!NIL_P(scope)) { vscope = NUM2INT(scope); +#ifdef MAP_ANON if (vscope & MAP_ANON) { rb_raise(rb_eArgError, "filename specified for an anonymous map"); } +#endif } } -#else - Check_SafeStr(fname); - path = RSTRING(fname)->ptr; -#endif vscope |= NIL_P(scope) ? MAP_SHARED : NUM2INT(scope); size = 0; perm = 0666; - if (path) { + if (!anonymous) { if (NIL_P(vmode)) { mode = "r"; } @@ -372,6 +412,9 @@ mm_s_new(argc, argv, obj) else if (strcmp(mode, "w") == 0) { smode = O_WRONLY; pmode = PROT_WRITE; + if (!NIL_P(fdv)) { + pmode |= PROT_READ; + } } else if (strcmp(mode, "rw") == 0 || strcmp(mode, "wr") == 0) { smode = O_RDWR; @@ -384,8 +427,10 @@ mm_s_new(argc, argv, obj) 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); + if (NIL_P(fdv)) { + if ((fd = open(path, smode, perm)) == -1) { + rb_raise(rb_eArgError, "Can't open %s", path); + } } if (fstat(fd, &st) == -1) { rb_raise(rb_eArgError, "Can't stat %s", path); @@ -402,7 +447,7 @@ mm_s_new(argc, argv, obj) Data_Get_Struct(obj, mm_mmap, t_mm); res = obj; #else - res = Data_Make_Struct(obj, mm_mmap, 0, mm_free, t_mm); + res = Data_Make_Struct(obj, mm_mmap, mm_mark, mm_free, t_mm); t_mm->incr = EXP_INCR_SIZE; #endif offset = 0; @@ -416,7 +461,7 @@ mm_s_new(argc, argv, obj) offset = t_mm->offset; } init = 0; - if (!path) { + if (anonymous) { if (size <= 0) { rb_raise(rb_eArgError, "length not specified for an anonymous map"); } @@ -426,22 +471,29 @@ mm_s_new(argc, argv, obj) } smode = O_RDWR; pmode = PROT_READ | PROT_WRITE; - t_mm->frozen |= MM_FIXED; + t_mm->flag |= MM_FIXED; } - else if (size == 0 && (smode & O_RDWR)) { - if (lseek(fd, t_mm->incr - 1, SEEK_END) == -1) { - rb_raise(rb_eIOError, "Can't lseek %d", t_mm->incr - 1); + else { + if (size == 0 && (smode & O_RDWR)) { + if (lseek(fd, t_mm->incr - 1, SEEK_END) == -1) { + rb_raise(rb_eIOError, "Can't lseek %d", t_mm->incr - 1); + } + if (write(fd, "\000", 1) != 1) { + rb_raise(rb_eIOError, "Can't extend %s", path); + } + init = 1; + size = t_mm->incr; } - if (write(fd, "\000", 1) != 1) { - rb_raise(rb_eIOError, "Can't extend %s", path); + if (!NIL_P(fdv)) { + t_mm->flag |= MM_FIXED; } - init = 1; - size = t_mm->incr; } addr = mmap(0, size, pmode, vscope, fd, offset); - if (fd != -1) close(fd); + if (NIL_P(fdv) && !anonymous) { + close(fd); + } if (addr == MAP_FAILED || !addr) { - rb_raise(rb_eArgError, "mmap failed (%x)", addr); + rb_raise(rb_eArgError, "mmap failed (%d)", errno); } #ifdef MADV_NORMAL if (t_mm->advice && madvise(addr, size, t_mm->advice) == -1) { @@ -455,9 +507,12 @@ mm_s_new(argc, argv, obj) t_mm->vscope = vscope; t_mm->smode = smode; t_mm->path = (path)?ruby_strdup(path):(char *)-1; + if (!NIL_P(fdv)) { + t_mm->io = fname; + } if (smode == O_RDONLY) { res = rb_obj_freeze(res); - t_mm->frozen |= MM_FROZEN; + t_mm->flag |= MM_FROZEN; } else { OBJ_TAINT(res); @@ -524,7 +579,7 @@ mm_mprotect(obj, a) else { pmode = NUM2INT(a); } - if ((pmode & PROT_WRITE) && (t_mm->frozen & MM_FROZEN)) + if ((pmode & PROT_WRITE) && (t_mm->flag & MM_FROZEN)) rb_error_frozen("mmap"); if ((ret = mprotect(t_mm->addr, t_mm->len, pmode)) != 0) { rb_raise(rb_eArgError, "mprotect(%d)", ret); @@ -536,7 +591,7 @@ mm_mprotect(obj, a) t_mm->smode == O_RDONLY; if (t_mm->vscope == MAP_PRIVATE) { obj = rb_obj_freeze(obj); - t_mm->frozen |= MM_FROZEN; + t_mm->flag |= MM_FROZEN; } } } @@ -587,7 +642,7 @@ mm_update(str, beg, len, val) char *valp; long vall; - if (str->frozen & MM_FROZEN) rb_error_frozen("mmap"); + if (str->flag & MM_FROZEN) rb_error_frozen("mmap"); if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len); if (beg < 0) { beg += str->real; @@ -604,7 +659,7 @@ mm_update(str, beg, len, val) StringMmap(val, valp, vall); - if ((str->frozen & MM_FIXED) && vall != len) { + if ((str->flag & MM_FIXED) && vall != len) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } if (len < vall) { @@ -675,7 +730,8 @@ get_pat(pat) } static int -mm_correct_backref() +mm_correct_backref(t_mm) + mm_mmap *t_mm; { VALUE match; struct re_registers *regs; @@ -725,7 +781,7 @@ mm_sub_bang(argc, argv, obj) pat = get_pat(argv[0]); res = Qnil; if (rb_reg_search(pat, str, 0, 0) >= 0) { - start = mm_correct_backref(); + start = mm_correct_backref(t_mm); match = rb_backref_get(); regs = RMATCH(match)->regs; if (iter) { @@ -739,20 +795,20 @@ mm_sub_bang(argc, argv, obj) RSTRING(str)->ptr -= start; } if (OBJ_TAINTED(repl)) tainted = 1; - plen = END(0); + plen = END(0) - BEG(0); if (RSTRING(repl)->len > plen) { mm_realloc(t_mm, RSTRING(str)->len + RSTRING(repl)->len - plen); RSTRING(str)->ptr = t_mm->addr; } if (RSTRING(repl)->len != plen) { - if (t_mm->frozen & MM_FIXED) { + if (t_mm->flag & MM_FIXED) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } - memmove(RSTRING(str)->ptr + start + RSTRING(repl)->len, - RSTRING(str)->ptr + start + plen, - RSTRING(str)->len - start - plen); + memmove(RSTRING(str)->ptr + start + BEG(0) + RSTRING(repl)->len, + RSTRING(str)->ptr + start + BEG(0) + plen, + RSTRING(str)->len - start - BEG(0) - plen); } - memcpy(RSTRING(str)->ptr + start, + memcpy(RSTRING(str)->ptr + start + BEG(0), RSTRING(repl)->ptr, RSTRING(repl)->len); t_mm->real += RSTRING(repl)->len - plen; if (tainted) OBJ_TAINT(obj); @@ -798,7 +854,7 @@ mm_gsub_bang(argc, argv, obj) return Qnil; } while (beg >= 0) { - start = mm_correct_backref(); + start = mm_correct_backref(t_mm); match = rb_backref_get(); regs = RMATCH(match)->regs; if (iter) { @@ -812,20 +868,19 @@ mm_gsub_bang(argc, argv, obj) RSTRING(str)->ptr -= start; } if (OBJ_TAINTED(repl)) tainted = 1; - plen = END(0); + plen = END(0) - BEG(0); if ((t_mm->real + RSTRING(val)->len - plen) > t_mm->len) { mm_realloc(t_mm, RSTRING(str)->len + RSTRING(val)->len - plen); - RSTRING(str)->ptr = t_mm->addr; } if (RSTRING(val)->len != plen) { - if (t_mm->frozen & MM_FIXED) { + if (t_mm->flag & MM_FIXED) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } - memmove(RSTRING(str)->ptr + start + RSTRING(val)->len, - RSTRING(str)->ptr + start + plen, - RSTRING(str)->len - start - plen); + memmove(RSTRING(str)->ptr + start + BEG(0) + RSTRING(val)->len, + RSTRING(str)->ptr + start + BEG(0) + plen, + RSTRING(str)->len - start - BEG(0) - plen); } - memcpy(RSTRING(str)->ptr + start, + memcpy(RSTRING(str)->ptr + start + BEG(0), RSTRING(val)->ptr, RSTRING(val)->len); RSTRING(str)->len += RSTRING(val)->len - plen; t_mm->real = RSTRING(str)->len; @@ -1014,11 +1069,11 @@ mm_slice_bang(argc, argv, str) } buf[i] = rb_str_new(0,0); result = mm_aref_m(argc, buf, str); -#if RUBY_VERSION_CODE >= 172 +#if RUBY_VERSION_CODE >= 168 if (!NIL_P(result)) { #endif mm_aset_m(argc+1, buf, str); -#if RUBY_VERSION_CODE >= 172 +#if RUBY_VERSION_CODE >= 168 } #endif return result; @@ -1094,7 +1149,7 @@ mm_strip_bang(str) while (s <= t && ISSPACE(*t)) t--; t++; - if (t_mm->real != (t - s) && (t_mm->frozen & MM_FIXED)) { + if (t_mm->real != (t - s) && (t_mm->flag & MM_FIXED)) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } t_mm->real = t-s; @@ -1126,7 +1181,7 @@ mm_lstrip_bang(str) e = t = s + t_mm->real; while (s < t && ISSPACE(*s)) s++; - if (t_mm->real != (t - s) && (t_mm->frozen & MM_FIXED)) { + if (t_mm->real != (t - s) && (t_mm->flag & MM_FIXED)) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } t_mm->real = t - s; @@ -1151,7 +1206,7 @@ mm_rstrip_bang(str) t--; while (s <= t && ISSPACE(*t)) t--; t++; - if (t_mm->real != (t - s) && (t_mm->frozen & MM_FIXED)) { + if (t_mm->real != (t - s) && (t_mm->flag & MM_FIXED)) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } t_mm->real = t - s; @@ -1316,7 +1371,7 @@ mm_bang_i(obj, flag, id, argc, argv) mm_mmap *t_mm; GetMmap(obj, t_mm, 0); - if ((flag & MM_CHANGE) && (t_mm->frozen & MM_FIXED)) { + if ((flag & MM_CHANGE) && (t_mm->flag & MM_FIXED)) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } str = mm_str(obj, flag); @@ -1583,13 +1638,13 @@ mm_mlock(obj) mm_mmap *t_mm; Data_Get_Struct(obj, mm_mmap, t_mm); - if (t_mm->lock) { + if (t_mm->flag & MM_LOCK) { return obj; } if (mlock(t_mm->addr, t_mm->len) == -1) { rb_raise(rb_eArgError, "mlock(%d)", errno); } - t_mm->lock = 1; + t_mm->flag |= MM_LOCK; return obj; } @@ -1600,17 +1655,16 @@ mm_munlock(obj) mm_mmap *t_mm; Data_Get_Struct(obj, mm_mmap, t_mm); - if (!t_mm->lock) { + if (!(t_mm->flag & MM_LOCK)) { return obj; } if (munlock(t_mm->addr, t_mm->len) == -1) { rb_raise(rb_eArgError, "munlock(%d)", errno); } - t_mm->lock = 0; + t_mm->flag &= ~MM_LOCK; return obj; } - void Init_mmap() { diff --git a/mmap.html b/mmap.html index 3eaf01a..0cf909e 100644 --- a/mmap.html +++ b/mmap.html @@ -128,60 +128,162 @@ the mapped file.

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[nth] -
self[start..last] -
self[start, length] -
self[nth] = val -
self[start..last] = val -
self[start, len] = val -
self <=> other -
<<(other) -
casecmp(other) >= 1.7.1 -
concat(other) -
capitalize! -
chop! -
chomp!([rs]) -
count(o1 [, o2, ...]) -
crypt(salt) -
delete!(str) -
downcase! -
each_byte {|char|...} -
each([rs]) {|line|...} -
each_line([rs]) {|line|...} -
empty? -
freeze -
frozen -
gsub!(pattern, replace) -
gsub!(pattern) {|str|...} -
include?(other) -
index(substr[, pos]) -
insert(index, str) >= 1.7.1 -
length -
reverse! -
rindex(substr[, pos]) -
scan(pattern) -
scan(pattern) {|str| ...} -
size -
slice -
slice! -
split([sep[, limit]]) -
squeeze!([str]) -
strip! -
sub!(pattern, replace) -
sub!(pattern) {|str| ...} -
sum([bits]) -
swapcase! -
tr!(search, replace) -
tr_s!(search, replace) -
upcase! +
self == other
+
+

comparison

+
self > other
+
+

comparison

+
self >= other
+
+

comparison

+
self < other
+
+

comparison

+
self <= other
+
+

comparison

+
self === other
+
+

used for case comparison

+
self << other
+
+

append other to self

+
self =~ other
+
+

return an index of the match

+
self[nth]
+
+

retrieve the nth character

+
self[start..last]
+
+

return a substring from start to last

+
self[start, length]
+
+

return a substring of lenght characters from start

+
self[nth] = val
+
+

change the nth character with val

+
self[start..last] = val
+
+

change substring from start to last with val

+
self[start, len] = val
+
+

replace length characters from start with val.

+
self <=> other
+
+

comparison : return -1, 0, 1

+
casecmp(other) >= 1.7.1 +
concat(other)
+
+

append the contents of other

+
capitalize!
+
+

change the first character to uppercase letter

+
chop!
+
+

chop off the last character

+
chomp!([rs])
+
+

chop off the line ending character, specified by rs

+
count(o1 [, o2, ...])
+
+

each parameter defines a set of character to count

+
crypt(salt)
+
+

crypt with salt

+
delete!(str)
+
+

delete every characters included in str

+
downcase!
+
+

change all uppercase character to lowercase character

+
each_byte {|char|...}
+
+

iterate on each byte

+
each([rs]) {|line|...} +
each_line([rs]) {|line|...}
+
+

iterate on each line

+
empty?
+
+

return true if the file is empty

+
freeze
+
+

freeze the current file

+
frozen
+
+

return true if the file is frozen

+
gsub!(pattern, replace)
+
+

global substitution

+
gsub!(pattern) {|str|...}
+
+

global substitution

+
include?(other)
+
+

return true if other is found

+
index(substr[, pos])
+
+

return the index of substr

+
insert(index, str) >= 1.7.1
+
+

insert str at index

+
length
+
+

return the size of the file

+
reverse!
+
+

reverse the content of the file

+
rindex(substr[, pos])
+
+

return the index of the last occurrence of substr

+
scan(pattern)
+
+

return an array of all occurence matched by pattern

+
scan(pattern) {|str| ...}
+
+

iterate through the file, matching the pattern

+
size
+
+

return the size of the file

+
slice
+
+

same than []

+
slice!
+
+

delete the specified portion of the file

+
split([sep[, limit]])
+
+

splits into a list of strings and return this array

+
squeeze!([str])
+
+

squeezes sequences of the same characters which is included in str

+
strip!
+
+

removes leading and trailing whitespace

+
sub!(pattern, replace)
+
+

substitution

+
sub!(pattern) {|str| ...}
+
+

substitution

+
sum([bits])
+
+

return a checksum

+
swapcase!
+
+

replaces all lowercase characters to uppercase characters, and vice-versa

+
tr!(search, replace)
+
+

translate the character from search to replace

+
tr_s!(search, replace)
+
+

translate the character from search to replace, then +squeeze sequence of the same characters

+
upcase!
+
+

replaces all lowercase characters to downcase characters

diff --git a/mmap.rd b/mmap.rd index 81fd8d8..7cf978e 100644 --- a/mmap.rd +++ b/mmap.rd @@ -100,111 +100,160 @@ Object --- self == other + comparison --- self > other + comparison --- self >= other + comparison --- self < other + comparison --- self <= other + comparison --- self === other + used for ((|case|)) comparison --- self << other + append ((|other|)) to ((|self|)) ---- self =~ other +--- self =~ other + return an index of the match --- self[nth] + retrieve the ((|nth|)) character --- self[start..last] + return a substring from ((|start|)) to ((|last|)) ---- self[start, length] +--- self[start, length] + return a substring of ((|lenght|)) characters from ((|start|)) --- self[nth] = val + change the ((|nth|)) character with ((|val|)) --- self[start..last] = val + change substring from ((|start|)) to ((|last|)) with ((|val|)) --- self[start, len] = val + replace ((|length|)) characters from ((|start|)) with ((|val|)). --- self <=> other - ---- <<(other) + comparison : return -1, 0, 1 --- casecmp(other) >= 1.7.1 --- concat(other) + append the contents of ((|other|)) ---- capitalize! +--- capitalize! + change the first character to uppercase letter --- chop! + chop off the last character --- chomp!([rs]) + chop off the line ending character, specified by ((|rs|)) --- count(o1 [, o2, ...]) + each parameter defines a set of character to count ---- crypt(salt) +--- crypt(salt) + crypt with ((|salt|)) --- delete!(str) + delete every characters included in ((|str|)) --- downcase! + change all uppercase character to lowercase character --- each_byte {|char|...} + iterate on each byte --- each([rs]) {|line|...} - --- each_line([rs]) {|line|...} + iterate on each line --- empty? + return ((|true|)) if the file is empty ---- freeze +--- freeze + freeze the current file --- frozen + return ((|true|)) if the file is frozen --- gsub!(pattern, replace) + global substitution --- gsub!(pattern) {|str|...} + global substitution --- include?(other) + return ((|true|)) if ((|other|)) is found ---- index(substr[, pos]) +--- index(substr[, pos]) + return the index of ((|substr|)) --- insert(index, str) >= 1.7.1 + insert ((|str|)) at ((|index|)) --- length + return the size of the file ---- reverse! +--- reverse! + reverse the content of the file --- rindex(substr[, pos]) + return the index of the last occurrence of ((|substr|)) ---- scan(pattern) +--- scan(pattern) + return an array of all occurence matched by ((|pattern|)) --- scan(pattern) {|str| ...} + iterate through the file, matching the ((|pattern|)) --- size + return the size of the file --- slice + same than ((|[]|)) --- slice! + delete the specified portion of the file --- split([sep[, limit]]) + splits into a list of strings and return this array --- squeeze!([str]) + squeezes sequences of the same characters which is included in ((|str|)) --- strip! + removes leading and trailing whitespace ---- sub!(pattern, replace) +--- sub!(pattern, replace) + substitution --- sub!(pattern) {|str| ...} + substitution --- sum([bits]) + return a checksum --- swapcase! + replaces all lowercase characters to uppercase characters, and vice-versa ---- tr!(search, replace) +--- tr!(search, replace) + translate the character from ((|search|)) to ((|replace|)) --- tr_s!(search, replace) + translate the character from ((|search|)) to ((|replace|)), then + squeeze sequence of the same characters --- upcase! + replaces all lowercase characters to downcase characters =end diff --git a/tests/mmapt.rb b/tests/mmapt.rb index c6a1fdc..b94358c 100644 --- a/tests/mmapt.rb +++ b/tests/mmapt.rb @@ -140,9 +140,13 @@ class TestMmap < Inh::TestCase assert_equal($mmap.scan(/include/), $str.scan(/include/), "") assert_equal($mmap.index("rb_raise"), $str.index("rb_raise"), "") assert_equal($mmap.rindex("rb_raise"), $str.rindex("rb_raise"), "") + assert_equal($mmap.index(/rb_raise/), $str.index(/rb_raise/), "") + assert_equal($mmap.rindex(/rb_raise/), $str.rindex(/rb_raise/), "") ('a' .. 'z').each do |i| assert_equal($mmap.index(i), $str.index(i), "") assert_equal($mmap.rindex(i), $str.rindex(i), "") + assert_equal($mmap.index(i), $str.index(/#{i}/), "") + assert_equal($mmap.rindex(i), $str.rindex(/#{i}/), "") end $mmap.sub!(/GetMmap/, 'XXXX'); $str.sub!(/GetMmap/, 'XXXX') assert_equal($mmap.to_str, $str, "") -- cgit v1.1-2-g2b99