]> git.mdlowis.com Git - projs/tide.git/commitdiff
refactored more gapbuf functions
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 15 Oct 2019 02:09:38 +0000 (22:09 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 15 Oct 2019 02:09:38 +0000 (22:09 -0400)
inc/edit.h
src/lib/buf.c
src/lib/gapbuf.c
src/tide.c
tests/lib/buf.c

index bb7512048b20a3f8198562e5fa5cd9d9d6c86afc..d351f3cbb98e50d9eed618c4759aed4e3e0ba9a3 100644 (file)
@@ -16,18 +16,21 @@ typedef struct {
     size_t col;
 } Sel;
 
-/* gap buffer main data structure */
 typedef struct {
-    enum {
-        NORMAL = 0, MODIFIED, OUTDATED, ERRORED
-    } status;
-    char* path;       /* the path to the open file */
-    uint64_t modtime; /* modification time of the opened file */
     size_t bufsize;   /* size of the buffer in runes */
     char* bufstart;   /* start of the data buffer */
     char* bufend;     /* end of the data buffer */
     char* gapstart;   /* start of the gap */
     char* gapend;     /* end of the gap */
+} GapBuf;
+
+/* gap buffer main data structure */
+typedef struct {
+    enum {
+        NORMAL = 0, MODIFIED, OUTDATED, ERRORED
+    } status;
+    char* path;       /* the path to the open file */
+    GapBuf contents;  /* underlying sequence data structure */
     Log* undo;        /* undo list */
     Log* redo;        /* redo list */
     Log* save;        /* pointer to last save position */
@@ -35,6 +38,14 @@ typedef struct {
     Sel selection;    /* the currently selected text */
 } Buf;
 
+void gapbuf_init(GapBuf* buf);
+size_t gapbuf_end(GapBuf* buf);
+long gapbuf_save(GapBuf* buf, char* path);
+void gapbuf_load(GapBuf* buf, char* path);
+char gapbuf_getb(GapBuf* buf, size_t off);
+void gapbuf_putb(GapBuf* buf, char b, Sel* p_sel);
+void gapbuf_del(GapBuf* buf, size_t off, size_t len);
+
 void buf_init(Buf* buf);
 void buf_setpath(Buf* buf, char* path);
 void buf_load(Buf* buf, char* path);
index 9abd8ba8770800e32a42c4bd08eef0a3e124ea2f..5402c6b3c96f94f2febebd0bc0213c3a555e939c 100644 (file)
@@ -8,28 +8,21 @@
 #include <sys/stat.h>
 #include "config.h"
 
-extern void gapbuf_init(Buf* buf);
-extern long gapbuf_save(Buf* buf, char* path);
-extern void gapbuf_load(Buf* buf, char* path);
-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)
 {
     return (
-           (buf->bufsize > 0)
-        && (buf->bufstart != NULL)
-        && (buf->bufend != NULL)
-        && (buf->gapstart != NULL)
-        && (buf->gapend != NULL)
-        && (buf->bufstart < buf->bufend)
-        && (buf->gapstart <= buf->gapend)
-        && (buf->gapstart >= buf->bufstart)
-        && (buf->gapend >= buf->bufstart)
-        && (buf->gapstart <= buf->bufend)
-        && (buf->gapend <= buf->bufend)
+           (buf->contents.bufsize > 0)
+        && (buf->contents.bufstart != NULL)
+        && (buf->contents.bufend != NULL)
+        && (buf->contents.gapstart != NULL)
+        && (buf->contents.gapend != NULL)
+        && (buf->contents.bufstart < buf->contents.bufend)
+        && (buf->contents.gapstart <= buf->contents.gapend)
+        && (buf->contents.gapstart >= buf->contents.bufstart)
+        && (buf->contents.gapend >= buf->contents.bufstart)
+        && (buf->contents.gapstart <= buf->contents.bufend)
+        && (buf->contents.gapend <= buf->contents.bufend)
     );
 }
 #endif
@@ -54,13 +47,14 @@ static void putch(Buf* buf, char b, Sel* p_sel)
     {
         if (b == '\n' && DosLineFeed)
         {
-            gapbuf_putb(buf, '\r', p_sel);
-            gapbuf_putb(buf, '\n', p_sel);
+            gapbuf_putb(&buf->contents, '\r', p_sel);
+            gapbuf_putb(&buf->contents, '\n', p_sel);
         }
         else
         {
-            gapbuf_putb(buf, b, p_sel);
+            gapbuf_putb(&buf->contents, b, p_sel);
         }
+        buf->status = MODIFIED;
     }
 }
 
