]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add functions to concat talloced arrays of strings
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 17 Jun 2022 21:39:58 +0000 (16:39 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 18 Jun 2022 02:05:10 +0000 (21:05 -0500)
src/lib/util/talloc.c
src/lib/util/talloc.h

index c8a324237313a9b7abcfa43f993cfb332c38017b..4b6070cb720453b02e57d9324502c5583a26790f 100644 (file)
  */
 RCSID("$Id$")
 
+#include <freeradius-devel/util/atexit.h>
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/dlist.h>
+#include <freeradius-devel/util/sbuff.h>
 #include <freeradius-devel/util/strerror.h>
-#include <freeradius-devel/util/atexit.h>
 
 static TALLOC_CTX *global_ctx;
 static _Thread_local TALLOC_CTX *thread_local_ctx;
@@ -765,6 +766,41 @@ void **talloc_array_null_strip(void **array)
        return new;
 }
 
+/** Concat an array of strings (not 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 talloc_array_concat(fr_sbuff_t *out, char const * const *array, char const *sep)
+{
+       fr_sbuff_t              our_out = FR_SBUFF(out);
+       size_t                  len = talloc_array_length(array);
+       char const * const *    p;
+       char const * const *    end;
+       fr_sbuff_escape_rules_t e_rules = {
+                                       .name = __FUNCTION__,
+                                       .chr = '\\'
+                               };
+
+       if (sep) e_rules.subs[(uint8_t)*sep] = *sep;
+
+       for (p = array, end = array + len;
+            (p < end);
+            p++) {
+               if (*p) FR_SBUFF_RETURN(fr_sbuff_in_escape, &our_out, *p, strlen(*p), &e_rules);
+
+               if (sep && ((p + 1) < end)) {
+                       FR_SBUFF_RETURN(fr_sbuff_in_strcpy, &our_out, sep);
+               }
+       }
+
+       return fr_sbuff_set(out, &our_out);
+}
+
 /** Callback to free the autofree ctx on global exit
  *
  */
index 48c4855b305a1f53f6f770b497ba8f18ccfb5dd1..0d1a85254b61a77b563e934792e736eb2e7e37ce 100644 (file)
@@ -28,9 +28,6 @@ RCSIDH(talloc_h, "$Id$")
 extern "C" {
 #endif
 
-#include <freeradius-devel/autoconf.h> /* Very easy to miss including in special builds */
-#include <freeradius-devel/build.h>
-#include <freeradius-devel/missing.h>
 #include <ctype.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -43,6 +40,11 @@ DIAG_OFF(documentation)
 DIAG_ON(documentation)
 #endif
 
+#include <freeradius-devel/autoconf.h> /* Very easy to miss including in special builds */
+#include <freeradius-devel/build.h>
+#include <freeradius-devel/missing.h>
+#include <freeradius-devel/util/sbuff.h>
+
 #undef talloc_autofree_context
 /** The original function is deprecated, so replace it with our version
  */
@@ -198,6 +200,8 @@ void                **talloc_array_null_terminate(void **array);
 
 void           **talloc_array_null_strip(void **array);
 
+fr_slen_t      talloc_array_concat(fr_sbuff_t *out, char const * const *array, char const *sep);
+
 /** Free const'd memory
  *
  * @param[in] ptr      to free.