Files
my-os-project2/ulib/args/args.c
2025-09-27 15:16:26 +02:00

94 lines
2.2 KiB
C

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <args/args.h>
#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++) {
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 (!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 E_OK;
}