From ec605bf138a16e62d6398d0bf2a43d2fea2dbe74 Mon Sep 17 00:00:00 2001 From: Lieuwe Rooijakkers Date: Fri, 2 Aug 2024 22:55:54 +0200 Subject: toilet: use read_file.h --- src/toilet.c | 89 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/src/toilet.c b/src/toilet.c index 10c7510..b1da9f1 100644 --- a/src/toilet.c +++ b/src/toilet.c @@ -8,11 +8,14 @@ #include #include #include + #include "util/versie.h" #include "util/error.h" #include "util/debug.h" #include "util/map.h" +#include "io/read_file.h" + static void usage(FILE *f) { fprintf(f, "Gebruik: toilet [-nchV] [BESTAND]...\n" @@ -67,21 +70,21 @@ static char** parse_options(int argc, char **argv, int *modeMap) { return argv + optind; } -size_t get_count(enum MODE mode, struct map *map) { +size_t get_count(enum MODE mode, struct filebuf *fb) { switch (mode) { case M_BYTES: - return map->sb.st_size; + return fb->sz; case M_WORDS: { size_t words = 0; - assert(map->sb.st_size >= 0); + assert(fb->sz >= 0); // (c) Tom Forging - for (size_t i = 0; i < (size_t)map->sb.st_size;) { + for (size_t i = 0; i < (size_t)fb->sz;) { size_t previ = i; - while (!isspace(map->addr[i])) i++; + while (!isspace(fb->buf[i])) i++; words += i != previ; - while (isspace(map->addr[i])) i++; + while (isspace(fb->buf[i])) i++; } return words; @@ -89,15 +92,15 @@ size_t get_count(enum MODE mode, struct map *map) { case M_LINES: { size_t lines = 0; - char *ptr = map->addr; + size_t i = 0; - while (ptr != map->end) { - if (*ptr == '\n') lines++; - ptr++; + while (i != fb->sz) { + if (fb->buf[i] == '\n') lines++; + i++; } // handle case if file does not have trailing newline - if (*(ptr - 1) != '\n') { + if (fb->buf[i - 1] != '\n') { lines++; } @@ -109,6 +112,20 @@ size_t get_count(enum MODE mode, struct map *map) { } } +static void process(char *fname, struct filebuf *fb, int modeMap) { + for (enum MODE mode = 1; mode <= M_BYTES; mode <<= 1) { + if (mode & modeMap) { + const size_t count = get_count(mode, fb); + printf("%li ", count); + } + } + printf("%s\n", fname); + free_filebuf(fb); +} + +// TODO: be smarter, toilet doesn't have to read the whole file in memory (for +// unmappable files) + int entry_toilet(int argc, char **argv) { int modeMap = 0; char **args = parse_options(argc, argv, &modeMap); @@ -116,30 +133,44 @@ int entry_toilet(int argc, char **argv) { modeMap = INT_MAX; } - while (*args != NULL) { - bool isdir; - struct map *map = open_map(*args, &isdir); - if (map == NULL && !isdir) { - fprintf(stderr, "toilet: fout bij lezen bestand '%s'\n", *args); - return 1; - } else if (isdir) { - fprintf(stderr, "toilet: %s: is een mapje\n", *args); - goto next; - } + if (*args == NULL) { + struct filebuf *fb = stream_to_filebuf(stdin, 0); + if (fb == NULL) goto err_stdin; - for (enum MODE mode = 1; mode <= M_BYTES; mode <<= 1) { - if (mode & modeMap) { - const size_t count = get_count(mode, map); - printf("%li ", count); - } + process("", fb, modeMap); + return 0; + } + + while (*args != NULL) { + struct filebuf *fb = NULL; + + if (!strcmp(*args, "-")) { + fb = stream_to_filebuf(stdin, 0); + if (fb == NULL) goto err_stdin; + *args = ""; // no filename when stdin + } else { + bool isdir = false; + fb = file_to_filebuf(*args, 0, &isdir); + if (isdir) goto err_isdir; + else if (fb == NULL) goto err_file; } - printf("%s\n", *args); - close_map(map); + process(*args, fb, modeMap); -next: args++; } return 0; + +err_stdin: + fprintf(stderr, "toilet: fout bij lezen van standaard invoer\n"); + return 1; + +err_file: + fprintf(stderr, "toilet: fout bij lezen van bestand\n"); + return 1; + +err_isdir: + fprintf(stderr, "toilet: bestand '%s' is een mapje\n", *args); + return 1; } -- cgit v1.2.3-70-g09d2