From c4f21492915b9f53eb431b0cc4b771a144b2320e Mon Sep 17 00:00:00 2001 From: Masahiko AMANO Date: Thu, 29 Dec 2022 18:35:01 +0300 Subject: [PATCH] feat(cli)!: significant interface improvements --- cli/cli.c | 314 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 165 insertions(+), 149 deletions(-) diff --git a/cli/cli.c b/cli/cli.c index c532c6a..5f3d965 100644 --- a/cli/cli.c +++ b/cli/cli.c @@ -47,21 +47,26 @@ void print_tanzaku_all() { } // Sasa view menu handler -int menu_view_sasa() { - char input[16]; - printf(HIGHLIGHT("Enter sasa ID: ")); - fgets(input, 16, stdin); +int menu_view_sasa(const char *arg) { + if (arg == NULL) { + return 1; + } + if (strcmp(arg, ".") == 0) { + print_sasa_all(); + return 0; + } char *endptr; - uint64_t sasa_id = strtoull(input, &endptr, 16); - if (*input != '\n' && *endptr == '\n') { + uint64_t sasa_id = strtoull(arg, &endptr, 16); + if (*endptr == 0) { Sasa current_sasa = tanabata_sasa_get_by_id(&tanabata, sasa_id); if (current_sasa.id != HOLE_ID) { char datetime[20]; strftime(datetime, 20, DT_FORMAT, localtime((const time_t *) ¤t_sasa.created_ts)); - printf(HIGHLIGHT("File path")" %s\n" + printf(HIGHLIGHT("Sasa ID")" %lx\n" + HIGHLIGHT("File path")" %s\n" HIGHLIGHT("Added datetime")" %s\n", - current_sasa.path, datetime); + sasa_id, current_sasa.path, datetime); Tanzaku *related_tanzaku = tanabata_tanzaku_get_by_sasa(&tanabata, current_sasa.id); if (related_tanzaku != NULL) { printf(HIGHLIGHT("\n↓ Related tanzaku ↓\n")); @@ -83,24 +88,33 @@ int menu_view_sasa() { } // Tanzaku view menu handler -int menu_view_tanzaku() { - char input[16]; - printf(HIGHLIGHT("Enter tanzaku ID: ")); - fgets(input, 16, stdin); +int menu_view_tanzaku(const char *arg) { + if (arg == NULL) { + return 1; + } + if (strcmp(arg, ".") == 0) { + print_tanzaku_all(); + return 0; + } char *endptr; - uint64_t tanzaku_id = strtoull(input, &endptr, 16); - if (*input != '\n' && *endptr == '\n') { + uint64_t tanzaku_id = strtoull(arg, &endptr, 16); + if (*endptr == 0) { Tanzaku current_tanzaku = tanabata_tanzaku_get_by_id(&tanabata, tanzaku_id); if (current_tanzaku.id != HOLE_ID) { char datetime[20]; strftime(datetime, 20, DT_FORMAT, localtime((const time_t *) ¤t_tanzaku.created_ts)); - printf(HIGHLIGHT("Name")" %s\n" - HIGHLIGHT("Created datetime")" %s\n" - HIGHLIGHT("\n↓ Description ↓\n") - "%s\n" - HIGHLIGHT("↑ Description ↑\n"), - current_tanzaku.name, datetime, current_tanzaku.description); + printf(HIGHLIGHT("Tanzaku ID")" %lx\n" + HIGHLIGHT("Name")" %s\n" + HIGHLIGHT("Created datetime")" %s\n\n", + tanzaku_id, current_tanzaku.name, datetime); + if (*current_tanzaku.description != 0) { + printf(HIGHLIGHT("↓ Description ↓\n") + "%s\n" + HIGHLIGHT("↑ Description ↑\n"), current_tanzaku.description); + } else { + printf(HIGHLIGHT("No description\n")); + } Sasa *related_sasa = tanabata_sasa_get_by_tanzaku(&tanabata, tanzaku_id); if (related_sasa != NULL) { printf(HIGHLIGHT("\n↓ Related sasa ↓\n")); @@ -122,95 +136,95 @@ int menu_view_tanzaku() { } // Sasa add menu handler -int menu_add_sasa() { +int menu_add_sasa(const char *arg) { + if (arg == NULL) { + return 1; + } if (tanabata.sasahyou.size == -1 && tanabata.sasahyou.hole_cnt == 0) { fprintf(stderr, ERROR("Failed to add file to database: sasahyou is full\n")); return 1; } - char path[4096]; - printf(HIGHLIGHT("Enter file path: ")); - fgets(path, 4096, stdin); - if (*path != '\n') { - path[strlen(path) - 1] = 0; - if (tanabata_sasa_add(&tanabata, path) == 0) { - if (tanabata_save(&tanabata) == 0) { - printf(SUCCESS("Successfully added file to database\n")); - return 0; - } - } - fprintf(stderr, ERROR("Failed to add file to database\n")); - return 1; + if (tanabata_sasa_add(&tanabata, arg) == 0 && + tanabata_save(&tanabata) == 0) { + printf(SUCCESS("Successfully added file to database\n")); + return 0; } + fprintf(stderr, ERROR("Failed to add file to database\n")); return 1; } // Tanzaku add menu handler -int menu_add_tanzaku() { +int menu_add_tanzaku(const char *arg) { + if (arg == NULL) { + return 1; + } if (tanabata.sappyou.size == -1 && tanabata.sappyou.hole_cnt == 0) { fprintf(stderr, ERROR("Failed to add tanzaku: sappyou is full\n")); return 1; } - char name[4096]; - char description[4096]; - printf(HIGHLIGHT("Enter tanzaku name: ")); - fgets(name, 4096, stdin); - printf(HIGHLIGHT("Enter tanzaku description: ")); - fgets(description, 4096, stdin); - if (*name != '\n') { - name[strlen(name) - 1] = 0; + if (*arg != 0) { + char description[4096]; + printf(HIGHLIGHT("Enter tanzaku description: ")); + fgets(description, 4096, stdin); description[strlen(description) - 1] = 0; - if (tanabata_tanzaku_add(&tanabata, name, description) == 0) { - if (tanabata_save(&tanabata) == 0) { - printf(SUCCESS("Successfully added tanzaku to database\n")); - return 0; - } + if (tanabata_tanzaku_add(&tanabata, arg, description) == 0 && + tanabata_save(&tanabata) == 0) { + printf(SUCCESS("Successfully added tanzaku to database\n")); + return 0; } - fprintf(stderr, ERROR("Failed to add tanzaku to database\n")); - return 1; } + fprintf(stderr, ERROR("Failed to add tanzaku to database\n")); return 1; } // Kazari add menu handler -int menu_add_kazari() { +int menu_add_kazari(char *arg) { + if (arg == NULL) { + return 1; + } if (tanabata.shoppyou.size == -1 && tanabata.shoppyou.hole_cnt == 0) { fprintf(stderr, ERROR("Failed to add kazari: shoppyou is full\n")); return 1; } - char input[16]; - printf(HIGHLIGHT("Enter sasa ID: ")); - fgets(input, 16, stdin); - char *endptr; - uint64_t sasa_id = strtoull(input, &endptr, 16); - if (*input == '\n' || *endptr != '\n') { - fprintf(stderr, ERROR("Invalid ID\n")); - return 1; - } - printf(HIGHLIGHT("Enter tanzaku ID: ")); - fgets(input, 16, stdin); - uint64_t tanzaku_id = strtoull(input, &endptr, 16); - if (*input == '\n' || *endptr != '\n') { - fprintf(stderr, ERROR("Invalid ID\n")); - return 1; - } - if (tanabata_kazari_add(&tanabata, sasa_id, tanzaku_id) == 0) { - if (tanabata_save(&tanabata) == 0) { - printf(SUCCESS("Successfully added kazari\n")); - return 0; + char *left = arg, *right = "\0", *endptr; + for (size_t i = 0; i < strlen(arg); i++) { + if (arg[i] == '-') { + arg[i] = 0; + right = arg + i + 1; + break; } } + if (*left == 0 || *right == 0) { + fprintf(stderr, ERROR("Failed to add kazari: invalid argument\n")); + return 1; + } + uint64_t sasa_id = strtoull(left, &endptr, 16); + if (*endptr != 0) { + fprintf(stderr, ERROR("Failed to add kazari: invalid sasa ID\n")); + return 1; + } + uint64_t tanzaku_id = strtoull(right, &endptr, 16); + if (*endptr != 0) { + fprintf(stderr, ERROR("Failed to add kazari: invalid tanzaku ID\n")); + return 1; + } + if (tanabata_kazari_add(&tanabata, sasa_id, tanzaku_id) == 0 && + tanabata_save(&tanabata) == 0) { + printf(SUCCESS("Successfully added kazari\n")); + return 0; + } fprintf(stderr, ERROR("Failed to add kazari\n")); return 1; } // Sasa remove menu handler -int menu_rem_sasa() { - char input[16]; - printf(HIGHLIGHT("Enter sasa ID: ")); - fgets(input, 16, stdin); +int menu_rem_sasa(const char *arg) { + if (arg == NULL) { + return 1; + } char *endptr; - uint64_t sasa_id = strtoull(input, &endptr, 16); - if (*input != '\n' && *endptr == '\n') { + uint64_t sasa_id = strtoull(arg, &endptr, 16); + if (*endptr == 0) { if (tanabata_sasa_rem_by_id(&tanabata, sasa_id) == 0 && tanabata_save(&tanabata) == 0) { printf(SUCCESS("Successfully removed sasa\n")); @@ -224,13 +238,13 @@ int menu_rem_sasa() { } // Tanzaku remove menu handler -int menu_rem_tanzaku() { - char input[16]; - printf(HIGHLIGHT("Enter tanzaku ID: ")); - fgets(input, 16, stdin); +int menu_rem_tanzaku(const char *arg) { + if (arg == NULL) { + return 1; + } char *endptr; - uint64_t tanzaku_id = strtoull(input, &endptr, 16); - if (*input != '\n' && *endptr == '\n') { + uint64_t tanzaku_id = strtoull(arg, &endptr, 16); + if (*endptr == 0) { if (tanabata_tanzaku_rem_by_id(&tanabata, tanzaku_id) == 0 && tanabata_save(&tanabata) == 0) { printf(SUCCESS("Successfully removed tanzaku\n")); @@ -244,21 +258,30 @@ int menu_rem_tanzaku() { } // Kazari remove menu handler -int menu_rem_kazari() { - char input[16]; - printf(HIGHLIGHT("Enter sasa ID: ")); - fgets(input, 16, stdin); - char *endptr; - uint64_t sasa_id = strtoull(input, &endptr, 16); - if (*input == '\n' || *endptr != '\n') { - fprintf(stderr, "Invalid ID\n"); +int menu_rem_kazari(char *arg) { + if (arg == NULL) { return 1; } - printf(HIGHLIGHT("Enter tanzaku ID: ")); - fgets(input, 16, stdin); - uint64_t tanzaku_id = strtoull(input, &endptr, 16); - if (*input == '\n' || *endptr != '\n') { - fprintf(stderr, "Invalid ID\n"); + char *left = arg, *right = "\0", *endptr; + for (size_t i = 0; i < strlen(arg); i++) { + if (arg[i] == '-') { + arg[i] = 0; + right = arg + i + 1; + break; + } + } + if (*left == 0 || *right == 0) { + fprintf(stderr, ERROR("Failed to remove kazari: invalid argument\n")); + return 1; + } + uint64_t sasa_id = strtoull(left, &endptr, 16); + if (*endptr != 0) { + fprintf(stderr, ERROR("Failed to remove kazari: invalid sasa ID\n")); + return 1; + } + uint64_t tanzaku_id = strtoull(right, &endptr, 16); + if (*endptr != 0) { + fprintf(stderr, ERROR("Failed to remove kazari: invalid tanzaku ID\n")); return 1; } if (tanabata_kazari_rem(&tanabata, sasa_id, tanzaku_id) == 0 && @@ -275,17 +298,6 @@ int main(int argc, char **argv) { fprintf(stderr, ERROR("No options provided\n")); return 1; } - const char *shortopts = "hI:O:isuaftkwV"; - char *abspath = NULL; - int opt; - _Bool opt_i = 0; - _Bool opt_a = 0; - _Bool opt_s = 0; - _Bool opt_u = 0; - _Bool opt_f = 0; - _Bool opt_t = 0; - _Bool opt_k = 0; - _Bool opt_w = 0; char *tanabata_path; FILE *config = fopen("/etc/tfm/config", "r"); if (config == NULL) { @@ -318,6 +330,19 @@ int main(int argc, char **argv) { } } } + const char *shortopts = "hI:O:isuf:t:c:wV"; + char *abspath = NULL; + int opt; + _Bool opt_i = 0; + _Bool opt_s = 0; + _Bool opt_u = 0; + _Bool opt_f = 0; + _Bool opt_t = 0; + _Bool opt_c = 0; + _Bool opt_w = 0; + char *opt_f_arg; + char *opt_t_arg; + char *opt_c_arg; while ((opt = getopt(argc, argv, shortopts)) != -1) { switch (opt) { case 'h': @@ -326,18 +351,18 @@ int main(int argc, char **argv) { HIGHLIGHT("Usage:\n") "tfm \n\n" HIGHLIGHT("Options:\n") - HIGHLIGHT("-h")" Print this help and exit\n" - HIGHLIGHT("-I ")" Initialize new Tanabata database in directory \n" - HIGHLIGHT("-O ")" Open existing Tanabata database from directory \n" - HIGHLIGHT("-i")" View database info\n" - HIGHLIGHT("-a")" View all\n" - HIGHLIGHT("-s")" Set or add\n" - HIGHLIGHT("-u")" Unset or remove\n" - HIGHLIGHT("-f")" File-sasa menu\n" - HIGHLIGHT("-t")" Tanzaku menu\n" - HIGHLIGHT("-k")" Kazari menu (can only be used with the '-s' or '-u' option)\n" - HIGHLIGHT("-w")" Weed (defragment) database\n" - HIGHLIGHT("-V")" Print version and exit\n\n" + HIGHLIGHT("-h")" Print this help and exit\n" + HIGHLIGHT("-I ")" Initialize new Tanabata database in directory \n" + HIGHLIGHT("-O ")" Open existing Tanabata database from directory \n" + HIGHLIGHT("-i")" View database info\n" + HIGHLIGHT("-s")" Set or add\n" + HIGHLIGHT("-u")" Unset or remove\n" + HIGHLIGHT("-f ")" File-sasa menu\n" + HIGHLIGHT("-t ")" Tanzaku menu\n" + HIGHLIGHT( + "-c -")" Kazari menu (can only be used with the '-s' or '-u' option)\n" + HIGHLIGHT("-w")" Weed (defragment) database\n" + HIGHLIGHT("-V")" Print version and exit\n\n" ); if (tanabata_path != NULL) { printf(HIGHLIGHT("Current database location: %s\n"), tanabata_path); @@ -392,23 +417,23 @@ int main(int argc, char **argv) { case 'i': opt_i = 1; break; - case 'a': - opt_a = 1; - break; case 's': opt_s = 1; break; case 'u': - opt_u = -1; + opt_u = 1; break; case 'f': opt_f = 1; + opt_f_arg = optarg; break; case 't': opt_t = 1; + opt_t_arg = optarg; break; - case 'k': - opt_k = 1; + case 'c': + opt_c = 1; + opt_c_arg = optarg; break; case 'w': opt_w = 1; @@ -427,10 +452,6 @@ int main(int argc, char **argv) { fprintf(stderr, ERROR("Failed to load database\n")); return 1; } - if (opt_s && opt_u) { - opt_s = 0; - opt_u = 0; - } fclose(config); if (opt_i) { char datetime[20]; @@ -475,41 +496,36 @@ int main(int argc, char **argv) { fprintf(stderr, ERROR("Failed to weed database\n")); return 1; } - if (opt_a) { + if (opt_s && opt_u) { + opt_s = 0; + opt_u = 0; + } + if (opt_s) { if (opt_f) { - print_sasa_all(); - return 0; + return menu_add_sasa(opt_f_arg); } if (opt_t) { - print_tanzaku_all(); - return 0; + return menu_add_tanzaku(opt_t_arg); } - } else if (opt_s) { - if (opt_f) { - return menu_add_sasa(); - } - if (opt_t) { - return menu_add_tanzaku(); - } - if (opt_k) { - return menu_add_kazari(); + if (opt_c) { + return menu_add_kazari(opt_c_arg); } } else if (opt_u) { if (opt_f) { - return menu_rem_sasa(); + return menu_rem_sasa(opt_f_arg); } if (opt_t) { - return menu_rem_tanzaku(); + return menu_rem_tanzaku(opt_t_arg); } - if (opt_k) { - return menu_rem_kazari(); + if (opt_c) { + return menu_rem_kazari(opt_c_arg); } } else { if (opt_f) { - return menu_view_sasa(); + return menu_view_sasa(opt_f_arg); } if (opt_t) { - return menu_view_tanzaku(); + return menu_view_tanzaku(opt_t_arg); } } return 0;