From 5f10d9b51487c4635a8400e8a86bbd51e221bdd2 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Thu, 22 Nov 2018 22:04:41 -0500 Subject: Add fileWrite for edi --- bin/edi/edi.c | 4 +++- bin/edi/edi.h | 5 +++++ bin/edi/file.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) (limited to 'bin') diff --git a/bin/edi/edi.c b/bin/edi/edi.c index fb6e3929..3a52e228 100644 --- a/bin/edi/edi.c +++ b/bin/edi/edi.c @@ -29,10 +29,12 @@ int main(int argc, char *argv[]) { struct File file = fileAlloc(strdup(argv[1])); fileRead(&file); - const struct Table *table = &file.log.states[file.log.state].table; + const struct Table *table = logTable(&file.log); for (struct Iter it = iter(table, 0); it.ch != WEOF; it = iterNext(it)) { printf("%lc", it.ch); } + fileWrite(&file); + fileFree(&file); } diff --git a/bin/edi/edi.h b/bin/edi/edi.h index 644e0901..ee1fdd4a 100644 --- a/bin/edi/edi.h +++ b/bin/edi/edi.h @@ -82,6 +82,10 @@ struct Log { struct Log logAlloc(size_t cap); void logFree(struct Log *log); void logPush(struct Log *log, struct Table table); +static inline struct Table *logTable(const struct Log *log) { + if (log->state == log->len) return NULL; + return &log->states[log->state].table; +} struct File { char *path; @@ -92,3 +96,4 @@ struct File { struct File fileAlloc(char *path); void fileFree(struct File *file); void fileRead(struct File *file); +void fileWrite(struct File *file); diff --git a/bin/edi/file.c b/bin/edi/file.c index 85984aee..7f9fef45 100644 --- a/bin/edi/file.c +++ b/bin/edi/file.c @@ -14,7 +14,6 @@ * along with this program. If not, see . */ -#include #include #include #include @@ -80,3 +79,34 @@ void fileRead(struct File *file) { fclose(stream); } + +// TODO: Error handling. +void fileWrite(struct File *file) { + if (!file->path) return; + + FILE *stream = fopen(file->path, "w"); + if (!stream) err(EX_CANTCREAT, "%s", file->path); + + const struct Table *table = logTable(&file->log); + if (!table) errx(EX_SOFTWARE, "fileWrite: no table"); + + char buf[BufferCap]; + mbstate_t state = StateInit; + for (size_t i = 0; i < table->len; ++i) { + struct Slice slice = table->slices[i]; + while (slice.len) { + size_t mbsLen = wcsnrtombs( + buf, &slice.ptr, slice.len, sizeof(buf), &state + ); + if (mbsLen == (size_t)-1) err(EX_DATAERR, "%s", file->path); + slice.len -= slice.ptr - table->slices[i].ptr; + + fwrite(buf, 1, mbsLen, stream); + if (ferror(stream)) err(EX_IOERR, "%s", file->path); + } + } + file->clean = file->log.state; + + fclose(stream); + if (ferror(stream)) err(EX_IOERR, "%s", file->path); +} -- cgit 1.4.1