From 3bb50ffb5b72a0ca00846972e0ed90324a23b349 Mon Sep 17 00:00:00 2001 From: Sigmanificient Date: Wed, 24 Apr 2024 01:40:11 +0200 Subject: [PATCH 1/4] Migrate ls command to getopt --- src/ls/ls_main.c | 71 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/src/ls/ls_main.c b/src/ls/ls_main.c index d50813a..e28cdff 100644 --- a/src/ls/ls_main.c +++ b/src/ls/ls_main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,21 +9,65 @@ #define VERSION "1.0.0" #define AUTHOR "Yohann Boniface (Sigmanificient)" +#include "cgetopt.h" #include "version_info.h" -static const char FLAGLIST[] = "alRdrt"; static char DEFAULT_LOCATION[] = "."; +enum { + GETOPT_VERSION_CHAR = (CHAR_MIN - 1), + GETOPT_SORT_CHAR = (CHAR_MIN - 2), +}; + +static const struct option LONG_OPTIONS[] = { + {"version", no_argument, NULL, GETOPT_VERSION_CHAR}, + {"all", no_argument, NULL, 'a'}, + {"recursive", no_argument, NULL, 'R'}, + {"directory", no_argument, NULL, 'd'}, + {"reverse", no_argument, NULL, 'r'}, + {"sort", required_argument, NULL, GETOPT_SORT_CHAR}, + {0}}; + static char compose_flaglist(int argc, char **argv) { - int flags = 0; + char flags = 0; + int oi = -1; - for (int i = 1; i < argc; i++) { - if (argv[i][0] != '-' || argv[i][1] == '\0') - continue; - for (int j = 1; argv[i][j] != '\0'; j++) - flags |= 1 << (stridx(FLAGLIST, argv[i][j]) + 1); + for (;;) { + int c = getopt_long(argc, argv, "alRdrt", LONG_OPTIONS, &oi); + + if (c == -1) + return flags; + switch (c) { + case 'a': + flags |= F_ALL_FILES; + break; + case 'l': + flags |= F_LONG_FORM; + break; + case 'R': + flags |= F_RECURSIVE; + break; + case 'd': + flags |= F_DIRECTORY; + break; + case 'r': + flags |= F_REV_ORDER; + break; + case 't': + flags |= F_SORT_TIME; + break; + case (CHAR_MAX + 1): + if (!strcmp(optarg, "time")) + flags |= F_SORT_TIME; + break; + case GETOPT_VERSION_CHAR: + print_version(); + return -1; + default: + fprintf(stderr, "ls: invalid option -- '%c'\n", c); + return -2; + } } - return (char)(flags >> 1); } static size_t count_targets(int argc, char **argv) { @@ -55,15 +100,11 @@ static bool list_dirs(dirbuff_t *db, int argc, char **argv, char flags) { int main(int argc, char **argv) { dirbuff_t db = {.size = MIN_ALLOCATED_ENTRY}; - char flags; + char flags = compose_flaglist(argc, argv); int err = 0; - for (int i = 0; argv[i] != NULL; i++) - if (!strcmp(argv[i], "--version")) { - print_version(); - return EXIT_SUCCESS; - } - flags = compose_flaglist(argc, argv); + if (flags < 0) + return (flags == -1) ? EXIT_SUCCESS : EXIT_FAILURE; db.entries = malloc(db.size * sizeof(*db.entries)); if (db.entries == NULL) return EXIT_FAILURE; From f50ebba671e923513e01d739e8c23ae9832235ab Mon Sep 17 00:00:00 2001 From: Sigmanificient Date: Wed, 24 Apr 2024 02:13:01 +0200 Subject: [PATCH 2/4] Fix directory listing loop by offsetting argv properly --- src/ls/ls_main.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/ls/ls_main.c b/src/ls/ls_main.c index e28cdff..1229116 100644 --- a/src/ls/ls_main.c +++ b/src/ls/ls_main.c @@ -70,24 +70,17 @@ static char compose_flaglist(int argc, char **argv) { } } -static size_t count_targets(int argc, char **argv) { - int count = 0; - - for (int i = 1; i < argc; i++) - if (argv[i][0] != '-' || argv[i][1] == '\0') - count++; - return count; -} - static bool list_dirs(dirbuff_t *db, int argc, char **argv, char flags) { int err = 0; - size_t count = count_targets(argc, argv); + size_t count = argc - optind; if (count == 0) { db->name = DEFAULT_LOCATION; err |= list_dir(db, flags); } - for (int i = 1; i < argc; i++) { + argv += optind; + argc -= optind; + for (int i = 0; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] != '\0') continue; db->name = argv[i]; From 752e6b7de6f07d7cb85cc48f59745a4a2938b2af Mon Sep 17 00:00:00 2001 From: Sigmanificient Date: Wed, 24 Apr 2024 02:14:36 +0200 Subject: [PATCH 3/4] Improve getopt_long call --- src/ls/ls_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ls/ls_main.c b/src/ls/ls_main.c index 1229116..aacf2b9 100644 --- a/src/ls/ls_main.c +++ b/src/ls/ls_main.c @@ -30,10 +30,9 @@ static const struct option LONG_OPTIONS[] = { static char compose_flaglist(int argc, char **argv) { char flags = 0; - int oi = -1; for (;;) { - int c = getopt_long(argc, argv, "alRdrt", LONG_OPTIONS, &oi); + int c = getopt_long(argc, argv, "alRdrt", LONG_OPTIONS, NULL); if (c == -1) return flags; @@ -49,6 +48,7 @@ static char compose_flaglist(int argc, char **argv) { break; case 'd': flags |= F_DIRECTORY; + flags &= ~F_RECURSIVE; break; case 'r': flags |= F_REV_ORDER; @@ -101,8 +101,6 @@ int main(int argc, char **argv) { db.entries = malloc(db.size * sizeof(*db.entries)); if (db.entries == NULL) return EXIT_FAILURE; - if (flags & F_DIRECTORY) - flags &= ~F_RECURSIVE; err |= !list_dirs(&db, argc, argv, flags); free(db.entries); return err ? EXIT_SUCCESS : EXIT_FAILURE; From 0f3f56effe2f010dc4c2fb048e03c3db25c3e148 Mon Sep 17 00:00:00 2001 From: Sigmanificient Date: Wed, 24 Apr 2024 02:41:02 +0200 Subject: [PATCH 4/4] Use while c != -1 loop pattern --- src/ls/ls_main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ls/ls_main.c b/src/ls/ls_main.c index aacf2b9..5b061ab 100644 --- a/src/ls/ls_main.c +++ b/src/ls/ls_main.c @@ -30,12 +30,9 @@ static const struct option LONG_OPTIONS[] = { static char compose_flaglist(int argc, char **argv) { char flags = 0; + int c; - for (;;) { - int c = getopt_long(argc, argv, "alRdrt", LONG_OPTIONS, NULL); - - if (c == -1) - return flags; + while ((c = getopt_long(argc, argv, "alRdrt", LONG_OPTIONS, NULL)) != -1) { switch (c) { case 'a': flags |= F_ALL_FILES; @@ -68,6 +65,7 @@ static char compose_flaglist(int argc, char **argv) { return -2; } } + return flags; } static bool list_dirs(dirbuff_t *db, int argc, char **argv, char flags) {