From 051e86242043cd10dee186343e3f7b661ee30219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 1 Dec 2022 15:00:44 +0100 Subject: [PATCH] config: allow string values to be quoted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Both double and single quotes are recognized. There’s no difference in how they are handled. * The entire string must be quoted: - “a quoted string” - OK - quotes “in the middle” of a string - NOT ok * Two escape characters are regonized: - Backslash - The quote character itself --- CHANGELOG.md | 2 ++ config.c | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13b87f4b..bffe4e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ * Support (optional) for utmp logging with libutempter. * `kxIN` and `kxOUT` (focus in/out events) to terminfo. * `name` capability to `XTGETTCAP`. +* String values in `foot.ini` may now be quoted. This can be used to + set a value to the empty string, for example. [1136]: https://codeberg.org/dnkl/foot/issues/1136 diff --git a/config.c b/config.c index e2c007d2..cbf64abc 100644 --- a/config.c +++ b/config.c @@ -502,8 +502,48 @@ value_to_double(struct context *ctx, float *res) static bool NOINLINE value_to_str(struct context *ctx, char **res) { + char *copy = xstrdup(ctx->value); + char *end = copy + strlen(copy) - 1; + + /* Un-quote + * + * Note: this is very simple; we only support the *entire* value + * being quoted. That is, no mid-value quotes. Both double and + * single quotes are supported. + * + * - key="value" OK + * - key=abc "quote" def NOT OK + * - key=’value’ OK + * + * Finally, we support escaping the quote character, and the + * escape character itself: + * + * - key="value \"quotes\"" + * - key="backslash: \\" + * + * ONLY the "current" quote character can be escaped: + * + * key="value \'" NOt OK (both backslash and single quote is kept) + */ + + if ((copy[0] == '"' && *end == '"') || + (copy[0] == '\'' && *end == '\'')) + { + const char quote = copy[0]; + *end = '\0'; + + memmove(copy, copy + 1, end - copy); + + /* Un-escape */ + for (char *p = copy; *p != '\0'; p++) { + if (p[0] == '\\' && (p[1] == '\\' || p[1] == quote)) { + memmove(p, p + 1, end - p); + } + } + } + free(*res); - *res = xstrdup(ctx->value); + *res = copy; return true; }