From 610808a5902adad751a4acdbcc310803a51fed5d Mon Sep 17 00:00:00 2001 From: wrmr Date: Sat, 2 Nov 2024 19:33:08 -0500 Subject: very different document data structure --- doc.c | 157 ++++++++++++++---------------------------------------------------- 1 file changed, 33 insertions(+), 124 deletions(-) (limited to 'doc.c') 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; } -- cgit 1.4.1-2-gfad0