WIP 2
This commit is contained in:
@ -5,35 +5,89 @@
|
||||
#include <string/conv.h>
|
||||
#include <string/string.h>
|
||||
#include <uprintf.h>
|
||||
#include <errors.h>
|
||||
|
||||
int32_t parse_args(char **argv, size_t argc, Arg *defs) {
|
||||
#define CONSUME_TK() i++
|
||||
|
||||
if (!argv || !defs) {
|
||||
return E_INVALIDARGUMENT;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
if (argv[i][0] == '-' && argv[i][1] != '\0') {
|
||||
char *optname = argv[i];
|
||||
char *arg = argv[i];
|
||||
if (!arg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg[0] == '-' && arg[1] != '\0') {
|
||||
size_t j = 0;
|
||||
while (!defs[j].end) {
|
||||
Arg *def = &defs[j];
|
||||
if (string_strcmp(def->shortname, optname) == 0) {
|
||||
if (i < argc - 1) {
|
||||
switch (def->expected_value) {
|
||||
case ARG_STRING:
|
||||
*((char **)def->ptr) = argv[i+1];
|
||||
break;
|
||||
case ARG_BOOL:
|
||||
*((bool *)def->ptr) = string_strcmp(argv[i+1], "yes") == 0;
|
||||
break;
|
||||
case ARG_INT: {
|
||||
char *end;
|
||||
*((int32_t *)def->ptr) = string_conv_strtol(argv[i+1], &end, 10);
|
||||
} break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!def->shortname || !def->ptr) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string_strcmp(def->shortname, arg) == 0) {
|
||||
bool have_next = (i + 1) < argc && argv[i + 1] != NULL;
|
||||
char *nexttk = have_next ? argv[i + 1] : NULL;
|
||||
|
||||
if (nexttk && nexttk[0] == '-' && nexttk[1] != '\0') {
|
||||
have_next = false;
|
||||
nexttk = NULL;
|
||||
}
|
||||
|
||||
switch (def->expected_value) {
|
||||
case ARG_STRING:
|
||||
if (!have_next) {
|
||||
break;
|
||||
}
|
||||
*((char **)def->ptr) = nexttk;
|
||||
CONSUME_TK();
|
||||
break;
|
||||
case ARG_BOOL:
|
||||
if (!have_next) {
|
||||
*((bool *)def->ptr) = true;
|
||||
} else {
|
||||
if (string_strcmp(nexttk, "yes") == 0) {
|
||||
*((bool *)def->ptr) = true;
|
||||
CONSUME_TK();
|
||||
} else if (string_strcmp(nexttk, "no") == 0) {
|
||||
*((bool *)def->ptr) = false;
|
||||
CONSUME_TK();
|
||||
} else {
|
||||
*((bool *)def->ptr) = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ARG_INT:
|
||||
if (!have_next) {
|
||||
break;
|
||||
}
|
||||
char *endptr = NULL;
|
||||
long val = string_conv_strtol(nexttk, &endptr, 10);
|
||||
if (endptr == NULL) {
|
||||
break;
|
||||
}
|
||||
if (*endptr != '\0') {
|
||||
break;
|
||||
}
|
||||
*((int32_t *)def->ptr) = (int32_t)val;
|
||||
CONSUME_TK();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ARGP_OK;
|
||||
return E_OK;
|
||||
}
|
||||
|
Reference in New Issue
Block a user