summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2018-02-17 18:18:52 -0800
committerVito Caputo <vcaputo@pengaru.com>2018-02-20 13:58:18 -0800
commitbdd87e11c050819fea910bcc36865b84b59733ad (patch)
tree4ee6b2a7dd563d9469372069658902e3a7968cd6
parent7cccd01fe2f56a4e1805ab7b1cb3a4ee1f852b21 (diff)
setup: add simple stdio setup_interactively()
Preliminary means for interactively configuring settings and defaults
-rw-r--r--src/Makefile.am2
-rw-r--r--src/setup.c124
-rw-r--r--src/setup.h8
3 files changed, 133 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 9ee9d88..acb5c16 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
SUBDIRS = modules
bin_PROGRAMS = rototiller
-rototiller_SOURCES = drmsetup.c drmsetup.h drm_fb.c drm_fb.h fb.c fb.h fps.c fps.h rototiller.c rototiller.h settings.h settings.c threads.c threads.h util.c util.h
+rototiller_SOURCES = drmsetup.c drmsetup.h drm_fb.c drm_fb.h fb.c fb.h fps.c fps.h rototiller.c rototiller.h settings.h settings.c setup.h setup.c threads.c threads.h util.c util.h
rototiller_LDADD = @ROTOTILLER_LIBS@ -lm modules/julia/libjulia.a modules/plasma/libplasma.a modules/ray/libray.a modules/roto/libroto.a modules/sparkler/libsparkler.a modules/stars/libstars.a
rototiller_CPPFLAGS = @ROTOTILLER_CFLAGS@
diff --git a/src/setup.c b/src/setup.c
new file mode 100644
index 0000000..6c4a87f
--- /dev/null
+++ b/src/setup.c
@@ -0,0 +1,124 @@
+#include <assert.h>
+#include <stdio.h>
+
+#include "settings.h"
+#include "util.h"
+
+/* add key=value, but if key is NULL, use value as key. */
+static int add_value(settings_t *settings, const char *key, const char *value)
+{
+ assert(settings);
+
+ if (!key) {
+ key = value;
+ value = NULL;
+ }
+
+ assert(key);
+
+ return settings_add_value(settings, key, value);
+}
+
+
+/* returns negative on error, otherwise number of additions made to settings */
+int setup_interactively(settings_t *settings, int (*setup_func)(settings_t *settings, setting_desc_t **next), int defaults)
+{
+ unsigned additions = 0;
+ char buf[256] = "\n";
+ setting_desc_t *next;
+ int r;
+
+ assert(settings);
+ assert(setup_func);
+
+ /* TODO: regex and error handling */
+
+ while ((r = setup_func(settings, &next)) > 0) {
+ additions++;
+
+ if (!defaults)
+ puts("");
+
+ if (next->values) {
+ unsigned i, preferred = 0;
+ int width = 0;
+
+ for (i = 0; next->values[i]; i++) {
+ int len;
+
+ len = strlen(next->values[i]);
+ if (len > width)
+ width = len;
+ }
+
+ /* multiple choice */
+ if (!defaults)
+ printf("Select %s:\n", next->name);
+
+ for (i = 0; next->values[i]; i++) {
+ if (!defaults)
+ printf(" %u: %*s%s%s\n", i, width, next->values[i],
+ next->annotations ? ": " : "",
+ next->annotations ? next->annotations[i] : "");
+
+ if (!strcmp(next->preferred, next->values[i]))
+ preferred = i;
+ }
+
+ if (!defaults)
+ printf("Enter a value 0-%u [%u (%s)]: ",
+ i - 1, preferred, next->preferred);
+ } else {
+ /* arbitrarily typed input */
+ if (!defaults)
+ printf("%s [%s]: ", next->name, next->preferred);
+ }
+
+ if (!defaults) {
+ fflush(stdout);
+ fgets(buf, sizeof(buf), stdin);
+ }
+
+ if (*buf == '\n') {
+ /* accept preferred */
+ add_value(settings, next->key, next->preferred);
+ } else {
+ buf[strlen(buf) - 1] = '\0';
+
+ if (next->values) {
+ unsigned i, j, found;
+
+ /* multiple choice, map numeric input to values entry */
+ if (sscanf(buf, "%u", &j) < 1) {
+ printf("Invalid input: \"%s\"\n", buf);
+
+ goto _next;
+ }
+
+ for (found = i = 0; next->values[i]; i++) {
+ if (i == j) {
+ add_value(settings, next->key, next->values[i]);
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("Invalid option: %u outside of range [0-%u]\n",
+ j, i - 1);
+
+ goto _next;
+ }
+
+ } else {
+ /* use typed input as setting, TODO: apply regex */
+ add_value(settings, next->key, buf);
+ }
+ }
+
+_next:
+ setting_desc_free(next);
+ }
+
+ return r < 0 ? r : additions;
+}
diff --git a/src/setup.h b/src/setup.h
new file mode 100644
index 0000000..2f190f4
--- /dev/null
+++ b/src/setup.h
@@ -0,0 +1,8 @@
+#ifndef _SETUP_H
+#define _SETUP_H
+
+#include "settings.h"
+
+int setup_interactively(settings_t *settings, int (*setup_func)(settings_t *settings, setting_desc_t **next), int defaults);
+
+#endif
© All Rights Reserved