diff options
| author | Lieuwe Rooijakkers <lieuwerooijakkers@gmail.com> | 2024-09-29 22:04:15 +0200 | 
|---|---|---|
| committer | Lieuwe Rooijakkers <lieuwerooijakkers@gmail.com> | 2024-09-29 22:04:48 +0200 | 
| commit | fcb4d926fa7b106a60830992148e06f2ebe02ebc (patch) | |
| tree | 03a80e5f603f4acaea939b00b420550515d51db2 | |
| parent | 3db442021a8af00ae0aba842c6ab294d25e9d626 (diff) | |
| -rw-r--r-- | Maakbestand | 2 | ||||
| -rw-r--r-- | src/toilet.c | 78 | 
2 files changed, 69 insertions, 11 deletions
| diff --git a/Maakbestand b/Maakbestand index cf87dd4..d4f3360 100644 --- a/Maakbestand +++ b/Maakbestand @@ -11,7 +11,7 @@ else  endif  CFLAGS += -D_GNU_SOURCE -DDRUKKEDOOS_VERSIE=\"$(VERSION)\"  CFLAGS += -Isrc -I. -LDFLAGS := +LDFLAGS := -lm  OBJDIR := obj  TARGET := drukkedoos 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;  } | 
