From: Arran Cudbard-Bell Date: Thu, 5 Jun 2025 17:12:48 +0000 (-0600) Subject: Add sbuff array concat function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f7737c80ce30bb7ff2209601ac3a51778abd2fd;p=thirdparty%2Ffreeradius-server.git Add sbuff array concat function --- diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index 342ef71c3a5..8e303e99928 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 7cda384d870..2c3fbc9bc7c 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.