summaryrefslogtreecommitdiff
path: root/doc.c
diff options
context:
space:
mode:
authorwrmr2024-11-02 19:33:08 -0500
committerwrmr2024-11-02 19:33:08 -0500
commit610808a5902adad751a4acdbcc310803a51fed5d (patch)
tree76599dc60cccf6a3765f484dfa1b19e1af88efa1 /doc.c
parent58214ec5f982c1b97aadce254c958a5f922c9724 (diff)
very different document data structure
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;
}