summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2022-07-20 23:33:55 -0700
committerVito Caputo <vcaputo@pengaru.com>2022-07-20 23:33:55 -0700
commitcbfe780b20ced576c2e3d41361a9036210ab5c9b (patch)
tree1f742aad1d71b39de9d1c87b500953fc6f28c3a1 /src
parentc69917862a58cac01d9deca2b91255f0510b243c (diff)
til_settings: support rudimentary =value escaping
This is a step towards properly handling nested settings, so we can do stuff like: --module=rtv,channels=compose\,layers=checkers\\\,fill_module=shapes\\\,size=64\,texture=plasma and have rtv actually cycle through just compose with checkers+plasma layers but holding the specified checkers settings to shapes filler with a size of 64, randomizing the rest. There's more work to do before that can actually happen, but first thing is to just support escaping the settings values.
Diffstat (limited to 'src')
-rw-r--r--src/til_settings.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/til_settings.c b/src/til_settings.c
index 01b27b7..3e26686 100644
--- a/src/til_settings.c
+++ b/src/til_settings.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -38,6 +39,7 @@ typedef enum til_settings_fsm_state_t {
TIL_SETTINGS_FSM_STATE_KEY,
TIL_SETTINGS_FSM_STATE_EQUAL,
TIL_SETTINGS_FSM_STATE_VALUE,
+ TIL_SETTINGS_FSM_STATE_VALUE_ESCAPED,
TIL_SETTINGS_FSM_STATE_COMMA,
} til_settings_fsm_state_t;
@@ -65,6 +67,9 @@ til_settings_t * til_settings_new(const char *settings_string)
til_settings_fsm_state_t state = TIL_SETTINGS_FSM_STATE_KEY;
const char *p, *token;
til_settings_t *settings;
+ FILE *value_fp;
+ char *value_buf;
+ size_t value_sz;
settings = calloc(1, sizeof(til_settings_t));
if (!settings)
@@ -73,7 +78,6 @@ til_settings_t * til_settings_new(const char *settings_string)
if (!settings_string)
return settings;
- /* TODO: unescaping? */
for (token = p = settings_string; ;p++) {
switch (state) {
@@ -94,15 +98,29 @@ til_settings_t * til_settings_new(const char *settings_string)
break;
case TIL_SETTINGS_FSM_STATE_EQUAL:
+ value_fp = open_memstream(&value_buf, &value_sz);
+ if (!value_fp)
+ goto _err;
+
token = p;
state = TIL_SETTINGS_FSM_STATE_VALUE;
/* fallthrough, necessary to not leave NULL values for empty "key=\0" settings */
case TIL_SETTINGS_FSM_STATE_VALUE:
- if (*p == ',' || *p == '\0') {
- settings->settings[settings->num - 1]->value = strndup(token, p - token);
+ if (*p == '\\')
+ state = TIL_SETTINGS_FSM_STATE_VALUE_ESCAPED;
+ else if (*p == ',' || *p == '\0') {
+ fclose(value_fp);
+ settings->settings[settings->num - 1]->value = value_buf;
state = TIL_SETTINGS_FSM_STATE_COMMA;
- }
+ } else
+ fputc(*p, value_fp);
+
+ break;
+
+ case TIL_SETTINGS_FSM_STATE_VALUE_ESCAPED:
+ fputc(*p, value_fp);
+ state = TIL_SETTINGS_FSM_STATE_VALUE;
break;
default:
@@ -116,6 +134,9 @@ til_settings_t * til_settings_new(const char *settings_string)
/* FIXME: this should probably never leave a value or key entry NULL */
return settings;
+
+_err:
+ return til_settings_free(settings);
}
© All Rights Reserved