#
# Text blocks owptext.b
implement Tblks;
include "sys.m";
sys: Sys;
fprint, fildes: import sys;
include "string.m";
str: String;
prefix: import str;
include "error.m";
err: Error;
checkload, stderr, panic, kill, error: import err;
include "tblks.m";
debug := 0;
init(sysm: Sys, strm: String, e: Error, dbg: int)
{
sys = sysm;
str = strm;
err = e;
debug = dbg;
}
Str.findr(s: self ref Str, pos: int, c: int, lim: int): int
{
for (i := pos; i >= 0 && i < len s.s; i--)
if (s.s[i] == c || --lim == 0)
return i;
return -1;
}
Str.find(s: self ref Str, pos: int, c:int, lim: int): int
{
for(; pos < len s.s; pos++){
if (s.s[pos] == c || --lim == 0)
return pos;
}
return -1;
}
fixpos(pos: int, n: int): int
{
if (pos < 0)
return 0;
else if (pos > n)
return n;
else
return pos;
}
fixposins(pos, inspos, n: int): int
{
if (inspos < pos)
pos += n;
return pos;
}
fixposdel(pos, delpos, n: int): int
{
if (delpos < pos){
if (delpos + n > pos)
n = pos - delpos;
pos -= n;
}
return pos;
}
Blks.blen(blks: self ref Blks): int
{
l := 0;
for (i := 0; i < len blks.b && blks.b[i] != nil; i++)
l += len blks.b[i].s;
return l;
}
Blks.new(s: string): ref Blks
{
b0 := ref Str(s);
return ref Blks(array[] of { b0 });
}
Blks.pack(blks: self ref Blks): ref Str
{
for(i := 1; i < len blks.b && blks.b[i] != nil; i++){
blks.b[0].s += blks.b[i].s;
blks.b[i] = nil;
}
return blks.b[0];
}
Blks.seek(blks: self ref Blks, off: int): (int, int)
{
for(i := 0; i < len blks.b && blks.b[i] != nil; i++){
nr := len blks.b[i].s;
if (nr == 0)
continue;
if (off <= nr)
break;
off -= nr;
}
return (i, off);
}
Blks.getc(blks: self ref Blks, pos: int): int
{
for(i:= 0; i < len blks.b && blks.b[i] != nil; i++){
if (pos < len blks.b[i].s)
return blks.b[i].s[pos];
pos -= len blks.b[i].s;
}
return -1;
}
Blks.gets(blks: self ref Blks, pos: int, nr: int): string
{
s := blks.pack();
if (pos > len s.s)
pos = len s.s;
if (pos + nr > len s.s)
nr = len s.s - pos;
if (nr == 0)
return "";
else
return s.s[pos:pos+nr];
}
Blks.ins(blks: self ref Blks, t: string, pos: int)
{
if (debug)
fprint(stderr, "Blks.ins: '%s' %d\n", dtxt(t), pos);
s: ref Str;
nr := 0;
for(i := 0; i < len blks.b && blks.b[i] != nil; i++){
s = blks.b[i];
nr = len s.s;
if (pos <= nr)
break;
if (nr == 0)
continue;
pos -= nr;
}
if (pos == nr && len t == 1)
s.s[pos] = t[0];
else {
ns := ref Str(t);
ns2 := ref Str(blks.b[i].s[pos:]);
blks.b[i].s = blks.b[i].s[0:pos];
nb := array[len blks.b + 2] of ref Str;
nb[0:] = blks.b[0:i];
nb[i] = blks.b[i];
nb[i+1] = ns;
nb[i+2] = ns2;
if (i + 1 < len blks.b)
nb[i+3:] = blks.b[i+1:];
blks.b = nb;
}
}
Blks.del(blks: self ref Blks, n: int, pos: int): string
{
if (n <= 0)
return "";
s: ref Str;
nr: int;
for(i := 0; i < len blks.b && blks.b[i] != nil; i++){
s = blks.b[i];
nr = len s.s;
if (nr == 0)
continue;
if (pos <= nr)
break;
pos -= nr;
}
t := "";
while(i < len blks.b && blks.b[i] != nil && n > 0) {
s = blks.b[i];
nr = len s.s;
edel := pos + n;
if (edel > nr)
edel = nr;
ndel := edel - pos;
if (ndel > 0)
t += s.s[pos:edel];
if (nr - edel > 0)
s.s = s.s[0:pos] + s.s[edel:];
else
s.s = s.s[0:pos];
n -= ndel;
pos = 0;
i++;
}
return t;
}
strchr(s : string, c : int) : int
{
for (i := 0; i < len s; i++)
if (s[i] == c)
return i;
return -1;
}
strstr(s1, s2: string): int
{
for (i := 0; i < len s1; i++)
if (prefix(s2, s1[i:]))
return i;
return -1;
}
dtxt(s: string): string
{
if (len s> 35)
s = s[0:15] + " ... " + s[len s - 15:];
ns := "";
for (i := 0; i < len s; i++)
if (s[i] == '\n')
ns += "\\n";
else
ns[len ns] = s[i];
return ns;
}
Blks.dump(blks: self ref Blks)
{
if (blks == nil || blks.b == nil)
return;
fprint(stderr, "%d blks\n", len blks.b);
for (i := 0; i < len blks.b && blks.b[i] != nil; i++)
fprint(stderr, "\tblk[%d]: %d '%s'\n", i, len blks.b[i].s, dtxt(blks.b[i].s));
}
|