summary refs log tree commit diff
path: root/doc.c
diff options
context:
space:
mode:
Diffstat (limited to 'doc.c')
-rw-r--r--doc.c157
1 files changed, 33 insertions, 124 deletions
diff --git a/doc.c b/doc.c
index 3478f8b..658315c 100644
--- a/doc.c
+++ b/doc.c
@@ -5,139 +5,48 @@
 #include "doc.h"
 #include "err.h"
 
-/* text */
-
-static struct {
-	char *buf;
-	size_t len, cap;
-} txt;
-
-void txt_init(void) {
-	txt.buf = malloc(1);
-	if (!txt.buf) efatal("txt_init");
-	txt.buf[0] = 0;
-	txt.len = 0;
-	txt.cap = 1;
-}
-
-void txt_fini(void) {
-	free(txt.buf);
-}
-
-void txt_grow(size_t n) {
-	size_t cap = txt.cap;
-	size_t len = txt.len + n;
-	if (cap < len) {
-		while (cap < len) cap <<= 1;
-		char *s = realloc(txt.buf, cap);
-		if (!s) efatal("txt_grow");
-		txt.cap = cap;
-		txt.buf = s;
-	}
-}
-
-/* docs */
-
-struct doc {
-	size_t ofs, len, idx;
-};
-
-#define DOC_MAX 32
-
-static struct doc docv[DOC_MAX] = {
-	{
-		 
-		.ofs = 0,
+void doc_init(struct doc *d) {
+	buf_init(&d->txt, sizeof(struct doc_line));
+	buf_init(&d->lnk, 1);
+	d->txt.sz = sizeof(struct doc_line);
+	*(struct doc_line *)d->txt.buf = (struct doc_line) {
+		.prev = 0,
+		.link = DOC_LINK_NONE,
 		.len = 0,
-		.idx = 0
-	}
-};
-
-static size_t docn = 0, doci = 0;
-
-void doc_pop(void) {
-	if (docn > 0) {
-		docn--;
-		if (doci > 0) doci--;
-	}
-}
-
-void doc_shift(void) {
-	if (docn > 0) {
-		docn--;
-		memmove(txt.buf, txt.buf + docv[0].len, txt.len - docv[0].len);
-		memmove(&docv[0], &docv[1], docn * sizeof(struct doc));
-		docv[0].ofs = 0;
-		for (int i = 1; i < docn; i++) {
-			docv[i].idx = docv[i - 1].ofs + (docv[i].idx - docv[i].ofs);
-			docv[i].ofs = docv[i - 1].ofs + docv[i - 1].len;
-		}
-		if (docn > 0 && doci >= docn) doci = docn - 1;
-	}
-}
-
-void doc_new(void) {
-	while (docn >= DOC_MAX) {
-		doc_shift();
-	}
-	if (doci < docn) {
-		txt.len = docv[doci].ofs;
-		docn = doci;
-	}
-	memset(&docv[docn], 0, sizeof(struct doc));
-	docv[docn].ofs = txt.len;
-	docv[docn].idx = txt.len;
-	doci = docn++;
-}
-
-void doc_add(const char *buf, size_t n) {
-	txt_grow(n);
-	memcpy(&txt.buf[txt.len], buf, n);
-	txt.len += n;
-	docv[doci].len += n;
-}
-
-void doc_adds(const char *s) {
-	doc_add(s, strlen(s));
-}
-
-void doc_prev(void) {
-	if (doci > 0) doci--;
+	};
+	d->latest = 0;
 }
 
-void doc_next(void) {
-	if (doci < docn) doci++;
+void doc_fini(struct doc *d) {
+	buf_free(&d->txt);
+	buf_free(&d->lnk);
 }
 
-void doc_back_line(void) {
-	if (doci >= docn) return;
-	struct doc *d = &docv[doci];
-	size_t i = d->idx;
-	while (i > 0 && txt.buf[d->idx] != '\n') i--;
-	if (i > 0) i--;
-	while (i > 0 && txt.buf[d->idx] != '\n') i--;
-	if (i > 0) i++;
-	d->idx = i;
+void doc_new_line(struct doc *d) {
+	size_t here = d->latest, there = d->txt.sz;
+	buf_grow(&d->txt, sizeof(struct doc_line));
+	*(struct doc_line *)&d->txt.buf[there] = (struct doc_line) {
+		.prev = there - here,
+		.link = DOC_LINK_NONE,
+		.len = 0
+	};
+	d->txt.sz += sizeof(struct doc_line);
+	d->latest = there;
 }
 
-void doc_print_line(void) {
-	if (doci >= docn) return;
-	struct doc *d = &docv[doci];
-	size_t i = d->idx;
-	size_t n = d->ofs + d->len;
-	while (i < n && txt.buf[d->idx] != '\n') {
-		putchar(txt.buf[i++]);
-	}
-	if (i < n) i++;
-	d->idx = i;
+void doc_add_line(struct doc *d, const char *s) {
+	doc_add_text(d, s);
+	doc_new_line(d);
 }
 
-void doc_init(void) {
-	txt_init();
-	doc_new();
-	doc_adds("Type ? for command help.\n");
+void doc_add_text(struct doc *d, const char *s) {
+	doc_add_textn(d, s, strlen(s));
 }
 
-void doc_fini(void) {
-	txt_fini();
+void doc_add_textn(struct doc *d, const char *s, size_t n) {
+	buf_grow(&d->txt, n);
+	memcpy(&d->txt.buf[d->txt.sz], s, n);
+	struct doc_line *dl = (struct doc_line *)&d->txt.buf[d->latest];
+	d->txt.sz += n;
+	dl->len += n;
 }