]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add sbuff array concat function
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 5 Jun 2025 17:12:48 +0000 (11:12 -0600)
committerNick Porter <nick@portercomputing.co.uk>
Wed, 18 Jun 2025 12:53:18 +0000 (13:53 +0100)
src/lib/util/sbuff.c
src/lib/util/sbuff.h

index 342ef71c3a55c9d438f3f1d8d3ab48a89b72e8ab..8e303e99928840ccffb699d30e7bfe57b1842349 100644 (file)
@@ -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.
index 7cda384d870360818d6c2a60625e8df635c62844..2c3fbc9bc7c184ffd4acb8ef287c039b57239edb 100644 (file)
@@ -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.