Switch to simple buffers. - sam - An updated version of the sam text editor. | |
git clone git://vernunftzentrum.de/sam.git | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit b74192453a1bd53ded5dca89283ff6f27be028d2 | |
parent c278f2b4d6f063d41632760c4e59addd653af041 | |
Author: Rob King <[email protected]> | |
Date: Mon, 3 Oct 2016 22:53:59 -0500 | |
Switch to simple buffers. | |
Diffstat: | |
sam/Makefile | 2 +- | |
sam/buffer.c | 267 ++++++++++++++----------------- | |
sam/disc.c | 335 ------------------------------- | |
sam/file.c | 18 +++++------------- | |
sam/sam.h | 62 ++----------------------------- | |
5 files changed, 133 insertions(+), 551 deletions(-) | |
--- | |
diff --git a/sam/Makefile b/sam/Makefile | |
@@ -33,7 +33,7 @@ CFLAGS=$(STANDARDS) $(INCS) $(INCLUDES) -DUSE64BITS=$(USE64BI… | |
LIB=../libframe/libframe.a ../libXg/libXg.a | |
CC?=c99 | |
-OBJ=sam.o address.o buffer.o cmd.o disc.o error.o file.o io.o \ | |
+OBJ=sam.o address.o buffer.o cmd.o error.o file.o io.o \ | |
list.o mesg.o moveto.o multi.o rasp.o regexp.o shell.o \ | |
string.o sys.o unix.o xec.o | |
diff --git a/sam/buffer.c b/sam/buffer.c | |
@@ -1,176 +1,155 @@ | |
-/* Copyright (c) 1998 Lucent Technologies - All rights reserved. */ | |
+/* Copyright 2016 Rob King -- See LICENSE for details */ | |
+ | |
#include "sam.h" | |
-int incache(Buffer*, Posn, Posn); | |
+#define BUFFER_MIN 65535 | |
+#define GAPSIZE(b) ((b)->ge - (b)->gs) | |
-Buffer * | |
-Bopen(Discdesc *dd) | |
+typedef size_t pos_t; | |
+typedef struct Gapbuffer Gapbuffer; | |
+struct Gapbuffer{ | |
+ size_t size; | |
+ pos_t gs; | |
+ pos_t ge; | |
+ wchar_t *buf; | |
+}; | |
+ | |
+static void | |
+movegap(Gapbuffer *b, pos_t p) | |
{ | |
- Buffer *b; | |
+ if (p == b->gs) | |
+ return; | |
+ else if (p < b->gs){ | |
+ size_t d = b->gs - p; | |
+ b->gs -= d; | |
+ b->ge -= d; | |
+ wmemmove(b->buf + b->ge, b->buf + b->gs, d); | |
+ } else{ | |
+ size_t d = p - b->gs; | |
+ b->gs += d; | |
+ b->ge += d; | |
+ wmemmove(b->buf + b->gs - d, b->buf + b->ge - d, d); | |
+ } | |
+} | |
- b = emalloc(sizeof(Buffer)); | |
- b->disc = Dopen(dd); | |
- Strinit(&b->cache); | |
- return b; | |
+static void | |
+ensuregap(Gapbuffer *b, size_t l) | |
+{ | |
+ size_t ns = b->size + l + BUFFER_MIN; | |
+ size_t es = b->size - b->ge; | |
+ | |
+ if (GAPSIZE(b) >= l) | |
+ return; | |
+ | |
+ b->buf = realloc(b->buf, ns * RUNESIZE); | |
+ if (!b->buf) | |
+ panic("out of memory"); | |
+ | |
+ wmemmove(b->buf + (ns - es), b->buf + b->ge, es); | |
+ b->ge = ns - es; | |
+ b->size = ns; | |
} | |
-void | |
-Bterm(Buffer *b) | |
+static void | |
+deletebuffer(Gapbuffer *b, pos_t p, size_t l) | |
{ | |
- Dclose(b->disc); | |
- Strclose(&b->cache); | |
- free(b); | |
+ movegap(b, p); | |
+ b->ge += l; | |
} | |
-int | |
-Bread(Buffer *b, wchar_t *addr, int n, Posn p0) | |
+static size_t | |
+readbuffer(Gapbuffer *b, pos_t p, size_t l, wchar_t *c) | |
{ | |
- int m; | |
- | |
- if(b->c2>b->disc->nrunes || b->c1>b->disc->nrunes) | |
- panic("bread cache"); | |
- if(p0 < 0) | |
- panic("Bread p0<0"); | |
- if(p0+n > b->nrunes){ | |
- n = b->nrunes-p0; | |
- if(n < 0) | |
- panic("Bread<0"); | |
- } | |
- if(!incache(b, p0, p0+n)){ | |
- Bflush(b); | |
- if(n>=BLOCKSIZE/2) | |
- return Dread(b->disc, addr, n, p0); | |
- else{ | |
- Posn minp; | |
- if(b->nrunes-p0>BLOCKSIZE/2) | |
- m = BLOCKSIZE/2; | |
- else | |
- m = b->nrunes-p0; | |
- if(m<n) | |
- m = n; | |
- minp = p0-BLOCKSIZE/2; | |
- if(minp<0) | |
- minp = 0; | |
- m += p0-minp; | |
- Strinsure(&b->cache, m); | |
- if(Dread(b->disc, b->cache.s, m, minp)!=m) | |
- panic("Bread"); | |
- b->cache.n = m; | |
- b->c1 = minp; | |
- b->c2 = minp+m; | |
- b->dirty = false; | |
- } | |
+ size_t r = 0; | |
+ | |
+ if (p < b->gs){ | |
+ size_t d = b->gs - p; | |
+ size_t t = l > d ? d : l; | |
+ | |
+ wmemcpy(c, b->buf + p, t); | |
+ c += t; | |
+ l -= t; | |
+ r += t; | |
+ | |
+ wmemcpy(c, b->buf + b->ge, l); | |
+ r += l; | |
+ } else{ | |
+ p += GAPSIZE(b); | |
+ | |
+ wmemcpy(c, b->buf + p, l); | |
+ r = l; | |
} | |
- memmove(addr, &b->cache.s[p0-b->c1], n*RUNESIZE); | |
- return n; | |
+ | |
+ return r; | |
} | |
-void | |
-Binsert(Buffer *b, String *s, Posn p0) | |
+static void | |
+insertbuffer(Gapbuffer *b, pos_t p, const wchar_t *s, size_t l) | |
{ | |
- if(b->c2>b->disc->nrunes || b->c1>b->disc->nrunes) | |
- panic("binsert cache"); | |
- if(p0<0) | |
- panic("Binsert p0<0"); | |
- if(s->n == 0) | |
- return; | |
- if(incache(b, p0, p0) && b->cache.n+s->n<=STRSIZE){ | |
- Strinsert(&b->cache, s, p0-b->c1); | |
- b->dirty = true; | |
- if(b->cache.n > BLOCKSIZE*2){ | |
- b->nrunes += s->n; | |
- Bflush(b); | |
- /* try to leave some cache around p0 */ | |
- if(p0 >= b->c1+BLOCKSIZE){ | |
- /* first BLOCKSIZE can go */ | |
- Strdelete(&b->cache, 0, BLOCKSIZE); | |
- b->c1 += BLOCKSIZE; | |
- }else if(p0 <= b->c2-BLOCKSIZE){ | |
- /* last BLOCKSIZE can go */ | |
- b->cache.n -= BLOCKSIZE; | |
- b->c2 -= BLOCKSIZE; | |
- }else{ | |
- /* too hard; negate the cache and pick up next time */ | |
- Strzero(&b->cache); | |
- b->c1 = b->c2 = 0; | |
- } | |
- return; | |
- } | |
- }else{ | |
- Bflush(b); | |
- if(s->n >= BLOCKSIZE/2){ | |
- b->cache.n = 0; | |
- b->c1 = b->c2 = 0; | |
- Dinsert(b->disc, s->s, s->n, p0); | |
- }else{ | |
- int m; | |
- Posn minp; | |
- if(b->nrunes-p0 > BLOCKSIZE/2) | |
- m = BLOCKSIZE/2; | |
- else | |
- m = b->nrunes-p0; | |
- minp = p0-BLOCKSIZE/2; | |
- if(minp < 0) | |
- minp = 0; | |
- m += p0-minp; | |
- Strinsure(&b->cache, m); | |
- if(Dread(b->disc, b->cache.s, m, minp)!=m) | |
- panic("Bread"); | |
- b->cache.n = m; | |
- b->c1 = minp; | |
- b->c2 = minp+m; | |
- Strinsert(&b->cache, s, p0-b->c1); | |
- b->dirty = true; | |
- } | |
- } | |
- b->nrunes += s->n; | |
+ ensuregap(b, l); | |
+ movegap(b, p); | |
+ wmemcpy(b->buf + b->gs, s, l); | |
+ b->gs += l; | |
} | |
-void | |
-Bdelete(Buffer *b, Posn p1, Posn p2) | |
+Buffer * | |
+Bopen(void) | |
{ | |
- if(p1<0 || p2<0) | |
- panic("Bdelete p<0"); | |
- if(b->c2>b->disc->nrunes || b->c1>b->disc->nrunes) | |
- panic("bdelete cache"); | |
- if(p1 == p2) | |
- return; | |
- if(incache(b, p1, p2)){ | |
- Strdelete(&b->cache, p1-b->c1, p2-b->c1); | |
- b->dirty = true; | |
- }else{ | |
- Bflush(b); | |
- Ddelete(b->disc, p1, p2); | |
- b->cache.n = 0; | |
- b->c1 = b->c2 = 0; | |
- } | |
- b->nrunes -= p2-p1; | |
+ Buffer *b = calloc(1, sizeof(Buffer)); | |
+ if (!b) | |
+ panic("out of memory"); | |
+ | |
+ b->gb = calloc(1, sizeof(Gapbuffer)); | |
+ if (!b->gb) | |
+ panic("out of memory"); | |
+ | |
+ b->gb->buf = calloc(1, BUFFER_MIN * RUNESIZE); | |
+ if (!b->gb->buf) | |
+ panic("out of memory"); | |
+ | |
+ b->gb->size = BUFFER_MIN; | |
+ b->gb->gs = 0; | |
+ b->gb->ge = BUFFER_MIN; | |
+ | |
+ return b; | |
} | |
void | |
-Bflush(Buffer *b) | |
+Bterm(Buffer *b) | |
{ | |
- if(b->dirty){ | |
- Dreplace(b->disc, b->c1, b->c2, b->cache.s, b->cache.n); | |
- b->c2 = b->c1+b->cache.n; | |
- b->dirty = false; | |
- if(b->nrunes != b->disc->nrunes) | |
- panic("Bflush"); | |
+ if (b){ | |
+ free(b->gb->buf); | |
+ free(b->gb); | |
+ free(b); | |
} | |
} | |
+int | |
+Bread(Buffer *b, wchar_t *c, int l, Posn p) | |
+{ | |
+ if (p + l > b->nrunes) | |
+ l = b->nrunes - p; | |
+ | |
+ if (l == 0) | |
+ return 0; | |
+ | |
+ size_t r = readbuffer(b->gb, p, l, c); | |
+ return (int)r; | |
+} | |
+ | |
void | |
-Bclean(Buffer *b) | |
+Binsert(Buffer *b, String *s, Posn p) | |
{ | |
- if(b->dirty){ | |
- Bflush(b); | |
- b->c1 = b->c2 = 0; | |
- Strzero(&b->cache); | |
+ if (s->n > 0){ | |
+ insertbuffer(b->gb, (size_t)p, s->s, s->n); | |
+ b->nrunes += s->n; | |
} | |
} | |
-int | |
-incache(Buffer *b, Posn p1, Posn p2) | |
+void | |
+Bdelete(Buffer *b, Posn p1, Posn p2) | |
{ | |
- return b->c1<=p1 && p2<=b->c1+b->cache.n; | |
+ size_t l = p2 - p1; | |
+ deletebuffer(b->gb, p1, l); | |
+ b->nrunes -= l; | |
} | |
diff --git a/sam/disc.c b/sam/disc.c | |
@@ -1,335 +0,0 @@ | |
-/* Copyright (c) 1998 Lucent Technologies - All rights reserved. */ | |
-#include "sam.h" | |
- | |
-#define BLOCKFILL (BLOCKSIZE/2) | |
- | |
-static Discdesc desc[NBUFFILES]; | |
- | |
-void bkalloc(Disc*, int); | |
-void bkfree(Disc*, int); | |
-void bkwrite(Disc*, wchar_t*, int, int, int); | |
-void bkread(Disc*, wchar_t*, int, int, int); | |
- | |
- | |
-Discdesc * | |
-Dstart(void) | |
-{ | |
- int i, fd; | |
- Discdesc *dd; | |
- | |
- for(i=0, dd=desc; dd->fd; i++, dd++) | |
- if(i == NBUFFILES-1) | |
- panic("too many buffer files"); | |
- fd = newtmp(); | |
- if(fd < 0) | |
- panic("can't create buffer file"); | |
- dd->fd = fd; | |
- return dd; | |
-} | |
- | |
-Disc * | |
-Dopen(Discdesc *dd) | |
-{ | |
- Disc *d; | |
- | |
- d = emalloc(sizeof(Disc)); | |
- d->desc = dd; | |
- return d; | |
-} | |
- | |
-void | |
-Dclose(Disc *d) | |
-{ | |
- int i; | |
- | |
- for(i=d->block.nused; --i>=0; ) /* backwards because bkfree() stacks */ | |
- bkfree(d, i); | |
- free(d->block.listptr); | |
- free(d); | |
-} | |
- | |
-int | |
-Dread(Disc *d, wchar_t *addr, int n, Posn p1) | |
-{ | |
- int i, nb, nr; | |
- Posn p = 0, p2 = p1+n; | |
- | |
- for(i=0; i<d->block.nused; i++){ | |
- if((p+=d->block.blkptr[i].nrunes) > p1){ | |
- p -= d->block.blkptr[i].nrunes; | |
- goto out; | |
- } | |
- } | |
- if(p == p1) | |
- return 0; /* eof */ | |
- return -1; /* past eof */ | |
- | |
- out: | |
- n = 0; | |
- if(p != p1){ /* trailing partial block */ | |
- nb = d->block.blkptr[i].nrunes; | |
- if(p2 > p+nb) | |
- nr = nb-(p1-p); | |
- else | |
- nr = p2-p1; | |
- bkread(d, addr, nr, i, p1-p); | |
- /* advance to next block */ | |
- p += nb; | |
- addr += nr; | |
- n += nr; | |
- i++; | |
- } | |
- /* whole blocks */ | |
- while(p<p2 && (nb = d->block.blkptr[i].nrunes)<=p2-p){ | |
- if(i >= d->block.nused) | |
- return n; /* eof */ | |
- bkread(d, addr, nb, i, 0); | |
- p += nb; | |
- addr += nb; | |
- n += nb; | |
- i++; | |
- } | |
- if(p < p2){ /* any initial partial block left? */ | |
- nr = p2-p; | |
- nb = d->block.blkptr[i].nrunes; | |
- if(nr>nb) | |
- nr = nb; /* eof */ | |
- /* just read in the part that survives */ | |
- bkread(d, addr, nr, i, 0); | |
- n += nr; | |
- } | |
- return n; | |
-} | |
- | |
-void | |
-Dinsert(Disc *d, wchar_t *addr, int n, Posn p0) /* if addr null, just make spa… | |
-{ | |
- int i, nb, ni; | |
- Posn p = 0; | |
- wchar_t hold[BLOCKSIZE]; | |
- int nhold; | |
- | |
- for(i=0; i<d->block.nused; i++){ | |
- if((p+=d->block.blkptr[i].nrunes) >= p0){ | |
- p -= d->block.blkptr[i].nrunes; | |
- goto out; | |
- } | |
- } | |
- if(p != p0) | |
- panic("Dinsert"); /* beyond eof */ | |
- | |
- out: | |
- d->nrunes += n; | |
- nhold = 0; | |
- if(i<d->block.nused && (nb=d->block.blkptr[i].nrunes)>p0-p){ | |
- nhold = nb-(p0-p); | |
- bkread(d, hold, nhold, i, p0-p); | |
- d->block.blkptr[i].nrunes -= nhold; /* no write necessary */ | |
- } | |
- /* insertion point is now at end of block i (which may not exist) */ | |
- while(n > 0){ | |
- if(i < d->block.nused | |
- && (nb=d->block.blkptr[i].nrunes) < BLOCKFILL){ | |
- /* fill this block */ | |
- if(nb+n > BLOCKSIZE) | |
- ni = BLOCKFILL-nb; | |
- else | |
- ni = n; | |
- if(addr) | |
- bkwrite(d, addr, ni, i, nb); | |
- nb += ni; | |
- }else{ /* make new block */ | |
- if(i < d->block.nused) | |
- i++; /* put after this block, if it exists */ | |
- bkalloc(d, i); | |
- if(n > BLOCKSIZE) | |
- ni = BLOCKFILL; | |
- else | |
- ni = n; | |
- if(addr) | |
- bkwrite(d, addr, ni, i, 0); | |
- nb = ni; | |
- } | |
- d->block.blkptr[i].nrunes = nb; | |
- if(addr) | |
- addr += ni; | |
- n -= ni; | |
- } | |
- if(nhold){ | |
- if(i < d->block.nused | |
- && (nb=d->block.blkptr[i].nrunes)+nhold < BLOCKSIZE){ | |
- /* fill this block */ | |
- bkwrite(d, hold, nhold, i, nb); | |
- nb += nhold; | |
- }else{ /* make new block */ | |
- if(i < d->block.nused) | |
- i++; /* put after this block, if it exists */ | |
- bkalloc(d, i); | |
- bkwrite(d, hold, nhold, i, 0); | |
- nb = nhold; | |
- } | |
- d->block.blkptr[i].nrunes = nb; | |
- } | |
-} | |
- | |
-void | |
-Ddelete(Disc *d, Posn p1, Posn p2) | |
-{ | |
- int i, nb, nd; | |
- Posn p = 0; | |
- wchar_t buf[BLOCKSIZE]; | |
- | |
- for(i = 0; i<d->block.nused; i++){ | |
- if((p+=d->block.blkptr[i].nrunes) > p1){ | |
- p -= d->block.blkptr[i].nrunes; | |
- goto out; | |
- } | |
- } | |
- if(p1!=d->nrunes || p2!=p1) | |
- panic("Ddelete"); | |
- return; /* beyond eof */ | |
- | |
- out: | |
- d->nrunes -= p2-p1; | |
- if(p != p1){ /* throw away partial block */ | |
- nb = d->block.blkptr[i].nrunes; | |
- bkread(d, buf, nb, i, 0); | |
- if(p2 >= p+nb) | |
- nd = nb-(p1-p); | |
- else{ | |
- nd = p2-p1; | |
- memmove(buf+(p1-p), buf+(p1-p)+nd, RUNESIZE*(nb-((p1-p)+nd))); | |
- } | |
- nb -= nd; | |
- bkwrite(d, buf, nb, i, 0); | |
- d->block.blkptr[i].nrunes = nb; | |
- p2 -= nd; | |
- /* advance to next block */ | |
- p += nb; | |
- i++; | |
- } | |
- /* throw away whole blocks */ | |
- while(p<p2 && (nb = d->block.blkptr[i].nrunes)<=p2-p){ | |
- if(i >= d->block.nused) | |
- panic("Ddelete 2"); | |
- bkfree(d, i); | |
- p2 -= nb; | |
- } | |
- if(p >= p2) /* any initial partial block left to delete? */ | |
- return; /* no */ | |
- nd = p2-p; | |
- nb = d->block.blkptr[i].nrunes; | |
- /* just read in the part that survives */ | |
- bkread(d, buf, nb-=nd, i, nd); | |
- /* a little block merging */ | |
- if(nb<BLOCKSIZE/2 && i>0 && (nd = d->block.blkptr[i-1].nrunes)<BLOCKSIZE/2… | |
- memmove(buf+nd, buf, RUNESIZE*nb); | |
- bkread(d, buf, nd, --i, 0); | |
- bkfree(d, i); | |
- nb += nd; | |
- } | |
- bkwrite(d, buf, nb, i, 0); | |
- d->block.blkptr[i].nrunes = nb; | |
-} | |
- | |
-void | |
-Dreplace(Disc *d, Posn p1, Posn p2, wchar_t *addr, int n) | |
-{ | |
- int i, nb, nr; | |
- Posn p = 0; | |
- wchar_t buf[BLOCKSIZE]; | |
- | |
- if(p2-p1 > n) | |
- Ddelete(d, p1+n, p2); | |
- else if(p2-p1 < n) | |
- Dinsert(d, 0, n-(p2-p1), p2); | |
- if(n == 0) | |
- return; | |
- p2 = p1+n; | |
- /* they're now conformal; replace in place */ | |
- for(i=0; i<d->block.nused; i++){ | |
- if((p+=d->block.blkptr[i].nrunes) > p1){ | |
- p -= d->block.blkptr[i].nrunes; | |
- goto out; | |
- } | |
- } | |
- panic("Dreplace"); | |
- | |
- out: | |
- if(p != p1){ /* trailing partial block */ | |
- nb = d->block.blkptr[i].nrunes; | |
- bkread(d, buf, nb, i, 0); | |
- if(p2 > p+nb) | |
- nr = nb-(p1-p); | |
- else | |
- nr = p2-p1; | |
- memmove(buf+p1-p, addr, RUNESIZE*nr); | |
- bkwrite(d, buf, nb, i, 0); | |
- /* advance to next block */ | |
- p += nb; | |
- addr += nr; | |
- i++; | |
- } | |
- /* whole blocks */ | |
- while(p<p2 && (nb = d->block.blkptr[i].nrunes)<=p2-p){ | |
- if(i >= d->block.nused) | |
- panic("Dreplace 2"); | |
- bkwrite(d, addr, nb, i, 0); | |
- p += nb; | |
- addr += nb; | |
- i++; | |
- } | |
- if(p < p2){ /* any initial partial block left? */ | |
- nr = p2-p; | |
- nb = d->block.blkptr[i].nrunes; | |
- /* just read in the part that survives */ | |
- bkread(d, buf+nr, nb-nr, i, nr); | |
- memmove(buf, addr, RUNESIZE*nr); | |
- bkwrite(d, buf, nb, i, 0); | |
- } | |
-} | |
- | |
-void | |
-bkread(Disc *d, wchar_t *loc, int n, int bk, int off) | |
-{ | |
- Seek(d->desc->fd, RUNESIZE*(BLOCKSIZE*d->block.blkptr[bk].bnum+off), 0); | |
- Read(d->desc->fd, loc, n*RUNESIZE); | |
-} | |
- | |
-void | |
-bkwrite(Disc *d, wchar_t *loc, int n, int bk, int off) | |
-{ | |
- Seek(d->desc->fd, RUNESIZE*(BLOCKSIZE*d->block.blkptr[bk].bnum+off), 0); | |
- Write(d->desc->fd, loc, n*RUNESIZE); | |
- /* | |
- * sleazy hack to avoid silly SGI kernel bug | |
- * fill partial block with garbage | |
- */ | |
- if (off+n >= d->block.blkptr[bk].nrunes && off+n < BLOCKSIZE) | |
- Write(d->desc->fd, genbuf, (BLOCKSIZE-(off+n))*RUNESIZE); | |
-} | |
- | |
-void | |
-bkalloc(Disc *d, int n) | |
-{ | |
- Discdesc *dd = d->desc; | |
- uint64_t bnum; | |
- | |
- if(dd->free.nused) | |
- bnum = dd->free.longptr[--dd->free.nused]; | |
- else | |
- bnum = dd->nbk++; | |
- if(bnum >= 1<<(8*(sizeof(((Block*)0)->bnum)))) | |
- error(Etmpovfl); | |
- inslist(&d->block, n, 0L); | |
- d->block.blkptr[n].bnum = bnum; | |
-} | |
- | |
-void | |
-bkfree(Disc *d, int n) | |
-{ | |
- Discdesc *dd = d->desc; | |
- | |
- inslist(&dd->free, dd->free.nused, d->block.blkptr[n].bnum); | |
- dellist(&d->block, n); | |
-} | |
diff --git a/sam/file.c b/sam/file.c | |
@@ -3,8 +3,6 @@ | |
/* | |
* Files are splayed out a factor of NDISC to reduce indirect block access | |
*/ | |
-Discdesc *files[NDISC]; | |
-Discdesc *transcripts[NDISC]; | |
Buffer *undobuf; | |
static String *ftempstr(wchar_t*, int); | |
int fcount; | |
@@ -24,9 +22,9 @@ enum{ | |
void | |
Fstart(void) | |
{ | |
- undobuf = Bopen(Dstart()); | |
- snarfbuf = Bopen(Dstart()); | |
- plan9buf = Bopen(Dstart()); | |
+ undobuf = Bopen(); | |
+ snarfbuf = Bopen(); | |
+ plan9buf = Bopen(); | |
} | |
void | |
@@ -56,12 +54,8 @@ Fopen(void) | |
File *f; | |
f = emalloc(sizeof(File)); | |
- if(files[fcount] == 0){ | |
- files[fcount] = Dstart(); | |
- transcripts[fcount] = Dstart(); | |
- } | |
- f->buf = Bopen(files[fcount]); | |
- f->transcript = Bopen(transcripts[fcount]); | |
+ f->buf = Bopen(); | |
+ f->transcript = Bopen(); | |
if(++fcount == NDISC) | |
fcount = 0; | |
f->nrunes = 0; | |
@@ -232,8 +226,6 @@ Fupdate(File *f, int mktrans, int toterm) | |
if(f->state == Readerr) | |
return false; | |
- if(lastfile && f!=lastfile) | |
- Bclean(lastfile->transcript); /* save memory when multifile */ | |
lastfile = f; | |
Fflush(f); | |
if(f->marked) | |
diff --git a/sam/sam.h b/sam/sam.h | |
@@ -23,8 +23,6 @@ typedef uint16_t Mod; /* modification number */ | |
typedef struct Address Address; | |
typedef struct Block Block; | |
typedef struct Buffer Buffer; | |
-typedef struct Disc Disc; | |
-typedef struct Discdesc Discdesc; | |
typedef struct File File; | |
typedef struct List List; | |
typedef struct Mark Mark; | |
@@ -79,47 +77,6 @@ struct List /* code depends on a int64_t being able to hold … | |
#define filepptr g.filep | |
#define listval g.listv | |
-/* | |
- * Block must fit in a int64_t because the list routines manage arrays of | |
- * blocks. Two problems: some machines (e.g. Cray) can't pull this off | |
- * -- on them, use bitfields -- and the uint16_t bnum limits temp file sizes | |
- * to about 200 megabytes. Advantages: small, simple code and small | |
- * memory overhead. If you really want to edit huge files, making BLOCKSIZE | |
- * bigger is the easiest way. | |
-* | |
-* The necessary conditions are even stronger: | |
-* sizeof(struct Block)==sizeof(int64_t) | |
-* && the first 32 bits must hold bnum and nrunes. | |
-* When sizeof(uint16_t)+sizeof(int16_t) < sizeof(int64_t), | |
-* add padding at the beginning on a little endian and at | |
-* the end on a big endian, as shown below for the DEC Alpha. | |
- */ | |
-struct Block | |
-{ | |
-#if USE64BITS == 1 | |
- char pad[sizeof(int64_t)-sizeof(uint16_t)-sizeof(int16_t)]; | |
-#endif | |
- uint16_t bnum; /* absolute number on disk */ | |
- int16_t nrunes; /* runes stored in this block */ | |
-#if USE64BITS == 2 | |
- char pad[sizeof(int64_t)-sizeof(uint16_t)-sizeof(int16_t)]; | |
-#endif | |
-}; | |
- | |
-struct Discdesc | |
-{ | |
- int fd; /* plan 9 file descriptor of temp file */ | |
- uint64_t nbk; /* high water mark */ | |
- List free; /* array of free block indices */ | |
-}; | |
- | |
-struct Disc | |
-{ | |
- Discdesc *desc; /* descriptor of temp file */ | |
- Posn nrunes; /* runes on disc file */ | |
- List block; /* list of used block indices */ | |
-}; | |
- | |
struct String | |
{ | |
int16_t n; | |
@@ -127,14 +84,11 @@ struct String | |
wchar_t *s; | |
}; | |
+struct Gapbuffer; | |
struct Buffer | |
{ | |
- Disc *disc; /* disc storage */ | |
- Posn nrunes; /* total length of buffer */ | |
- String cache; /* in-core storage for efficiency */ | |
- Posn c1, c2; /* cache start and end positions in disc */ | |
- /* note: if dirty, cache is really c1, c1+cache.n */ | |
- int dirty; /* cache dirty */ | |
+ Posn nrunes; | |
+ struct Gapbuffer *gb; | |
}; | |
#define NGETC 128 | |
@@ -209,19 +163,12 @@ union Hdr | |
#define Fgetc(f) ((--(f)->ngetc<0)? Fgetcload(f, (f)->getcp) : (f)->getcbuf[(… | |
#define Fbgetc(f) (((f)->getci<=0)? Fbgetcload(f, (f)->getcp) : (f)->getcbuf[-… | |
-void Bclean(Buffer*); | |
void Bterm(Buffer*); | |
void Bdelete(Buffer*, Posn, Posn); | |
void Bflush(Buffer*); | |
void Binsert(Buffer*, String*, Posn); | |
-Buffer *Bopen(Discdesc*); | |
+Buffer *Bopen(void); | |
int Bread(Buffer*, wchar_t*, int, Posn); | |
-void Dclose(Disc*); | |
-void Ddelete(Disc*, Posn, Posn); | |
-void Dinsert(Disc*, wchar_t*, int, Posn); | |
-Disc *Dopen(Discdesc*); | |
-int Dread(Disc*, wchar_t*, int, Posn); | |
-void Dreplace(Disc*, Posn, Posn, wchar_t*, int); | |
int Fbgetcload(File*, Posn); | |
int Fbgetcset(File*, Posn); | |
int64_t Fchars(File*, wchar_t*, Posn, Posn); | |
@@ -334,7 +281,6 @@ void warn_S(Warn, String*); | |
int whichmenu(File*); | |
void writef(File*); | |
Posn writeio(File*); | |
-Discdesc *Dstart(void); | |
extern wchar_t samname[]; /* compiler dependent */ | |
extern wchar_t *left[]; |