From: Michael D. Lowis Date: Mon, 14 Oct 2019 11:48:54 +0000 (-0400) Subject: broke out gapbuf functions to separate file X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=7913282d655f57d742a3487e92e4f0173451ca41;p=projs%2Ftide.git broke out gapbuf functions to separate file --- diff --git a/src/lib/buf.c b/src/lib/buf.c index 193eb3d..bd54548 100644 --- a/src/lib/buf.c +++ b/src/lib/buf.c @@ -8,6 +8,10 @@ #include #include "config.h" +extern char gapbuf_getb(Buf* buf, size_t off); +extern void gapbuf_putb(Buf* buf, char b, Sel* p_sel); +extern void gapbuf_del(Buf* buf, size_t off, size_t len); + #ifndef NDEBUG static bool buf_valid(Buf* buf) { @@ -41,8 +45,6 @@ static Sel selget(Buf* buf) return (sel.end < sel.beg ? selswap(sel) : sel); } -/* Creation, Resizing, Loading, and Saving - ******************************************************************************/ static size_t pagealign(size_t sz) { size_t pgsize = sysconf(_SC_PAGE_SIZE); @@ -54,97 +56,18 @@ static size_t pagealign(size_t sz) return sz; } -static void buf_resize(Buf* buf, size_t sz) -{ - /* allocate the new buffer and gap */ - Buf copy = *buf; - copy.bufsize = sz; - copy.bufstart = (char*)malloc(copy.bufsize); - copy.bufend = copy.bufstart + copy.bufsize; - copy.gapstart = copy.bufstart; - copy.gapend = copy.bufend; - - /* copy the data from the old buffer to the new one */ - for (char* curr = buf->bufstart; curr < buf->gapstart; curr++) - { - *(copy.gapstart++) = *(curr); - } - for (char* curr = buf->gapend; curr < buf->bufend; curr++) - { - *(copy.gapstart++) = *(curr); - } - - /* free the buffer and commit the changes */ - free(buf->bufstart); - memcpy(buf, ©, sizeof(Buf)); -} - -static void buf_syncgap(Buf* buf, size_t off) -{ - assert(off <= buf_end(buf)); - /* If the buffer is full, resize it before syncing */ - if (0 == (buf->gapend - buf->gapstart)) - { - buf_resize(buf, buf->bufsize << 1); - } - - /* Move the gap to the desired offset */ - char* newpos = (buf->bufstart + off); - if (newpos < buf->gapstart) - { - while (newpos < buf->gapstart) - { - *(--buf->gapend) = *(--buf->gapstart); - } - } - else - { - while (newpos > buf->gapstart) - { - *(buf->gapstart++) = *(buf->gapend++); - } - } -} - -static char getb(Buf* buf, size_t off) -{ - int c = '\n'; // TODO: get rid of this hack - if (off < buf_end(buf)) - { - size_t bsz = (buf->gapstart - buf->bufstart); - if (off < bsz) - { - c = *(buf->bufstart + off); - } - else - { - c = *(buf->gapend + (off - bsz)); - } - } - return c; -} - -static void putb(Buf* buf, char b, Sel* p_sel) -{ - buf_syncgap(buf, p_sel->end); - *(buf->gapstart++) = b; - p_sel->end = p_sel->end + 1u; - p_sel->beg = p_sel->end; - buf->status = MODIFIED; -} - static void putch(Buf* buf, char b, Sel* p_sel) { if (b != '\r') { if (b == '\n' && DosLineFeed) { - putb(buf, '\r', p_sel); - putb(buf, '\n', p_sel); + gapbuf_putb(buf, '\r', p_sel); + gapbuf_putb(buf, '\n', p_sel); } else { - putb(buf, b, p_sel); + gapbuf_putb(buf, b, p_sel); } } } @@ -228,7 +151,7 @@ void buf_load(Buf* buf, char* path) buf_logclear(buf); /* use the EOL style of the first line to determine EOL style */ - DosLineFeed = (getb(buf, buf_eol(buf, 0)) == '\r'); + DosLineFeed = (gapbuf_getb(buf, buf_eol(buf, 0)) == '\r'); } ensure(buf_valid(buf)); } @@ -259,7 +182,7 @@ static void trim_whitespace(Buf* buf) buf_logstart(buf); while (prev != buf->selection.end) { - int r = getb(buf, buf->selection.end); + int r = gapbuf_getb(buf, buf->selection.end); /* If we reached a newline, then delete whatever we have selected */ if (r == '\r' || r == '\n') { @@ -424,7 +347,7 @@ static void log_swap(Buf* buf, Log** src, Log** dest) /* reinsert deleted bytes */ for (char* s = item->data; s && *s; s++, item->end++) { - putb(buf, *s, &(buf->selection)); + gapbuf_putb(buf, *s, &(buf->selection)); } free(item->data); item->data = NULL; @@ -436,8 +359,7 @@ static void log_swap(Buf* buf, Log** src, Log** dest) /* delete the added bytes */ Sel sel = selget(buf); item->data = buf_gets(buf); - buf_syncgap(buf, sel.beg); - buf->gapend += (item->end - item->beg); + gapbuf_del(buf, sel.beg, (item->end - item->beg)); sel.end = sel.beg; buf->selection = sel; item->beg = sel.beg; @@ -555,13 +477,13 @@ int buf_getrat(Buf* buf, size_t off) require(buf != NULL); size_t rlen = 0; Rune rune = 0; - if (getb(buf, off) == '\r' && getb(buf, off+1) == '\n') + if (gapbuf_getb(buf, off) == '\r' && gapbuf_getb(buf, off+1) == '\n') { rune = '\n'; } else { - while ( !utf8decode(&rune, &rlen, getb(buf, off++)) ) + while ( !utf8decode(&rune, &rlen, gapbuf_getb(buf, off++)) ) { } } @@ -607,7 +529,7 @@ char* buf_gets(Buf* buf) char* str = malloc(nbytes+1); for (size_t i = 0; i < nbytes; i++) { - str[i] = getb(buf, sel.beg + i); + str[i] = gapbuf_getb(buf, sel.beg + i); } str[nbytes] = '\0'; return str; @@ -632,8 +554,7 @@ void buf_del(Buf* buf) { buf->status = MODIFIED; char* str = buf_gets(buf); - buf_syncgap(buf, sel.beg); - buf->gapend += nbytes; + gapbuf_del(buf, sel.beg, nbytes); sel.end = sel.beg = (sel.beg < sel.end ? sel.beg : sel.end); buf->selection = sel; log_add(buf, sel.beg, sel.end, str); @@ -733,7 +654,7 @@ static int bytes_match(Buf* buf, size_t mbeg, size_t mend, char* str) int ret = 0; for (; *str && mbeg < mend; str++, mbeg++) { - int cmp = *str - getb(buf, mbeg); + int cmp = *str - gapbuf_getb(buf, mbeg); if (cmp != 0) { ret = cmp; @@ -882,7 +803,7 @@ size_t buf_byrune(Buf* buf, size_t pos, int count) { if (pos > 0 && move < 0) { - if (getb(buf, pos-2) == '\r' && getb(buf, pos-1) == '\n') + if (gapbuf_getb(buf, pos-2) == '\r' && gapbuf_getb(buf, pos-1) == '\n') { pos -= 2; } @@ -893,7 +814,7 @@ size_t buf_byrune(Buf* buf, size_t pos, int count) } else if (pos < buf_end(buf) && move > 0) { - if (getb(buf, pos) == '\r' && getb(buf, pos+1) == '\n') + if (gapbuf_getb(buf, pos) == '\r' && gapbuf_getb(buf, pos+1) == '\n') { pos += 2; } @@ -973,8 +894,8 @@ bool buf_findstr(Buf* buf, int dir, char* str) size_t nleft = buf_end(buf); for (; (mbeg != start) && nleft; nleft--) { - if ((getb(buf, mbeg) == str[0]) && - (getb(buf, mend-1) == str[len-1]) && + if ((gapbuf_getb(buf, mbeg) == str[0]) && + (gapbuf_getb(buf, mend-1) == str[len-1]) && (0 == bytes_match(buf, mbeg, mend, str))) { buf->selection.beg = mbeg, buf->selection.end = mend; diff --git a/src/lib/gapbuf.c b/src/lib/gapbuf.c new file mode 100644 index 0000000..1609b03 --- /dev/null +++ b/src/lib/gapbuf.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" + +static void resize(Buf* buf, size_t sz) +{ + /* allocate the new buffer and gap */ + Buf copy = *buf; + copy.bufsize = sz; + copy.bufstart = (char*)malloc(copy.bufsize); + copy.bufend = copy.bufstart + copy.bufsize; + copy.gapstart = copy.bufstart; + copy.gapend = copy.bufend; + + /* copy the data from the old buffer to the new one */ + for (char* curr = buf->bufstart; curr < buf->gapstart; curr++) + { + *(copy.gapstart++) = *(curr); + } + for (char* curr = buf->gapend; curr < buf->bufend; curr++) + { + *(copy.gapstart++) = *(curr); + } + + /* free the buffer and commit the changes */ + free(buf->bufstart); + memcpy(buf, ©, sizeof(Buf)); +} + +static void syncgap(Buf* buf, size_t off) +{ + assert(off <= buf_end(buf)); + /* If the buffer is full, resize it before syncing */ + if (0 == (buf->gapend - buf->gapstart)) + { + resize(buf, buf->bufsize << 1); + } + + /* Move the gap to the desired offset */ + char* newpos = (buf->bufstart + off); + if (newpos < buf->gapstart) + { + while (newpos < buf->gapstart) + { + *(--buf->gapend) = *(--buf->gapstart); + } + } + else + { + while (newpos > buf->gapstart) + { + *(buf->gapstart++) = *(buf->gapend++); + } + } +} + +char gapbuf_getb(Buf* buf, size_t off) +{ + int c = '\n'; // TODO: get rid of this hack + if (off < buf_end(buf)) + { + size_t bsz = (buf->gapstart - buf->bufstart); + if (off < bsz) + { + c = *(buf->bufstart + off); + } + else + { + c = *(buf->gapend + (off - bsz)); + } + } + return c; +} + +void gapbuf_putb(Buf* buf, char b, Sel* p_sel) +{ + syncgap(buf, p_sel->end); + *(buf->gapstart++) = b; + p_sel->end = p_sel->end + 1u; + p_sel->beg = p_sel->end; + buf->status = MODIFIED; +} + +void gapbuf_del(Buf* buf, size_t off, size_t len) +{ + syncgap(buf, off); + buf->gapend += len; +}