From ab87e56bec6a8727a1bbfae7858fb5b0122539a7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 18 Aug 2022 13:02:16 +0930 Subject: [PATCH] rune: add helpers for users doing DIY parsing. Signed-off-by: Rusty Russell --- ccan/rune/coding.c | 34 +++++++++++++++++++--------------- ccan/rune/rune.h | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/ccan/rune/coding.c b/ccan/rune/coding.c index 380a225c..f4d11028 100644 --- a/ccan/rune/coding.c +++ b/ccan/rune/coding.c @@ -184,7 +184,7 @@ static bool pull_char(const char **data, size_t *len, char *c) return true; } -static bool is_valid_cond(enum rune_condition cond) +bool rune_condition_is_valid(enum rune_condition cond) { switch (cond) { case RUNE_COND_IF_MISSING: @@ -203,31 +203,35 @@ static bool is_valid_cond(enum rune_condition cond) return false; } +size_t rune_altern_fieldname_len(const char *alternstr, size_t alternstrlen) +{ + for (size_t i = 0; i < alternstrlen; i++) { + if (cispunct(alternstr[i])) + return i; + } + return alternstrlen; +} + /* Sets *more on success: true if another altern follows */ static struct rune_altern *rune_altern_decode(const tal_t *ctx, const char **data, size_t *len, bool *more) { struct rune_altern *alt = tal(ctx, struct rune_altern); - const char *strstart = *data; char *value; - size_t strlen = 0; + size_t strlen; char c; - /* Swallow field up to conditional */ - for (;;) { - if (!pull_char(data, len, &c)) - return tal_free(alt); - if (cispunct(c)) - break; - strlen++; - } + /* Swallow field up to possible conditional */ + strlen = rune_altern_fieldname_len(*data, *len); + alt->fieldname = tal_strndup(alt, *data, strlen); + *data += strlen; + *len -= strlen; - alt->fieldname = tal_strndup(alt, strstart, strlen); - if (!is_valid_cond(c)) { - pull_invalid(data, len); + /* Grab conditional */ + if (!pull_char(data, len, &c) || !rune_condition_is_valid(c)) return tal_free(alt); - } + alt->condition = c; /* Assign worst case. */ diff --git a/ccan/rune/rune.h b/ccan/rune/rune.h index b67b7828..c373269a 100644 --- a/ccan/rune/rune.h +++ b/ccan/rune/rune.h @@ -376,4 +376,25 @@ char *rune_to_string(const tal_t *ctx, const struct rune *rune); struct rune_restr *rune_restr_from_string(const tal_t *ctx, const char *str, size_t len); + +/** + * rune_condition_is_valid: is this a valid condition? + * @cond: potential condition character. + * + * Returns true if it's one of enum rune_condition. + */ +bool rune_condition_is_valid(enum rune_condition cond); + +/** + * rune_altern_fieldname_len: how much of this string is condition? + * @alternstr: potential alternative string + * @alternstrlen: length + * + * This helps parsing your own runes. + * + * Returns the first possible condition (check with rune_condition_is_valid) + * or alternstrlen if none found. + */ +size_t rune_altern_fieldname_len(const char *alternstr, size_t alternstrlen); + #endif /* CCAN_RUNE_RUNE_H */ -- 2.39.2