diff options
-rw-r--r-- | src/boom.c | 85 |
1 files changed, 39 insertions, 46 deletions
@@ -1,4 +1,5 @@ #include <dirent.h> +#include <errno.h> #include <fcntl.h> #include <getopt.h> #include <limits.h> @@ -9,66 +10,60 @@ #include <unistd.h> #include "util/versie.h" +#include "util/option.h" static int max_depth = -1; static bool show_hidden = false; static bool dirs_only = false; -static void usage(FILE *f) { - fprintf(f, - "Gebruik: boom [OPTIES]... [STARTPUNTEN]...\n" - "\n" - "Geef inhoud van mapjes weer in een boom-achtig formaat.\n" - "\n" - " -a Alle bestanden worden weergegeven, ook al beginnen ze met een puntje\n" - " -m Geef alleen mapjes weer\n" - " -d DIEPTE Maximale diepte\n" - " -h Toon deze hulptekst\n" - " -V Toon versienummer\n"); -} +static const char *usage_string = + "Gebruik: %s [OPTIES]... [STARTPUNTEN]...\n" + "\n" + "Geef inhoud van mapjes weer in een boom-achtig formaat.\n" + "\n" + " -a Alle bestanden worden weergegeven, ook al beginnen ze met een puntje\n" + " -m Geef alleen mapjes weer\n" + " -d DIEPTE Maximale diepte\n" + " -h Toon deze hulptekst\n" + " -V Toon versienummer\n"; // Returns pointer to argument array containing the starting points static char** parse_options(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "amd:hV")) != -1) { - switch (opt) { - case 'a': - show_hidden = true; - break; - - case 'm': - dirs_only = true; - break; - - case 'd': - max_depth = atoi(optarg); - if (max_depth <= 0) { - fprintf(stderr, "boom: maximale diepte moet groter zijn dan 0\n"); - exit(1); - } - break; - - case 'h': - usage(stdout); - exit(0); - - case 'V': - drukkedoos_print_versie(stdout); - exit(0); - - case '?': - usage(stderr); - exit(1); + char *max_depth_str; + + const struct option_spec spec[] = { + {'a', OPTION_SETBOOL(&show_hidden)}, + {'m', OPTION_SETBOOL(&dirs_only)}, + {'d', OPTION_WITHARG(&max_depth_str)}, + {'h', OPTION_HELPUSAGE(usage_string)}, + {'V', OPTION_VERSION()}, + OPTION_SPEC_END + }; + + char **rest = option_parse(argc, argv, spec); + + if (max_depth_str != NULL) { + errno = 0; + max_depth = strtol(max_depth_str, NULL, 10); + if (errno != 0) { + fprintf(stderr, "boom: maximale diepte moet een getal zijn\n"); + exit(1); + } + if (max_depth <= 0) { + fprintf(stderr, "boom: maximale diepte moet groter zijn dan 0\n"); + exit(1); } } - return argv + optind; + return rest; } static int scandir_filterfunc(const struct dirent *ent) { if (dirs_only && ent->d_type != DT_DIR) return 0; if (!show_hidden && ent->d_name[0] == '.') return 0; + if (strcmp(ent->d_name, ".") == 0) return 0; + if (strcmp(ent->d_name, "..") == 0) return 0; return 1; } @@ -136,9 +131,7 @@ static void boom(int parentdirfd, const char *dirname, unsigned depth) { print_prefix(depth); if (list[i]->d_type == DT_LNK) { - ssize_t len = parentdirfd == -1 - ? readlink(list[i]->d_name, linknamebuf, PATH_MAX - 1) - : readlinkat(dirfd, list[i]->d_name, linknamebuf, PATH_MAX - 1); + ssize_t len = readlinkat(dirfd, list[i]->d_name, linknamebuf, PATH_MAX - 1); if (len == -1) { printf("%s -> [kon niet leeslinken]\n", list[i]->d_name); } else { |