summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tak.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/src/tak.c b/src/tak.c
index 64a07a7..3aa4d84 100644
--- a/src/tak.c
+++ b/src/tak.c
@@ -1,3 +1,4 @@
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -38,25 +39,25 @@ static char** parse_options(int argc, char **argv) {
return argv + optind;
}
-static void process(const char *fname) {
- struct map *map = open_map(fname);
- if (map == NULL) {
- exit(1);
- }
+struct state {
+ char *buf;
+ size_t sz;
+};
+static void process(struct state state) {
char *lstart, *lend;
- lend = &map->addr[map->sb.st_size - 1];
+ lend = &state.buf[state.sz - 1];
- while (lend > map->addr) {
+ while (lend > state.buf) {
if (*lend == '\n') {
lend--;
}
lstart = lend;
- while (*lstart != '\n' && lstart != map->addr) {
+ while (*lstart != '\n' && lstart != state.buf) {
lstart--;
}
- if (lstart != map->addr) {
+ if (lstart != state.buf) {
lstart++;
}
@@ -64,18 +65,53 @@ static void process(const char *fname) {
lend = lstart-1;
}
+}
+
+static char *read_stdin(size_t *sz) {
+ const size_t CHUNK_SIZE = 4096;
+
+ size_t cap = CHUNK_SIZE;
+ char *res = malloc(cap);
+
+ while (!feof(stdin)) {
+ if (cap-*sz < CHUNK_SIZE) {
+ cap *= 2;
+ res = realloc(res, cap);
+ }
+
+ const size_t n = fread(res+*sz, 1, CHUNK_SIZE, stdin);
+ *sz += n;
+
+ if (n != CHUNK_SIZE && !feof(stdin)) {
+ fprintf(stderr, "tak: fout tijdens lezen van standaard invoer.\n");
+ exit(1);
+ }
+ }
- close_map(map);
+ return res;
}
int entry_tak(int argc, char **argv) {
char **args = parse_options(argc, argv);
if (*args == NULL) {
- fprintf(stderr, "tak: Standaard invoer niet ondersteund in deze projectie-gebaseerde implementatie\n");
- return 1;
+ size_t sz = 0;
+ char *data = read_stdin(&sz);
+
+ struct state state = { .buf = data, .sz = sz };
+ process(state);
+
+ free(data);
} else {
while (*args != NULL) {
- process(*args);
+ struct map *map = open_map(*args);
+ if (map == NULL) {
+ return 1;
+ }
+
+ struct state state = { .buf = map->addr, .sz = map->sb.st_size };
+ process(state);
+
+ close_map(map);
args++;
}
}