diff options
Diffstat (limited to 'bin/edi')
-rw-r--r-- | bin/edi/buffer.c | 13 | ||||
-rw-r--r-- | bin/edi/edi.h | 1 | ||||
-rw-r--r-- | bin/edi/file.c | 22 | ||||
-rw-r--r-- | bin/edi/iter.c | 1 |
4 files changed, 20 insertions, 17 deletions
diff --git a/bin/edi/buffer.c b/bin/edi/buffer.c index 5950317e..b5cd39d6 100644 --- a/bin/edi/buffer.c +++ b/bin/edi/buffer.c @@ -73,11 +73,6 @@ void bufferDelete(struct Buffer *buf) { wchar_t *bufferDest(struct Buffer *buf, size_t len) { if (buf->len + len > buf->cap) { - if (!buf->len) { - struct Block *empty = buf->block; - buf->block = buf->block->prev; - free(empty); - } while (len > buf->cap) buf->cap *= 2; buf->block = blockAlloc(buf->block, buf->cap); buf->len = 0; @@ -89,6 +84,12 @@ wchar_t *bufferDest(struct Buffer *buf, size_t len) { return ptr; } +void bufferTruncate(struct Buffer *buf, size_t len) { + if (len > buf->slice.len) return; + buf->len -= buf->slice.len - len; + buf->slice.len = len; +} + #ifdef TEST #include <assert.h> @@ -159,6 +160,8 @@ int main() { dest[4] = L'E'; dest[5] = L'F'; assert(!wcsncmp(L"ABCDEF", buf.slice.ptr, buf.slice.len)); + bufferTruncate(&buf, 4); + assert(!wcsncmp(L"ABCD", buf.slice.ptr, buf.slice.len)); bufferFree(&buf); } diff --git a/bin/edi/edi.h b/bin/edi/edi.h index 6891b866..644e0901 100644 --- a/bin/edi/edi.h +++ b/bin/edi/edi.h @@ -46,6 +46,7 @@ void bufferInsert(struct Buffer *buf); void bufferAppend(struct Buffer *buf, wchar_t ch); void bufferDelete(struct Buffer *buf); wchar_t *bufferDest(struct Buffer *buf, size_t len); +void bufferTruncate(struct Buffer *buf, size_t len); static const struct Table { size_t cap, len; diff --git a/bin/edi/file.c b/bin/edi/file.c index 55b7d679..85984aee 100644 --- a/bin/edi/file.c +++ b/bin/edi/file.c @@ -25,14 +25,15 @@ #include "edi.h" enum { - BufCap = 8192, + BufferCap = 8192, + TableCap = 2, LogCap = 8, }; struct File fileAlloc(char *path) { struct File file = { .path = path, - .buf = bufferAlloc(BufCap), + .buf = bufferAlloc(BufferCap), .log = logAlloc(LogCap), }; if (!path) logPush(&file.log, TableEmpty); @@ -45,7 +46,7 @@ void fileFree(struct File *file) { free(file->path); } -static const mbstate_t MBStateInit; +static const mbstate_t StateInit; // TODO: Error handling. void fileRead(struct File *file) { @@ -59,22 +60,19 @@ void fileRead(struct File *file) { return; } - struct Table table = tableAlloc(1); - - char buf[BufCap]; - mbstate_t mbState = MBStateInit; + struct Table table = tableAlloc(TableCap); + char buf[BufferCap]; + mbstate_t state = StateInit; while (!feof(stream)) { size_t mbsLen = fread(buf, 1, sizeof(buf), stream); if (ferror(stream)) err(EX_IOERR, "%s", file->path); const char *mbs = buf; - mbstate_t mbLenState = mbState; - size_t wcsLen = mbsnrtowcs(NULL, &mbs, mbsLen, 0, &mbLenState); + wchar_t *wcs = bufferDest(&file->buf, mbsLen); + size_t wcsLen = mbsnrtowcs(wcs, &mbs, mbsLen, mbsLen, &state); if (wcsLen == (size_t)-1) err(EX_DATAERR, "%s", file->path); - wchar_t *wcs = bufferDest(&file->buf, wcsLen); - assert(wcsLen == mbsnrtowcs(wcs, &mbs, mbsLen, wcsLen, &mbState)); - + bufferTruncate(&file->buf, wcsLen); tablePush(&table, file->buf.slice); } logPush(&file->log, table); diff --git a/bin/edi/iter.c b/bin/edi/iter.c index cfbefc89..6331bb17 100644 --- a/bin/edi/iter.c +++ b/bin/edi/iter.c @@ -79,6 +79,7 @@ int main() { assert(L'B' == iter(&table, 1).ch); assert(L'C' == iter(&table, 2).ch); assert(L'D' == iter(&table, 3).ch); + assert(WEOF == iter(&table, 4).ch); assert(L'B' == iterNext(iter(&table, 0)).ch); assert(L'C' == iterNext(iter(&table, 1)).ch); |