cmd: parse user args #1
This commit is contained in:
parent
5211e5800e
commit
204aaad082
@ -12,6 +12,9 @@ static void __attribute__((constructor)) init_cdo(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
88
src/cmd.c
88
src/cmd.c
@ -5,12 +5,13 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
static struct ArgList* supported_args;
|
static struct ArgList* supported_args;
|
||||||
|
|
||||||
static const char* PREDEFINED_ARG_NAMES [] = {
|
static const char* PREDEFINED_ARG_NAMES [] = {
|
||||||
"project",
|
"--project",
|
||||||
"help"
|
"--help"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* PREDEFINED_ARG_DESC [] = {
|
static const char* PREDEFINED_ARG_DESC [] = {
|
||||||
@ -19,7 +20,7 @@ static const char* PREDEFINED_ARG_DESC [] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char* PREDEFINED_ARG_VALUES [] = {
|
static const char* PREDEFINED_ARG_VALUES [] = {
|
||||||
"Curernt WD",
|
"Curernt Working Directory",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ void usage(void) {
|
|||||||
buffer_flush(usage_lines);
|
buffer_flush(usage_lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct CommandLineArg* renderArg(ArgName name) {
|
static struct CommandLineArg* renderArgById(ArgNameId name) {
|
||||||
struct CommandLineArg* e = cdo_malloc(sizeof(struct CommandLineArg));
|
struct CommandLineArg* e = cdo_malloc(sizeof(struct CommandLineArg));
|
||||||
e->name = NULL;
|
e->name = NULL;
|
||||||
e->description = NULL;
|
e->description = NULL;
|
||||||
@ -62,6 +63,26 @@ static struct CommandLineArg* renderArg(ArgName name) {
|
|||||||
return e;
|
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) {
|
void init_cmd(void) {
|
||||||
supported_args = create_arg_list(ARG_COUNT);
|
supported_args = create_arg_list(ARG_COUNT);
|
||||||
for (int i = 0; i < ARG_COUNT; i++) {
|
for (int i = 0; i < ARG_COUNT; i++) {
|
||||||
@ -69,7 +90,7 @@ void init_cmd(void) {
|
|||||||
{
|
{
|
||||||
case ARG_PROJECT:
|
case ARG_PROJECT:
|
||||||
case ARG_HELP:
|
case ARG_HELP:
|
||||||
append_arg(supported_args, renderArg(i));
|
append_arg(supported_args, renderArgById(i));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR_EXIT("Undefined argument iterator %d", i);
|
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[]) {
|
static ArgNameId get_arg_name_id_from_str(const char* str) {
|
||||||
if (argc < 2) {
|
for (int i = 0; i < ARG_COUNT; i++) {
|
||||||
LOG_ERROR("At least 1 argument required.");
|
if (strcmp(str, PREDEFINED_ARG_NAMES[i]) == 0)
|
||||||
|
return (ArgNameId)i;
|
||||||
|
}
|
||||||
|
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();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
@ -12,7 +12,7 @@ typedef enum {
|
|||||||
ARG_PROJECT,
|
ARG_PROJECT,
|
||||||
ARG_HELP,
|
ARG_HELP,
|
||||||
ARG_COUNT
|
ARG_COUNT
|
||||||
} ArgName;
|
} ArgNameId;
|
||||||
|
|
||||||
struct CommandLineArg {
|
struct CommandLineArg {
|
||||||
char* name;
|
char* name;
|
||||||
@ -26,12 +26,11 @@ struct ArgList {
|
|||||||
size_t size;
|
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 init_cmd(void);
|
||||||
void exit_cmd(void);
|
void exit_cmd(void);
|
||||||
struct ArgList* create_arg_list(size_t capacity);
|
struct ArgList* create_arg_list(size_t capacity);
|
||||||
void append_arg(struct ArgList* list, struct CommandLineArg* arg);
|
void append_arg(struct ArgList* list, struct CommandLineArg* arg);
|
||||||
void free_arg_list(struct ArgList* list);
|
void free_arg_list(struct ArgList* list);
|
||||||
void usage(void);
|
void usage(void);
|
||||||
|
|
||||||
#endif /*__CMD_H__*/
|
#endif /*__CMD_H__*/
|
||||||
Loading…
x
Reference in New Issue
Block a user