bemanitools/src/main/cconfig/cmd.c
icex2 0adec478cc refactor: Entire code base, thread and log usage
Boils down to:
- Include headers
- Reduce boiler plate with helpers
- Swap out explicit usages with core API layer
  and ensure the right API is configured beforehand
2024-02-23 13:29:53 +01:00

142 lines
3.2 KiB
C

#define LOG_MODULE "cconfig-cmd"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "cconfig/cmd.h"
#include "core/log.h"
#include "util/hex.h"
#include "util/str.h"
static void
cconfig_cmd_usage_print(enum cconfig_cmd_usage_out output, const char *fmt, ...)
{
char buffer[32768];
va_list ap;
va_start(ap, fmt);
switch (output) {
case CCONFIG_CMD_USAGE_OUT_STDOUT:
vfprintf(stdout, fmt, ap);
break;
case CCONFIG_CMD_USAGE_OUT_STDERR:
vfprintf(stderr, fmt, ap);
break;
case CCONFIG_CMD_USAGE_OUT_DBG:
_vsnprintf(buffer, sizeof(buffer), fmt, ap);
OutputDebugString(buffer);
break;
case CCONFIG_CMD_USAGE_OUT_LOG:
_vsnprintf(buffer, sizeof(buffer), fmt, ap);
log_info("%s", buffer);
break;
default:
log_assert(false);
break;
}
va_end(ap);
}
bool cconfig_cmd_parse(
struct cconfig *config,
const char *key_ident,
int argc,
char **argv,
bool add_params_if_absent)
{
bool no_error;
struct cconfig_entry *entry;
char *tmp;
char *cur_tok;
int ntok;
char *toks[2];
no_error = true;
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], key_ident)) {
if (i + 1 >= argc) {
no_error = false;
break;
}
/* Not another key ident is following */
if (!strcmp(argv[i + 1], key_ident)) {
no_error = false;
break;
}
++i;
tmp = str_dup(argv[i]);
ntok = 0;
cur_tok = strtok(tmp, "=");
while (cur_tok != NULL) {
toks[ntok] = cur_tok;
ntok++;
cur_tok = strtok(NULL, "=");
if (ntok == 2) {
break;
}
}
if (ntok != 2) {
/* Tokenizing key=value parameter error */
log_warning("Parsing parameter '%s' failed, ignore", argv[i]);
free(tmp);
no_error = false;
continue;
}
log_misc("Key: %s, Value: %s", toks[0], toks[1]);
entry = cconfig_get(config, toks[0]);
if (entry || add_params_if_absent) {
cconfig_set2(config, toks[0], toks[1]);
} else {
/* Ignore cmd params that are not found in config */
log_warning(
"Could not find cmd parameter with key '%s' in "
"config, ignored",
toks[0]);
}
free(tmp);
}
}
return no_error;
}
void cconfig_cmd_print_usage(
struct cconfig *config,
const char *usage_header,
enum cconfig_cmd_usage_out output)
{
cconfig_cmd_usage_print(output, "%s\n", usage_header);
for (uint32_t i = 0; i < config->nentries; i++) {
cconfig_cmd_usage_print(
output,
" %s: %s\n"
" default: %s\n",
config->entries[i].key,
config->entries[i].desc,
config->entries[i].value);
}
}