@@ -68,18 +62,8 @@ void buf_init(Buf* buf)
 {
     require(buf != NULL);
 
-    /* cleanup old data if there is any */
-    if (buf->bufstart)
-    {
-        free(buf->bufstart);
-        buf->bufstart = NULL;
-        free(buf->path);
-        buf->path = NULL;
-        buf_logclear(buf);
-    }
-
     /* reset the state to defaults */
-    gapbuf_init(buf);
+    gapbuf_init(&buf->contents);
     buf->status    = NORMAL;
     buf->undo      = NULL;
     buf->redo      = NULL;
@@ -111,14 +95,14 @@ void buf_load(Buf* buf, char* path)
             path += 2;
         }
         buf->path = strdup(path);
-        gapbuf_load(buf, buf->path);
+        gapbuf_load(&buf->contents, buf->path);
 
         /* reset buffer state */
         buf->status  = NORMAL;
         buf_logclear(buf);
 
         /* use the EOL style of the first line to determine EOL style */
-        DosLineFeed = (gapbuf_getb(buf, buf_eol(buf, 0)) == '\r');
+        DosLineFeed = (gapbuf_getb(&buf->contents, buf_eol(buf, 0)) == '\r');
     }
     ensure(buf_valid(buf));
 }
@@ -149,7 +133,7 @@ static void trim_whitespace(Buf* buf)
     buf_logstart(buf);
     while (prev != buf->selection.end)
     {
-        int r = gapbuf_getb(buf, buf->selection.end);
+        int r = gapbuf_getb(&buf->contents, buf->selection.end);
         /* If we reached a newline, then delete whatever we have selected */
         if (r == '\r' || r == '\n')
         {
@@ -189,7 +173,7 @@ int buf_save(Buf* buf, char* path)
             trim_whitespace(buf);
         }
 
-        long nwrite = gapbuf_save(buf, buf->path);
+        long nwrite = gapbuf_save(&buf->contents, buf->path);
         buf->status = (nwrite >= 0 ? NORMAL : ERRORED);
 
         if (buf->status == NORMAL)
@@ -296,7 +280,8 @@ static void log_swap(Buf* buf, Log** src, Log** dest)
             /* reinsert deleted bytes */
             for (char* s = item->data; s && *s; s++, item->end++)
             {
-                gapbuf_putb(buf, *s, &(buf->selection));
+                gapbuf_putb(&buf->contents, *s, &(buf->selection));
+                buf->status = MODIFIED;
             }
             free(item->data);
             item->data = NULL;
@@ -308,7 +293,7 @@ static void log_swap(Buf* buf, Log** src, Log** dest)
             /* delete the added bytes */
             Sel sel = selget(buf);
             item->data = buf_gets(buf);
-            gapbuf_del(buf, sel.beg, (item->end - item->beg));
+            gapbuf_del(&buf->contents, sel.beg, (item->end - item->beg));
             sel.end = sel.beg;
             buf->selection = sel;
             item->beg = sel.beg;
@@ -415,10 +400,7 @@ void buf_lastins(Buf* buf)
  ******************************************************************************/
 size_t buf_end(Buf* buf)
 {
-    require(buf != NULL);
-    size_t bufsz = buf->bufend - buf->bufstart;
-    size_t gapsz = buf->gapend - buf->gapstart;
-    return (bufsz - gapsz);
+    return gapbuf_end(&buf->contents);
 }
 
 int buf_getrat(Buf* buf, size_t off)
@@ -426,13 +408,13 @@ int buf_getrat(Buf* buf, size_t off)
     require(buf != NULL);
     size_t rlen = 0;
     Rune rune = 0;
-    if (gapbuf_getb(buf, off) == '\r' && gapbuf_getb(buf, off+1) == '\n')
+    if (gapbuf_getb(&buf->contents, off) == '\r' && gapbuf_getb(&buf->contents, off+1) == '\n')
     {
         rune = '\n';
     }
     else
     {
-        while ( !utf8decode(&rune, &rlen, gapbuf_getb(buf, off++)) )
+        while ( !utf8decode(&rune, &rlen, gapbuf_getb(&buf->contents, off++)) )
         {
         }
     }
@@ -478,7 +460,7 @@ char* buf_gets(Buf* buf)
     char* str = malloc(nbytes+1);
     for (size_t i = 0; i < nbytes; i++)
     {
-        str[i] = gapbuf_getb(buf, sel.beg + i);
+        str[i] = gapbuf_getb(&buf->contents, sel.beg + i);
     }
     str[nbytes] = '\0';
     return str;
@@ -503,7 +485,7 @@ void buf_del(Buf* buf)
     {
         buf->status = MODIFIED;
         char* str = buf_gets(buf);
-        gapbuf_del(buf, sel.beg, nbytes);
+        gapbuf_del(&buf->contents, 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);
@@ -603,7 +585,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 - gapbuf_getb(buf, mbeg);
+        int cmp = *str - gapbuf_getb(&buf->contents, mbeg);
         if (cmp != 0)
         {
             ret = cmp;
@@ -752,7 +734,7 @@ size_t buf_byrune(Buf* buf, size_t pos, int count)
     {
         if (pos > 0 && move < 0)
         {
-            if (gapbuf_getb(buf, pos-2) == '\r' && gapbuf_getb(buf, pos-1) == '\n')
+            if (gapbuf_getb(&buf->contents, pos-2) == '\r' && gapbuf_getb(&buf->contents, pos-1) == '\n')
             {
                 pos -= 2;
             }
@@ -763,7 +745,7 @@ size_t buf_byrune(Buf* buf, size_t pos, int count)
         }
         else if (pos < buf_end(buf) && move > 0)
         {
-            if (gapbuf_getb(buf, pos) == '\r' && gapbuf_getb(buf, pos+1) == '\n')
+            if (gapbuf_getb(&buf->contents, pos) == '\r' && gapbuf_getb(&buf->contents, pos+1) == '\n')
             {
                 pos += 2;
             }
@@ -843,8 +825,8 @@ bool buf_findstr(Buf* buf, int dir, char* str)
     size_t nleft = buf_end(buf);
     for (; (mbeg != start) && nleft; nleft--)
     {
-        if ((gapbuf_getb(buf, mbeg) == str[0]) &&
-            (gapbuf_getb(buf, mend-1) == str[len-1]) &&
+        if ((gapbuf_getb(&buf->contents, mbeg) == str[0]) &&
+            (gapbuf_getb(&buf->contents, mend-1) == str[len-1]) &&
             (0 == bytes_match(buf, mbeg, mend, str)))
         {
             buf->selection.beg = mbeg, buf->selection.end = mend;
index 50cbef81eadac3d2f6b1540e8c469bc467900c07..03c93afb9141003bf75ffd13ba5e14fd56a23891 100644 (file)
@@ -8,6 +8,14 @@
 #include <sys/stat.h>
 #include "config.h"
 
+size_t gapbuf_end(GapBuf* buf)
+{
+    require(buf != NULL);
+    size_t bufsz = buf->bufend - buf->bufstart;
+    size_t gapsz = buf->gapend - buf->gapstart;
+    return (bufsz - gapsz);
+}
+
 static size_t pagealign(size_t sz)
 {
     size_t pgsize = sysconf(_SC_PAGE_SIZE);
@@ -19,10 +27,10 @@ static size_t pagealign(size_t sz)
     return sz;
 }
 
-static void resize(Buf* buf, size_t sz)
+static void resize(GapBuf* buf, size_t sz)
 {
     /* allocate the new buffer and gap */
-    Buf copy = *buf;
+    GapBuf copy = *buf;
     copy.bufsize  = sz;
     copy.bufstart = (char*)malloc(copy.bufsize);
     copy.bufend   = copy.bufstart + copy.bufsize;
@@ -41,12 +49,12 @@ static void resize(Buf* buf, size_t sz)
 
     /* free the buffer and commit the changes */
     free(buf->bufstart);
-    memcpy(buf, &copy, sizeof(Buf));
+    memcpy(buf, &copy, sizeof(GapBuf));
 }
 
-static void syncgap(Buf* buf, size_t off)
+static void syncgap(GapBuf* buf, size_t off)
 {
-    assert(off <= buf_end(buf));
+    assert(off <= gapbuf_end(buf));
     /* If the buffer is full, resize it before syncing */
     if (0 == (buf->gapend - buf->gapstart))
     {
@@ -71,7 +79,7 @@ static void syncgap(Buf* buf, size_t off)
     }
 }
 
-void gapbuf_init(Buf* buf)
+void gapbuf_init(GapBuf* buf)
 {
     buf->bufsize   = 8192;
     buf->bufstart  = malloc(buf->bufsize);
@@ -80,7 +88,7 @@ void gapbuf_init(Buf* buf)
     buf->gapend    = buf->bufend;
 }
 
-long gapbuf_save(Buf* buf, char* path)
+long gapbuf_save(GapBuf* buf, char* path)
 {
     char* wptr;
     long fd, nwrite = 0, towrite = 0;
@@ -95,8 +103,6 @@ long gapbuf_save(Buf* buf, char* path)
         while (towrite && ((nwrite = write(fd, wptr, towrite)) > 0))
             wptr += nwrite, towrite -= nwrite;
         close(fd);
-        /* report success or failure */
-        buf->status = (nwrite >= 0 ? NORMAL : ERRORED);
     }
     else
     {
@@ -105,7 +111,7 @@ long gapbuf_save(Buf* buf, char* path)
     return nwrite;
 }
 
-void gapbuf_load(Buf* buf, char* path)
+void gapbuf_load(GapBuf* buf, char* path)
 {
     /* load the contents from the file */
     int fd, nread;
@@ -129,10 +135,10 @@ void gapbuf_load(Buf* buf, char* path)
     }
 }
 
-char gapbuf_getb(Buf* buf, size_t off)
+char gapbuf_getb(GapBuf* buf, size_t off)
 {
     int c = '\n'; // TODO: get rid of this hack
-    if (off < buf_end(buf))
+    if (off < gapbuf_end(buf))
     {
         size_t bsz = (buf->gapstart - buf->bufstart);
         if (off < bsz)
@@ -147,16 +153,15 @@ char gapbuf_getb(Buf* buf, size_t off)
     return c;
 }
 
-void gapbuf_putb(Buf* buf, char b, Sel* p_sel)
+void gapbuf_putb(GapBuf* 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)
+void gapbuf_del(GapBuf* buf, size_t off, size_t len)
 {
     syncgap(buf, off);
     buf->gapend += len;
index 5ecb4168b29a03d1b9b73aeaaf73d08cbb822532..b4b05e609aab835f9a5f7c123e5012dd20c549e6 100644 (file)
@@ -60,12 +60,11 @@ static void dumpdata(FILE* f)
         fprintf(f, "\t.rows:\t\t%p\n",     (void*)Regions[i].rows);
         fprintf(f, "\t.buffer:\n");
         fprintf(f, "\t\t.status:\t%d\n",   Regions[i].buffer.status);
-        fprintf(f, "\t\t.modtime:\t%lu\n", (unsigned long)Regions[i].buffer.modtime);
-        fprintf(f, "\t\t.bufsize:\t%zu\n", Regions[i].buffer.bufsize);
-        fprintf(f, "\t\t.bufstart:\t%p\n", (void*)Regions[i].buffer.bufstart);
-        fprintf(f, "\t\t.bufend:\t%p\n",   (void*)Regions[i].buffer.bufend);
-        fprintf(f, "\t\t.gapstart:\t%p\n", (void*)Regions[i].buffer.gapstart);
-        fprintf(f, "\t\t.gapend:\t%p\n",   (void*)Regions[i].buffer.gapend);
+        fprintf(f, "\t\t.bufsize:\t%zu\n", Regions[i].buffer.contents.bufsize);
+        fprintf(f, "\t\t.bufstart:\t%p\n", (void*)Regions[i].buffer.contents.bufstart);
+        fprintf(f, "\t\t.bufend:\t%p\n",   (void*)Regions[i].buffer.contents.bufend);
+        fprintf(f, "\t\t.gapstart:\t%p\n", (void*)Regions[i].buffer.contents.gapstart);
+        fprintf(f, "\t\t.gapend:\t%p\n",   (void*)Regions[i].buffer.contents.gapend);
         fprintf(f, "\t\t.undo:\t\t%p\n",   (void*)Regions[i].buffer.undo);
         fprintf(f, "\t\t.redo:\t\t%p\n",   (void*)Regions[i].buffer.redo);
         fprintf(f, "\t\t.save:\t\t%p\n",   (void*)Regions[i].buffer.save);
index b33af63a58ac97a8ffcddef1c31fe59f5c35e8fc..6312141184d099459c4188c24bf10882cc1a7d08 100644 (file)
@@ -13,6 +13,15 @@ static Buf TestBuf = {0};
 
 static void set_buffer_text(char* str)
 {
+    /* cleanup old data if there is any */
+    if (TestBuf.contents.bufstart)
+    {
+        free(TestBuf.contents.bufstart);
+        TestBuf.contents.bufstart = NULL;
+        free(TestBuf.path);
+        TestBuf.path = NULL;
+        buf_logclear(&TestBuf);
+    }
     buf_init(&TestBuf);
     buf_puts(&TestBuf, str);
 }
@@ -128,11 +137,11 @@ TEST_SUITE(BufferTests)
     {
         buf_init(&TestBuf);
         CHECK(TestBuf.status      != MODIFIED);
-        CHECK(TestBuf.bufsize     == 8192);
-        CHECK(TestBuf.bufstart    != NULL);
-        CHECK(TestBuf.bufend      == TestBuf.bufstart + TestBuf.bufsize);
-        CHECK(TestBuf.gapstart    == TestBuf.bufstart);
-        CHECK(TestBuf.gapend      == TestBuf.bufend);
+        CHECK(TestBuf.contents.bufsize     == 8192);
+        CHECK(TestBuf.contents.bufstart    != NULL);
+        CHECK(TestBuf.contents.bufend      == TestBuf.contents.bufstart + TestBuf.contents.bufsize);
+        CHECK(TestBuf.contents.gapstart    == TestBuf.contents.bufstart);
+        CHECK(TestBuf.contents.gapend      == TestBuf.contents.bufend);
         CHECK(TestBuf.undo        == NULL);
         CHECK(TestBuf.redo        == NULL);
     }
@@ -143,11 +152,11 @@ TEST_SUITE(BufferTests)
         buf_putc(&TestBuf, 'a');
         buf_init(&TestBuf);
         CHECK(TestBuf.status      != MODIFIED);
-        CHECK(TestBuf.bufsize     == 8192);
-        CHECK(TestBuf.bufstart    != NULL);
-        CHECK(TestBuf.bufend      == TestBuf.bufstart + TestBuf.bufsize);
-        CHECK(TestBuf.gapstart    == TestBuf.bufstart);
-        CHECK(TestBuf.gapend      == TestBuf.bufend);
+        CHECK(TestBuf.contents.bufsize     == 8192);
+        CHECK(TestBuf.contents.bufstart    != NULL);
+        CHECK(TestBuf.contents.bufend      == TestBuf.contents.bufstart + TestBuf.contents.bufsize);
+        CHECK(TestBuf.contents.gapstart    == TestBuf.contents.bufstart);
+        CHECK(TestBuf.contents.gapend      == TestBuf.contents.bufend);
         CHECK(TestBuf.undo        == NULL);
         CHECK(TestBuf.redo        == NULL);
     }
@@ -177,7 +186,7 @@ TEST_SUITE(BufferTests)
         buf_init(&TestBuf);
         buf_load(&TestBuf, "testdocs/lorem.txt");
         CHECK(TestBuf.status      != MODIFIED);
-        CHECK(TestBuf.bufsize     == 61440);
+        CHECK(TestBuf.contents.bufsize     == 61440);
         CHECK(TestBuf.undo        == NULL);
         CHECK(TestBuf.redo        == NULL);
         CHECK(!strcmp(TestBuf.path, "testdocs/lorem.txt"));
@@ -188,7 +197,7 @@ TEST_SUITE(BufferTests)
         buf_init(&TestBuf);
         buf_load(&TestBuf, "testdocs/waf");
         CHECK(TestBuf.status      != MODIFIED);
-        CHECK(TestBuf.bufsize     == 98304);
+        CHECK(TestBuf.contents.bufsize     == 98304);
         CHECK(TestBuf.undo        == NULL);
         CHECK(TestBuf.redo        == NULL);
         CHECK(!strcmp(TestBuf.path, "testdocs/waf"));
@@ -199,7 +208,7 @@ TEST_SUITE(BufferTests)
         buf_init(&TestBuf);
         buf_load(&TestBuf, "./testdocs/lorem.txt");
         CHECK(TestBuf.status      != MODIFIED);
-        CHECK(TestBuf.bufsize     == 61440);
+        CHECK(TestBuf.contents.bufsize     == 61440);
         CHECK(TestBuf.undo        == NULL);
         CHECK(TestBuf.redo        == NULL);
         CHECK(!strcmp(TestBuf.path, "testdocs/lorem.txt"));
@@ -213,7 +222,7 @@ TEST_SUITE(BufferTests)
         TestBuf.path = "testdocs/lorem.txt";
         buf_reload(&TestBuf);
         CHECK(TestBuf.status      != MODIFIED);
-        CHECK(TestBuf.bufsize     == 61440);
+        CHECK(TestBuf.contents.bufsize     == 61440);
         CHECK(TestBuf.undo        == NULL);
         CHECK(TestBuf.redo        == NULL);
         CHECK(!strcmp(TestBuf.path, "testdocs/lorem.txt"));