#include <sys/stat.h>
#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)
{
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);
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);
}
}
}
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));
}
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')
{
/* 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;
/* 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;
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++)) )
{
}
}
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;
{
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);
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;
{
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;
}
}
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;
}
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;
--- /dev/null
+#include <stdc.h>
+#include <dbc.h>
+#include <utf.h>
+#include <edit.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#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;
+}