summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLieuwe Rooijakkers <lieuwerooijakkers@gmail.com>2024-09-29 22:04:15 +0200
committerLieuwe Rooijakkers <lieuwerooijakkers@gmail.com>2024-09-29 22:04:48 +0200
commitfcb4d926fa7b106a60830992148e06f2ebe02ebc (patch)
tree03a80e5f603f4acaea939b00b420550515d51db2 /src
parent3db442021a8af00ae0aba842c6ab294d25e9d626 (diff)
toilet: use minimal required paddingHEADmaster
Diffstat (limited to 'src')
-rw-r--r--src/toilet.c78
1 files changed, 68 insertions, 10 deletions
diff --git a/src/toilet.c b/src/toilet.c
index c66896a..6d95427 100644
--- a/src/toilet.c
+++ b/src/toilet.c
@@ -2,6 +2,7 @@
#include <ctype.h>
#include <getopt.h>
#include <limits.h>
+#include <tgmath.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -19,8 +20,13 @@
static int modeMap;
-// lines, words, bytes
-static size_t totals[3] = {0};
+struct finfo {
+ size_t values[3];
+ char *fname;
+};
+static struct finfo *finfo = NULL;
+static size_t finfolen = 0;
+static size_t finfocap = 0;
static void usage(FILE *f) {
fprintf(f,
@@ -132,16 +138,41 @@ static int mlog2(int val) {
#undef C
}
+static void init_finfo(int argc) {
+ assert(finfo == NULL);
+ argc += 1; // one more for the total tally
+ if (argc < 8) argc = 8;
+
+ finfo = calloc(argc, sizeof(struct finfo));
+ finfocap = argc;
+}
+
+static struct finfo *add_fname(char *fname) {
+ assert(finfo != NULL);
+
+ if (finfolen == finfocap) {
+ finfocap *= 2;
+ finfo = realloc(finfo, sizeof(struct finfo)*finfocap);
+ }
+
+ struct finfo *ptr = finfo + finfolen;
+ ptr->values[0] = 0;
+ ptr->values[1] = 0;
+ ptr->values[2] = 0;
+ ptr->fname = fname;
+
+ finfolen++;
+ return ptr;
+}
+
static int process(struct filebuf *fb, char *fname, bool) {
+ struct finfo *finfo = add_fname(fname);
+
for (enum MODE mode = 1; mode <= M_BYTES; mode <<= 1) {
if (mode & modeMap) {
- const size_t count = get_count(mode, fb);
- printf("% 10li ", count);
-
- totals[mlog2(mode)] += count;
+ finfo->values[mlog2(mode)] = get_count(mode, fb);
}
}
- printf("%s\n", fname);
free_filebuf(fb);
return 0;
}
@@ -150,6 +181,8 @@ static int process(struct filebuf *fb, char *fname, bool) {
// unmappable files)
int entry_toilet(int argc, char **argv) {
+ init_finfo(argc);
+
modeMap = 0;
char **args = parse_options(argc, argv, &modeMap);
if (modeMap == 0) {
@@ -158,10 +191,35 @@ int entry_toilet(int argc, char **argv) {
const int res = loop_files(args, process);
- for (size_t i = 0; i < 3; i++) {
- printf("% 10li ", totals[i]);
+ // tally file totals
+ {
+ struct finfo *ptr = add_fname("total");
+
+ for (size_t i = 0; i < 3; i++) {
+ for (size_t j = 0; j < finfolen; j++) {
+ ptr->values[i] += finfo[j].values[i];
+ }
+ }
}
- puts("totaal");
+
+ // calculate required padding
+ int pad[3] = {0};
+ for (size_t i = 0; i < finfolen; i++) {
+ for (size_t j = 0; j < 3; j++) {
+ const int sz = ceill(log10l(finfo[i].values[j])) + 1;
+ if (sz > pad[j]) pad[j] = sz;
+ }
+ }
+
+ // print all results
+ for (size_t i = 0; i < finfolen; i++) {
+ struct finfo *ptr = finfo + i;
+ for (size_t j = 0; j < 3; j++) {
+ printf("% *li ", pad[j], ptr->values[j]);
+ }
+ printf("%s\n", ptr->fname);
+ }
+
return res;
}