| #include "mk.h" |
| |
| static Bufblock *freelist; |
| #define QUANTA 4096 |
| |
| Bufblock * |
| newbuf(void) |
| { |
| Bufblock *p; |
| |
| if (freelist) { |
| p = freelist; |
| freelist = freelist->next; |
| } else { |
| p = (Bufblock *) Malloc(sizeof(Bufblock)); |
| p->start = Malloc(QUANTA*sizeof(*p->start)); |
| p->end = p->start+QUANTA; |
| } |
| p->current = p->start; |
| *p->start = 0; |
| p->next = 0; |
| return p; |
| } |
| |
| void |
| freebuf(Bufblock *p) |
| { |
| p->next = freelist; |
| freelist = p; |
| } |
| |
| void |
| growbuf(Bufblock *p) |
| { |
| int n; |
| Bufblock *f; |
| char *cp; |
| |
| n = p->end-p->start+QUANTA; |
| /* search the free list for a big buffer */ |
| for (f = freelist; f; f = f->next) { |
| if (f->end-f->start >= n) { |
| memcpy(f->start, p->start, p->end-p->start); |
| cp = f->start; |
| f->start = p->start; |
| p->start = cp; |
| cp = f->end; |
| f->end = p->end; |
| p->end = cp; |
| f->current = f->start; |
| break; |
| } |
| } |
| if (!f) { /* not found - grow it */ |
| p->start = Realloc(p->start, n); |
| p->end = p->start+n; |
| } |
| p->current = p->start+n-QUANTA; |
| } |
| |
| void |
| bufcpy(Bufblock *buf, char *cp, int n) |
| { |
| |
| while (n--) |
| insert(buf, *cp++); |
| } |
| |
| void |
| insert(Bufblock *buf, int c) |
| { |
| |
| if (buf->current >= buf->end) |
| growbuf(buf); |
| *buf->current++ = c; |
| } |
| |
| void |
| rinsert(Bufblock *buf, Rune r) |
| { |
| int n; |
| |
| n = runelen(r); |
| if (buf->current+n > buf->end) |
| growbuf(buf); |
| runetochar(buf->current, &r); |
| buf->current += n; |
| } |