aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/mk/bufblock.c
blob: 979403bcaa561eb3cc02278e24360e4203b1ac50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#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;
}