diff --git a/src/cdo.c b/src/cdo.c index b490655..930bb26 100644 --- a/src/cdo.c +++ b/src/cdo.c @@ -12,6 +12,9 @@ static void __attribute__((constructor)) init_cdo(void) { } int main (int argc, char *argv[]) { - struct CommandLineArg* args = parse_args(argc, argv); + struct ArgList* args = parse_args(argc, argv); + for (size_t i = 0; i < args->size; i++) { + printf("Arg: %s, param: %s\n", args->args[i].name, args->args[i].value); + } return 0; } diff --git a/src/cmd.c b/src/cmd.c index ff8116d..51e9c6f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -5,12 +5,13 @@ #include #include +#include static struct ArgList* supported_args; static const char* PREDEFINED_ARG_NAMES [] = { - "project", - "help" + "--project", + "--help" }; static const char* PREDEFINED_ARG_DESC [] = { @@ -19,7 +20,7 @@ static const char* PREDEFINED_ARG_DESC [] = { }; static const char* PREDEFINED_ARG_VALUES [] = { - "Curernt WD", + "Curernt Working Directory", NULL }; @@ -42,7 +43,7 @@ void usage(void) { buffer_flush(usage_lines); } -static struct CommandLineArg* renderArg(ArgName name) { +static struct CommandLineArg* renderArgById(ArgNameId name) { struct CommandLineArg* e = cdo_malloc(sizeof(struct CommandLineArg)); e->name = NULL; e->description = NULL; @@ -62,6 +63,26 @@ static struct CommandLineArg* renderArg(ArgName name) { return e; } +static struct CommandLineArg* renderArgByValues(const char* name, const char* description, const char* value) { + struct CommandLineArg* e = cdo_malloc(sizeof(struct CommandLineArg)); + e->name = NULL; + e->description = NULL; + e->value = NULL; + if (name) { + e->name = cdo_malloc(strlen(name) + 1); + strcpy(e->name, name); + } + if (description) { + e->description = cdo_malloc(strlen(description) + 1); + strcpy(e->description, description); + } + if (value) { + e->value = cdo_malloc(strlen(value) + 1); + strcpy(e->value, value); + } + return e; +} + void init_cmd(void) { supported_args = create_arg_list(ARG_COUNT); for (int i = 0; i < ARG_COUNT; i++) { @@ -69,7 +90,7 @@ void init_cmd(void) { { case ARG_PROJECT: case ARG_HELP: - append_arg(supported_args, renderArg(i)); + append_arg(supported_args, renderArgById(i)); break; default: LOG_ERROR_EXIT("Undefined argument iterator %d", i); @@ -117,11 +138,58 @@ void free_arg_list(struct ArgList* list) { } -struct CommandLineArg* parse_args(const int argc, char* argv[]) { - if (argc < 2) { - LOG_ERROR("At least 1 argument required."); - usage(); - exit(1); +static ArgNameId get_arg_name_id_from_str(const char* str) { + for (int i = 0; i < ARG_COUNT; i++) { + if (strcmp(str, PREDEFINED_ARG_NAMES[i]) == 0) + return (ArgNameId)i; } - return NULL; + return ARG_COUNT; +} + +static bool validate_arg_param(const char* str) { + for (int i = 0; i < ARG_COUNT; i++) { + if (strcmp(str, PREDEFINED_ARG_NAMES[i]) == 0) + return false; + } + return true; +} + +struct ArgList* parse_args(const int argc, char* argv[]) { + int initial_capacity = 1; + if (argc > 1) { + initial_capacity = argc / 2; + } + struct ArgList* user_args = create_arg_list(initial_capacity); + for(int i = 1; i < argc; i++) { + ArgNameId current_arg = get_arg_name_id_from_str(argv[i]); + switch (current_arg) + { + case ARG_HELP: + usage(); + break; + case ARG_PROJECT: + int next_iterator = (i + 1 < argc) ? i + 1 : i; + if (!validate_arg_param(argv[next_iterator])) { + LOG_ERROR("Argument '%s' requires a value.", PREDEFINED_ARG_NAMES[current_arg]); + goto defer; + } + i = next_iterator; + append_arg( + user_args, + renderArgByValues( + PREDEFINED_ARG_NAMES[current_arg], + NULL, + argv[next_iterator] + ) + ); + break; + default: + LOG_ERROR("Undefined argument '%s'", argv[i]); + goto defer; + } + } + return user_args; + defer: + usage(); + exit(1); } \ No newline at end of file diff --git a/src/cmd.h b/src/cmd.h index 242494b..16dd097 100644 --- a/src/cmd.h +++ b/src/cmd.h @@ -12,7 +12,7 @@ typedef enum { ARG_PROJECT, ARG_HELP, ARG_COUNT -} ArgName; +} ArgNameId; struct CommandLineArg { char* name; @@ -26,12 +26,11 @@ struct ArgList { size_t size; }; -struct CommandLineArg* parse_args(const int argc, char* argv[]); +struct ArgList* parse_args(const int argc, char* argv[]); void init_cmd(void); void exit_cmd(void); struct ArgList* create_arg_list(size_t capacity); void append_arg(struct ArgList* list, struct CommandLineArg* arg); void free_arg_list(struct ArgList* list); void usage(void); - #endif /*__CMD_H__*/ \ No newline at end of file