summaryrefslogtreecommitdiff
path: root/src/tak.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tak.c')
-rw-r--r--src/tak.c105
1 files changed, 22 insertions, 83 deletions
diff --git a/src/tak.c b/src/tak.c
index e970ae1..e8fb817 100644
--- a/src/tak.c
+++ b/src/tak.c
@@ -6,6 +6,7 @@
#include "util/map.h"
#include "util/versie.h"
+#include "io/read_file.h"
static void usage(FILE *f) {
fprintf(f,
@@ -39,25 +40,20 @@ static char** parse_options(int argc, char **argv) {
return argv + optind;
}
-struct state {
- char *buf;
- size_t sz;
-};
-
-static void process(struct state state) {
+static void process(struct filebuf *fb) {
char *lstart, *lend;
- lend = &state.buf[state.sz - 1];
+ lend = &fb->buf[fb->sz - 1];
- while (lend > state.buf) {
+ while (lend > fb->buf) {
if (*lend == '\n') {
lend--;
}
lstart = lend;
- while (*lstart != '\n' && lstart != state.buf) {
+ while (*lstart != '\n' && lstart != fb->buf) {
lstart--;
}
- if (lstart != state.buf) {
+ if (lstart != fb->buf) {
lstart++;
}
@@ -65,96 +61,39 @@ static void process(struct state state) {
lend = lstart-1;
}
-}
-
-#define CHECK_OOM(ptr) \
- if (ptr == NULL) { \
- fprintf(stderr, "tak: geheugen is op"); \
- /* I think I should free the original memory here, but whatever */ \
- return NULL; \
- }
-static char *read_stream(FILE *stream, size_t *sz) {
- *sz = 0;
- size_t cap = 4096;
- char *res = malloc(cap);
- CHECK_OOM(res);
-
- while (!feof(stream)) {
- if (cap-*sz == 0) {
- cap *= 2;
- res = realloc(res, cap);
- CHECK_OOM(res);
- }
-
- const size_t amount = cap-*sz;
- const size_t n = fread(res+*sz, 1, amount, stream);
- *sz += n;
-
- if (n != amount && !feof(stream)) {
- fprintf(stderr, "tak: fout tijdens lezen van standaard invoer.\n");
- free(res);
- return NULL;
- }
- }
-
- res = realloc(res, *sz);
- return res;
-}
-
-int handleStream(FILE *stream) {
- size_t sz = 0;
- char *data = read_stream(stream, &sz);
- if (data == NULL) {
- return 1;
- }
-
- struct state state = { .buf = data, .sz = sz };
- process(state);
-
- free(data);
- return 0;
-}
-
-int handleFile(char *fname) {
- struct map *map = open_map(fname);
- if (map == NULL) {
- return 1;
- }
-
- struct state state = { .buf = map->addr, .sz = map->sb.st_size };
- process(state);
-
- close_map(map);
-
- return 0;
+ free_filebuf(fb);
}
int entry_tak(int argc, char **argv) {
char **args = parse_options(argc, argv);
if (*args == NULL) {
- handleStream(stdin);
+ struct filebuf *fb = stream_to_filebuf(stdin);
+ if (fb == NULL) {
+ return 1;
+ }
+
+ process(fb);
return 0;
}
while (*args != NULL) {
+ struct filebuf *fb = NULL;
+
if (!strcmp(*args, "-")) {
- handleStream(stdin);
- goto next;
+ fb = stream_to_filebuf(stdin);
+ if (fb == NULL) {
+ return 1;
+ }
}
- if (!handleFile(*args)) {
- goto next;
+ if (fb == NULL) {
+ fb = file_to_filebuf(*args);
}
- FILE *stream = fopen(*args, "rb");
- if (handleStream(stream)) {
- return 1;
- }
- fclose(stream);
+ process(fb);
-next:
args++;
}