refactor(cli): make adding of subcommands simpler

This commit is contained in:
lisk77 2025-12-01 20:04:22 +01:00
parent 136fac9243
commit 31388f077d
2 changed files with 33 additions and 67 deletions

View file

@ -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

View file

@ -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 <PATH> <PATH>" },
{ "status", cmd_status, 2, 2, "usage: merk status" },
{ "commit", cmd_commit, 3, INT_MAX, "usage: merk commit [-m <MSG>] <FILE> ..." },
{ "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 <PATH> <PATH>");
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 <COMMIT MESSAGE>] <FILE> ...\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;
}