From 31388f077df63a7fc887dbc0c64b6ec0ccf1080e Mon Sep 17 00:00:00 2001 From: lisk77 Date: Mon, 1 Dec 2025 20:04:22 +0100 Subject: [PATCH] refactor(cli): make adding of subcommands simpler --- CMakeLists.txt | 2 +- src/main.c | 98 +++++++++++++++++--------------------------------- 2 files changed, 33 insertions(+), 67 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7eadf6..087b5c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ target_include_directories(${TARGET_NAME} if(MSVC) target_compile_options(${TARGET_NAME} PRIVATE /W4 /permissive-) else() - target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -Wpedantic) + target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wno-unused-parameter) endif() # Put built artifacts under build/bin and build/lib diff --git a/src/main.c b/src/main.c index 6feb19c..63e71f3 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,27 @@ #include "../include/commands.h" +typedef struct { + const char* name; + void (*func)(int argc, char** argv); + int min_args; + int max_args; + const char* usage; +} Command; + +static void cmd_init(int _argc, char** _argv) { init(); } +static void cmd_diff(int _argc, char** argv) { diff(argv[2], argv[3]); } +static void cmd_status(int _argc, char** _argv) { status(); } +static void cmd_commit(int argc, char** argv) { commit(argc, argv); } +static void cmd_log(int _argc, char** _argv) { commit_log(); } + +static const Command commands[] = { + { "init", cmd_init, 2, 2, "usage: merk init" }, + { "diff", cmd_diff, 4, 4, "usage: merk diff " }, + { "status", cmd_status, 2, 2, "usage: merk status" }, + { "commit", cmd_commit, 3, INT_MAX, "usage: merk commit [-m ] ..." }, + { "log", cmd_log, 2, 2, "usage: merk log" } +}; + int main(int argc, char** argv) { if (argc < 2) { usage(1); @@ -10,73 +32,17 @@ int main(int argc, char** argv) { } const char* subcmd = argv[1]; - - if (strcmp(subcmd, "diff") != 0 - && strcmp(subcmd, "init") != 0 - && strcmp(subcmd, "status") != 0 - && strcmp(subcmd, "commit") != 0 - && strcmp(subcmd, "log") != 0 - && strcmp(subcmd, "test") != 0 ) { - fprintf(stderr, "ERROR: Unknown subcommand: '%s'\n", subcmd); usage(2); - } - - // Initializes a merk repository in the current directory - if (strcmp(subcmd, "init") == 0) { - if (argc != 2) { - printf("ERROR: too many arguments given!\n"); - printf("Usage: merk init"); - exit(1); + size_t iter = sizeof(commands)/sizeof(commands[0]); + for (size_t i = 0; i < iter; i++) { + if (strcmp(subcmd, commands[i].name) == 0) { + if (argc < commands[i].min_args || argc > commands[i].max_args) { + printf("ERROR: invalid args for %s\n", subcmd); + } + commands[i].func(argc, argv); + return 0; } - - init(); } - // Prints out a visual representation of the diff of the files provided - else if (strcmp(subcmd, "diff") == 0) { - if (argc != 4) { - printf("ERROR: too many/little arguments given!\n"); - printf("Usage: merk diff "); - exit(1); - } - - diff(argv[2], argv[3]); - } - - // Gives a list of untracked files in the repo as well as meta information - else if (strcmp(subcmd, "status") == 0) { - if (argc != 2) { - printf("ERROR: too many arguments given!\n"); - printf("Usage: merk status"); - exit(1); - } - - status(); - } - - // Commits changes to the repo - else if (strcmp(subcmd, "commit") == 0) { - if (argc < 3) { - printf("ERROR: too little arguments given!\n"); - printf("Usage: merk commit [-m ] ...\n"); - exit(1); - } - - commit(argc, argv); - } - - else if (strcmp(subcmd, "log") == 0) { - if (argc != 2) { - printf("ERROR: too many arguments given!\n"); - printf("Usage: merk log"); - exit(1); - } - - commit_log(); - } - - else if (strcmp(subcmd, "test") == 0) {} - - else { usage(1); } - - return 0; + printf("ERROR: unknown subcmd %s\n", subcmd); + return 1; }