From: Michael D. Lowis Date: Tue, 21 Aug 2018 00:49:16 +0000 (-0400) Subject: refactored buf.c and fixed big with writing file to disk X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=b1f51c1d226c26e55396cb74d3e7d3f7bccbf676;p=projs%2Ftide.git refactored buf.c and fixed big with writing file to disk --- diff --git a/lib/buf.c b/lib/buf.c index f00477c..f8dcbbc 100644 --- a/lib/buf.c +++ b/lib/buf.c @@ -7,14 +7,14 @@ #include #include -static void buf_resize(Buf* buf, size_t sz); -static void log_clear(Log** list); -static void syncgap(Buf* buf, size_t off); -static int bytes_match(Buf* buf, size_t mbeg, size_t mend, char* str); -static Rune nextrune(Buf* buf, size_t off, int move, bool (*testfn)(Rune)); -static void selline(Buf* buf); -static void selblock(Buf* buf, Rune first, Rune last); -static size_t pagealign(size_t sz); +/* Creation, Resizing, Loading, and Saving + ******************************************************************************/ +static size_t pagealign(size_t sz) { + size_t pgsize = sysconf(_SC_PAGE_SIZE), alignmask = pgsize - 1; + if (sz & alignmask) + sz += pgsize - (sz & alignmask); + return sz; +} void buf_init(Buf* buf) { /* cleanup old data if there is any */ @@ -76,7 +76,7 @@ void buf_save(Buf* buf) { if (0 == buf_end(buf)) return; char* wptr; long fd, nwrite = 0, towrite = 0; - if (buf->path && (fd = open(buf->path, O_WRONLY|O_CREAT, 0644)) >= 0) { + if (buf->path && (fd = open(buf->path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) >= 0) { /* write the chunk before the gap */ wptr = buf->bufstart, towrite = (buf->gapstart - buf->bufstart); while (towrite && ((nwrite = write(fd, wptr, towrite)) > 0)) @@ -93,27 +93,6 @@ void buf_save(Buf* buf) { } } -size_t buf_end(Buf* buf) { - size_t bufsz = buf->bufend - buf->bufstart; - size_t gapsz = buf->gapend - buf->gapstart; - return (bufsz - gapsz); -} - -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)) - 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 void buf_resize(Buf* buf, size_t sz) { /* allocate the new buffer and gap */ Buf copy = *buf; @@ -132,9 +111,22 @@ static void buf_resize(Buf* buf, size_t sz) { 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 Sel getsel(Buf* buf) { +static Sel buf_getsel(Buf* buf) { size_t temp; Sel sel = buf->selection; if (sel.end < sel.beg) @@ -142,8 +134,39 @@ static Sel getsel(Buf* buf) { return sel; } +/* Unod/Redo Operations + ******************************************************************************/ +static void log_clear(Log** list) { + while (*list) { + Log* deadite = *list; + *list = (*list)->next; + if (deadite->data) + free(deadite->data); + free(deadite); + } +} + +void buf_undo(Buf* buf) { +} + +void buf_redo(Buf* buf) { +} + +void buf_logclear(Buf* buf) { + log_clear(&(buf->redo)); + log_clear(&(buf->undo)); +} + +void buf_lastins(Buf* buf) { + Sel sel = buf_getsel(buf); + // Set selection to last inserted text + buf->selection = sel; +} + +/* Basic Operations and Accessors + ******************************************************************************/ static void putb(Buf* buf, char b, Sel* p_sel) { - syncgap(buf, p_sel->end); + buf_syncgap(buf, p_sel->end); *(buf->gapstart++) = b; p_sel->end = p_sel->end + 1u; p_sel->beg = p_sel->end; @@ -159,6 +182,12 @@ static char getb(Buf* buf, size_t off) { return *(buf->gapend + (off - bsz)); } +size_t buf_end(Buf* buf) { + size_t bufsz = buf->bufend - buf->bufstart; + size_t gapsz = buf->gapend - buf->gapstart; + return (bufsz - gapsz); +} + int buf_getrat(Buf* buf, size_t off) { size_t rlen = 0; Rune rune = 0; @@ -182,7 +211,7 @@ int buf_getc(Buf* buf) { } char* buf_gets(Buf* buf) { - Sel sel = getsel(buf); + Sel sel = buf_getsel(buf); size_t nbytes = sel.end - sel.beg; char* str = malloc(nbytes+1); for (size_t i = 0; i < nbytes; i++) @@ -192,12 +221,12 @@ char* buf_gets(Buf* buf) { } void buf_del(Buf* buf) { - Sel sel = getsel(buf); + Sel sel = buf_getsel(buf); size_t nbytes = sel.end - sel.beg; if (nbytes > 0) { buf->status = MODIFIED; //char* str = buf_gets(buf, &sel); - syncgap(buf, sel.beg); + buf_syncgap(buf, sel.beg); buf->gapend += nbytes; sel.end = sel.beg; buf->selection = sel; @@ -206,36 +235,67 @@ void buf_del(Buf* buf) { } } -/******************************************************************************/ - -void buf_undo(Buf* buf) { +/* Positional and Movement Operations + ******************************************************************************/ +static Rune nextrune(Buf* buf, size_t off, int move, bool (*testfn)(Rune)) { + bool ret = false; + size_t end = buf_end(buf); + if (move < 0 && off > 0) + ret = testfn(buf_getrat(buf, off-1)); + else if (move > 0 && off < end) + ret = testfn(buf_getrat(buf, off+1)); + return ret; } -void buf_redo(Buf* buf) { +static void selline(Buf* buf) { + Sel sel = buf_getsel(buf); + sel.beg = buf_bol(buf, sel.end); + sel.end = buf_eol(buf, sel.end); + sel.end = buf_byrune(buf, sel.end, RIGHT); + buf->selection = sel; } -void buf_logclear(Buf* buf) { - log_clear(&(buf->redo)); - log_clear(&(buf->undo)); -} +static void selblock(Buf* buf, Rune first, Rune last) { + Sel sel = buf_getsel(buf); + int balance = 0, dir; + size_t beg, end = sel.end; -void buf_lastins(Buf* buf) { - Sel sel = getsel(buf); - // Set selection to last inserted text - buf->selection = sel; -} + /* figure out which end of the block we're starting at */ + if (buf_getrat(buf, end) == first) + dir = +1, balance++, beg = end++; + else if (buf_getrat(buf, end) == last) + dir = -1, balance--, beg = end--; + else + return; -static void log_clear(Log** list) { - while (*list) { - Log* deadite = *list; - *list = (*list)->next; - if (deadite->data) - free(deadite->data); - free(deadite); + /* scan for a blanced set of braces */ + while (true) { + if (buf_getrat(buf, end) == first) + balance++; + else if (buf_getrat(buf, end) == last) + balance--; + + if (balance == 0 || end >= buf_end(buf) || end == 0) + break; + else + end += dir; } + + /* bail if we failed to find a block */ + if (balance != 0) return; + + /* update the passed in selection */ + if (end > beg) beg++; else end++; + buf->selection.beg = beg, buf->selection.end = end; } -/******************************************************************************/ +static int bytes_match(Buf* buf, size_t mbeg, size_t mend, char* str) { + for (; *str; str++, mbeg++) { + int cmp = *str - getb(buf, mbeg); + if (cmp != 0) return cmp; + } + return 0; +} bool buf_iseol(Buf* buf, size_t off) { Rune r = buf_getrat(buf, off); @@ -253,7 +313,7 @@ size_t buf_eol(Buf* buf, size_t off) { } void buf_selword(Buf* buf, bool (*isword)(Rune)) { - Sel sel = getsel(buf); + Sel sel = buf_getsel(buf); for (; isword(buf_getrat(buf, sel.beg-1)); sel.beg--); for (; isword(buf_getrat(buf, sel.end)); sel.end++); buf->selection = sel; @@ -347,14 +407,6 @@ bool buf_findstr(Buf* buf, int dir, char* str) { return false; } -static int bytes_match(Buf* buf, size_t mbeg, size_t mend, char* str) { - for (; *str; str++, mbeg++) { - int cmp = *str - getb(buf, mbeg); - if (cmp != 0) return cmp; - } - return 0; -} - void buf_setln(Buf* buf, size_t line) { size_t curr = 0, end = buf_end(buf); while (line > 1 && curr < end) { @@ -391,20 +443,8 @@ void buf_setcol(Buf* buf) { buf->selection = sel; } -static Rune nextrune(Buf* buf, size_t off, int move, bool (*testfn)(Rune)) { - bool ret = false; - size_t end = buf_end(buf); - if (move < 0 && off > 0) - ret = testfn(buf_getrat(buf, off-1)); - else if (move > 0 && off < end) - ret = testfn(buf_getrat(buf, off+1)); - return ret; -} - -/******************************************************************************/ - size_t buf_selsz(Buf* buf) { - Sel sel = getsel(buf); + Sel sel = buf_getsel(buf); return sel.end - sel.beg; } @@ -416,7 +456,7 @@ void buf_selclr(Buf* buf, int dir) { } bool buf_insel(Buf* buf, size_t off) { - Sel sel = getsel(buf); + Sel sel = buf_getsel(buf); return (off >= sel.beg && off < sel.end); } @@ -433,55 +473,3 @@ char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off) { buf->selection = prev; return str; } - -/******************************************************************************/ - -static void selline(Buf* buf) { - Sel sel = getsel(buf); - sel.beg = buf_bol(buf, sel.end); - sel.end = buf_eol(buf, sel.end); - sel.end = buf_byrune(buf, sel.end, RIGHT); - buf->selection = sel; -} - -static void selblock(Buf* buf, Rune first, Rune last) { - Sel sel = getsel(buf); - int balance = 0, dir; - size_t beg, end = sel.end; - - /* figure out which end of the block we're starting at */ - if (buf_getrat(buf, end) == first) - dir = +1, balance++, beg = end++; - else if (buf_getrat(buf, end) == last) - dir = -1, balance--, beg = end--; - else - return; - - /* scan for a blanced set of braces */ - while (true) { - if (buf_getrat(buf, end) == first) - balance++; - else if (buf_getrat(buf, end) == last) - balance--; - - if (balance == 0 || end >= buf_end(buf) || end == 0) - break; - else - end += dir; - } - - /* bail if we failed to find a block */ - if (balance != 0) return; - - /* update the passed in selection */ - if (end > beg) beg++; else end++; - buf->selection.beg = beg, buf->selection.end = end; -} - -static size_t pagealign(size_t sz) { - size_t pgsize = sysconf(_SC_PAGE_SIZE), alignmask = pgsize - 1; - if (sz & alignmask) - sz += pgsize - (sz & alignmask); - return sz; -} -