aboutsummaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
authorneonloop2021-08-04 15:09:12 +0000
committerneonloop2021-08-04 15:09:12 +0000
commit99632f66e74fc57c463072be312d634aeb67bc61 (patch)
treee4ccaf52b93d04c69865d82556e2ce4cd3a6c599 /config.c
downloadpicoarch-99632f66e74fc57c463072be312d634aeb67bc61.tar.gz
picoarch-99632f66e74fc57c463072be312d634aeb67bc61.tar.bz2
picoarch-99632f66e74fc57c463072be312d634aeb67bc61.zip
Initial commit
Diffstat (limited to 'config.c')
-rw-r--r--config.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/config.c b/config.c
new file mode 100644
index 0000000..ba6041c
--- /dev/null
+++ b/config.c
@@ -0,0 +1,120 @@
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#include "main.h"
+#include "options.h"
+#include "scale.h"
+
+typedef enum {
+ CE_TYPE_STR = 0,
+ CE_TYPE_NUM = 4,
+} config_entry_type;
+
+#define CE_STR(val) \
+ { #val, CE_TYPE_STRING, val }
+
+#define CE_NUM(val) \
+ { #val, CE_TYPE_NUM, &val }
+
+static const struct {
+ const char *name;
+ config_entry_type type;
+ void *val;
+} config_data[] = {
+ CE_NUM(show_fps),
+ CE_NUM(limit_frames),
+ CE_NUM(audio_buffer_size),
+ CE_NUM(scale_size),
+ CE_NUM(scale_filter),
+};
+
+void config_write(FILE *f)
+{
+ for (int i = 0; i < array_size(config_data); i++) {
+ switch (config_data[i].type)
+ {
+ case CE_TYPE_STR:
+ fprintf(f, "%s = %s\n", config_data[i].name, (char *)config_data[i].val);
+ break;
+ case CE_TYPE_NUM:
+ fprintf(f, "%s = %u\n", config_data[i].name, *(uint32_t *)config_data[i].val);
+ break;
+ default:
+ PA_WARN("unhandled type %d for %s\n", config_data[i].type, (char *)config_data[i].val);
+ break;
+ }
+ }
+
+ for (int i = 0; i < core_options.len; i++) {
+ const char* k = options_get_key(i);
+ if (!options_is_blocked(k))
+ fprintf(f, "%s = %s\n", k, options_get_value(k));
+ }
+}
+
+static void parse_str_val(char *cval, const char *src)
+{
+ char *tmp;
+ strncpy(cval, src, 256);
+ cval[256 - 1] = 0;
+ tmp = strchr(cval, '\n');
+ if (tmp == NULL)
+ tmp = strchr(cval, '\r');
+ if (tmp != NULL)
+ *tmp = 0;
+}
+
+static void parse_num_val(uint32_t *cval, const char *src)
+{
+ char *tmp = NULL;
+ uint32_t val;
+ val = strtoul(src, &tmp, 10);
+ if (tmp == NULL || src == tmp)
+ return; // parse failed
+
+ *cval = val;
+}
+
+static char *config_find_value(const char* cfg, const char *key) {
+ char *tmp;
+
+ tmp = strstr(cfg, key);
+ if (tmp == NULL)
+ return NULL;
+ tmp += strlen(key);
+ if (strncmp(tmp, " = ", 3) != 0)
+ return NULL;
+ tmp += 3;
+
+ return tmp;
+}
+
+void config_read(const char* cfg)
+{
+ for (int i = 0; i < array_size(config_data); i++) {
+ char *tmp = config_find_value(cfg, config_data[i].name);
+ if (!tmp)
+ continue;
+
+ if (config_data[i].type == CE_TYPE_STR) {
+ parse_str_val(config_data[i].val, tmp);
+ continue;
+ }
+
+ parse_num_val(config_data[i].val, tmp);
+ }
+
+ for (int i = 0; i < core_options.len; i++) {
+ char value[256] = {0};
+ const char *key = options_get_key(i);
+ if (options_is_blocked(key))
+ continue;
+
+ char *tmp = config_find_value(cfg, key);
+ if (!tmp)
+ continue;
+
+ parse_str_val(value, tmp);
+ options_set_value(key, value);
+ }
+}