Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#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;
}