#include #include #include #include #include #include #include #include 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; }