summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLieuwe Rooijakkers <lieuwerooijakkers@gmail.com>2024-08-02 22:55:54 +0200
committerLieuwe Rooijakkers <lieuwerooijakkers@gmail.com>2024-08-02 23:04:14 +0200
commitec605bf138a16e62d6398d0bf2a43d2fea2dbe74 (patch)
treed022c838223a063418a38608e7cd8caaf99b54b0 /src
parentf3a540c2383e53b93a82ef76d5bc0ab210a09006 (diff)
toilet: use read_file.h
Diffstat (limited to 'src')
-rw-r--r--src/toilet.c89
1 files 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 <string.h>
#include <sys/types.h>
#include <unistd.h>
+
#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;
}