From 9f7737c80ce30bb7ff2209601ac3a51778abd2fd Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Thu, 5 Jun 2025 11:12:48 -0600 Subject: [PATCH] Add sbuff array concat function --- src/lib/util/sbuff.c | 31 +++++++++++++++++++++++++++++++ src/lib/util/sbuff.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index 342ef71c3a..8e303e9992 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -1703,6 +1703,37 @@ ssize_t fr_sbuff_in_escape_buffer(fr_sbuff_t *sbuff, char const *in, fr_sbuff_es return fr_sbuff_in_escape(sbuff, in, talloc_array_length(in) - 1, e_rules); } +/** Concat an array of strings (NULL terminated), with a string separator + * + * @param[out] out Where to write the resulting string. + * @param[in] array of strings to concat. + * @param[in] sep to insert between elements. May be NULL. + * @return + * - >= 0 on success - length of the string created. + * - <0 on failure. How many bytes we would need. + */ +fr_slen_t fr_sbuff_in_array(fr_sbuff_t *out, char const * const *array, char const *sep) +{ + fr_sbuff_t our_out = FR_SBUFF(out); + char const * const * p; + fr_sbuff_escape_rules_t e_rules = { + .name = __FUNCTION__, + .chr = '\\' + }; + + if (sep) e_rules.subs[(uint8_t)*sep] = *sep; + + for (p = array; *p; p++) { + if (*p) FR_SBUFF_RETURN(fr_sbuff_in_escape, &our_out, *p, strlen(*p), &e_rules); + + if (sep && p[1]) { + FR_SBUFF_RETURN(fr_sbuff_in_strcpy, &our_out, sep); + } + } + + FR_SBUFF_SET_RETURN(out, &our_out); +} + /** Return true and advance past the end of the needle if needle occurs next in the sbuff * * @param[in] sbuff to search in. diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index 7cda384d87..2c3fbc9bc7 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -1420,6 +1420,9 @@ ssize_t fr_sbuff_in_escape(fr_sbuff_t *sbuff, char const *in, size_t inlen, fr_s ssize_t fr_sbuff_in_escape_buffer(fr_sbuff_t *sbuff, char const *in, fr_sbuff_escape_rules_t const *e_rules); #define FR_SBUFF_IN_ESCAPE_BUFFER_RETURN(...) FR_SBUFF_RETURN(fr_sbuff_in_escape_buffer, ##__VA_ARGS__) +ssize_t fr_sbuff_in_array(fr_sbuff_t *sbuff, char const * const *array, char const *sep); +#define FR_SBUFF_IN_ARRAY(...) FR_SBUFF_RETURN(fr_sbuff_in_array, ##__VA_ARGS__) + /** Lookup a string in a table using an integer value, and copy it to the sbuff * * @param[out] _slen Where to write the return value. -- 2.47.3