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