From 4c5442ccd9428c4bb4e73939d3eff50911b574c0 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Mon, 29 Dec 2025 02:29:53 -0500 Subject: various asserts --- txt.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 6 deletions(-) (limited to 'txt.c') diff --git a/txt.c b/txt.c index 7092964..36af521 100644 --- a/txt.c +++ b/txt.c @@ -58,7 +58,7 @@ static void txt_buf_append(Txt *b, TxtBufIdx bi, const char *s, u32 n) { static isize txt_buf_dedup(Txt *b, TxtBufIdx bi, const char *s, u32 n) { TxtBuf *buf = &b->buf[bi]; - if (buf->n >= n && !memcmp(buf->s + (buf->n - n), s, n)) { + if (buf->n >= n && buf->s && !memcmp(buf->s + (buf->n - n), s, n)) { return buf->n - n; } else { return -1; @@ -128,6 +128,14 @@ static TxtLoc txt_join_or_kill(TxtLoc l) { return l; } +static inline TxtLoc resolve_loc(TxtLoc l) { + if (l.p + 1 < l.t->ptbl.n && l.i == l.t->ptbl.v[l.p].n) { + l.p++; + l.i = 0; + } + return l; +} + TxtLoc txt_insert(TxtLoc l, const char *s, u32 n) { l = txt_add_piece(l.t, l); TxtPiece *p = &l.t->ptbl.v[l.p]; @@ -142,7 +150,7 @@ TxtLoc txt_insert(TxtLoc l, const char *s, u32 n) { l.i = p->n; l = txt_join_or_kill(l); l.i = l.t->ptbl.v[l.p].n; - return l; + return resolve_loc(l); } TxtLoc txt_insert_c(TxtLoc l, u32 ch) { @@ -173,15 +181,28 @@ TxtLoc txt_delete(TxtLoc l, u32 n) { } l = txt_join_or_kill(l); } - return txt_join_or_kill(l); + return resolve_loc(txt_join_or_kill(l)); +} + +u32 txt_range_len(TxtLoc lo, TxtLoc hi) { + u32 n = 0; + while (lo.p < hi.p) { + n += lo.t->ptbl.v[lo.p].n - lo.i; + lo.p++; + lo.i = 0; + } + n += hi.i - lo.i; + return n; } TxtLoc txt_delete_range(TxtLoc lo, TxtLoc hi) { /* TODO: figure out nr. of chars, then delete all at once */ - while (txt_before(lo, hi)) { - hi = txt_delete(hi, 1); + if (txt_before(hi, lo)) { + TxtLoc t = lo; + lo = hi; + hi = t; } - return lo; + return txt_delete(hi, txt_range_len(lo, hi)); } TxtLoc txt_delete_c(TxtLoc l) { @@ -242,8 +263,28 @@ void txt_free(Txt *t) { free(t->ptbl.v); } +void txt_write_range(int fd, TxtLoc lo, TxtLoc hi) { + while (lo.p < hi.p) { + TxtPiece *p = &lo.t->ptbl.v[lo.p]; + write(fd, lo.t->buf[p->buf].s + p->ofs + lo.i, p->n - lo.i); + lo.p++; + lo.i = 0; + } + if (hi.i > lo.i) { + TxtPiece *p = &lo.t->ptbl.v[lo.p]; + write(fd, lo.t->buf[p->buf].s + p->ofs + lo.i, hi.i - lo.i); + } +} + /* navigation */ +int txt_valid_loc(TxtLoc l) { + return l.p < l.t->ptbl.n + && (l.i < l.t->ptbl.v[l.p].n + || (l.p + 1 == l.t->ptbl.n + && l.i <= l.t->ptbl.v[l.p].n)); +} + TxtLoc txt_at(Txt *b, u32 ofs) { for (u32 i = 0; i < b->ptbl.n; i++) { if (ofs < b->ptbl.v[i].n) { @@ -263,13 +304,25 @@ u32 txt_ofs(TxtLoc l) { } int txt_before(TxtLoc a, TxtLoc b) { + ASSERT(txt_valid_loc(a)); + ASSERT(txt_valid_loc(b)); return a.p < b.p || (a.p == b.p && a.i < b.i); } int txt_after(TxtLoc a, TxtLoc b) { + ASSERT(txt_valid_loc(a)); + ASSERT(txt_valid_loc(b)); return a.p > b.p || (a.p == b.p && a.i > b.i); } +TxtLoc txt_start(Txt *t) { + return (TxtLoc) { t, 0, 0 }; +} + +TxtLoc txt_end(Txt *t) { + return (TxtLoc) { t, t->ptbl.n-1, t->ptbl.v[t->ptbl.n-1].n }; +} + TxtLoc bnext(TxtLoc l) { TxtPiece *p = &l.t->ptbl.v[l.p]; if (l.p + 1 < l.t->ptbl.n) { -- cgit v1.2.3