This allows us to convert lil_values into a form which can be re-parsed. We were already doing this for lists, so we just have to expose the inner loop.
Signed-off-by: Sean Anderson <sean...@gmail.com> --- common/cli_lil.c | 89 ++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/common/cli_lil.c b/common/cli_lil.c index 42659920b5..2a8600ffb6 100644 --- a/common/cli_lil.c +++ b/common/cli_lil.c @@ -2387,49 +2387,64 @@ braces: return needs; } +static enum lil_error do_quote(struct lil_value *val, struct lil_value *item) +{ + char q; + size_t i; + + switch (item_needs(lil_to_string(item), item->l)) { + case NEEDS_NOTHING: + return lil_append_val(val, item); + case NEEDS_BRACES: + return lil_append_char(val, '{') ?: + lil_append_val(val, item) ?: + lil_append_char(val, '}'); + case NEEDS_DOUBLE: + q = '"'; + goto quote; + case NEEDS_SINGLE: + q = '\''; +quote: + if (lil_append_char(val, q)) + return LIL_ERR_OOM; + + for (i = 0; i < item->l; i++) { + char c = item->d[i]; + + if (c == '\\' || c == q) + if (lil_append_char(val, '\\')) + return LIL_ERR_OOM; + if (lil_append_char(val, c)) + return LIL_ERR_OOM; + } + if (lil_append_char(val, q)) + return LIL_ERR_OOM; + } + return LIL_ERR_NONE; +} + +static struct lil_value *lil_quote_value(struct lil_value *val) +{ + struct lil_value *r = alloc_value(NULL); + + if (do_quote(r, val)) { + lil_free_value(r); + return NULL; + } + return r; +} + struct lil_value *lil_list_to_value(struct lil_list *list) { struct lil_value *val = alloc_value(NULL); - size_t i, j; + size_t i; for (i = 0; i < list->c; i++) { - char q; - struct lil_value *item = lil_list_get(list, i); + if (i && lil_append_char(val, ' ')) + goto err; - if (i) - lil_append_char(val, ' '); - - switch (item_needs(lil_to_string(item), item->l)) { - case NEEDS_NOTHING: - if (lil_append_val(val, item)) - goto err; - continue; - case NEEDS_BRACES: - if (lil_append_char(val, '{') || - lil_append_val(val, item) || - lil_append_char(val, '}')) - goto err; - continue; - case NEEDS_DOUBLE: - q = '"'; - goto quote; - case NEEDS_SINGLE: - q = '\''; -quote: - if (lil_append_char(val, q)) - goto err; - for (j = 0; j < item->l; j++) { - char c = item->d[j]; - - if (c == '\\' || c == q) - if (lil_append_char(val, '\\')) - goto err; - if (lil_append_char(val, c)) - goto err; - } - if (lil_append_char(val, q)) - goto err; - } + if (do_quote(val, lil_list_get(list, i))) + goto err; } return val; -- 2.32.0