92 lines
2.1 KiB
C
92 lines
2.1 KiB
C
#include <cmdline_parser.h>
|
|
#include <debugconsole.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <strconv.h>
|
|
#include <string.h>
|
|
|
|
#define PARSE_MODE_NAME 0
|
|
#define PARSE_MODE_VALUE 1
|
|
|
|
static void cmdline_parse_opt(const char* cmdline, struct cmdline_opt* opt) {
|
|
const char* p = cmdline;
|
|
char optnamebuf[CMDLINE_OPT_NAME_MAX];
|
|
char optvaluebuf[CMDLINE_OPT_VALUE_MAX];
|
|
int mode = PARSE_MODE_NAME;
|
|
|
|
while (*p) {
|
|
if (isspace(*p)) {
|
|
p++;
|
|
continue;
|
|
}
|
|
|
|
if (mode == PARSE_MODE_NAME) {
|
|
if (*p == '-') {
|
|
p++;
|
|
|
|
memset(optnamebuf, 0, sizeof(optnamebuf));
|
|
|
|
size_t i = 0;
|
|
while (*p && !isspace(*p) && i < CMDLINE_OPT_NAME_MAX - 1) {
|
|
optnamebuf[i++] = *p++;
|
|
}
|
|
optnamebuf[i] = '\0';
|
|
|
|
if (strcmp(optnamebuf, opt->name) == 0 || strcmp(optnamebuf, opt->altname) == 0) {
|
|
if (opt->type == CMDLINE_OPT_VALUE_BOOL) {
|
|
*(bool*)opt->valueptr = true;
|
|
opt->set = true;
|
|
} else {
|
|
mode = PARSE_MODE_VALUE;
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
} else if (mode == PARSE_MODE_VALUE) {
|
|
memset(optvaluebuf, 0, sizeof(optvaluebuf));
|
|
|
|
size_t i = 0;
|
|
while (*p && !isspace(*p) && i < CMDLINE_OPT_VALUE_MAX - 1) {
|
|
optvaluebuf[i++] = *p++;
|
|
}
|
|
optvaluebuf[i] = '\0';
|
|
|
|
if (opt->type == CMDLINE_OPT_VALUE_STRING) {
|
|
strncpy(opt->valueptr, optvaluebuf, CMDLINE_OPT_VALUE_MAX);
|
|
opt->set = true;
|
|
} else if (opt->type == CMDLINE_OPT_VALUE_INT) {
|
|
*(uint64_t*)opt->valueptr = str_to_uint64(optvaluebuf);
|
|
opt->set = true;
|
|
}
|
|
|
|
mode = PARSE_MODE_NAME;
|
|
continue;
|
|
}
|
|
|
|
p++;
|
|
}
|
|
}
|
|
|
|
int cmdline_parse(const char* cmdline, struct cmdline_opt* opt_array) {
|
|
size_t curr_opt_idx = 0;
|
|
|
|
while (!opt_array[curr_opt_idx].end) {
|
|
struct cmdline_opt* curr_opt = &opt_array[curr_opt_idx++];
|
|
|
|
cmdline_parse_opt(cmdline, curr_opt);
|
|
}
|
|
|
|
curr_opt_idx = 0;
|
|
|
|
while (!opt_array[curr_opt_idx].end) {
|
|
struct cmdline_opt* curr_opt = &opt_array[curr_opt_idx++];
|
|
|
|
if (!curr_opt->set && curr_opt->required)
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|