summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/boom.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/src/boom.c b/src/boom.c
index d4829ef..266180c 100644
--- a/src/boom.c
+++ b/src/boom.c
@@ -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 {