ref: 4d69aacea023546a7150d92e147e531c38de822f
dir: /sys/src/cmd/mk/bufblock.c/
#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) { assert(p->current >= p->start); p->current = 0; 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) { assert(f->current == 0); 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; 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 c; while (c = *cp++) insert(buf, c); } void bufncpy(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; }