[Bf-blender-cvs] [81c0e643a08] master: BLI_string_utils: string joining utility functions

Campbell Barton noreply at git.blender.org
Wed Aug 23 11:13:57 CEST 2017


Commit: 81c0e643a088f3e354e90b883f6704fb93ea535a
Author: Campbell Barton
Date:   Wed Aug 23 18:16:46 2017 +1000
Branches: master
https://developer.blender.org/rB81c0e643a088f3e354e90b883f6704fb93ea535a

BLI_string_utils: string joining utility functions

Includes a version that takes a separator and macros for convenience.

===================================================================

M	source/blender/blenlib/BLI_string_utils.h
M	source/blender/blenlib/intern/string_utils.c

===================================================================

diff --git a/source/blender/blenlib/BLI_string_utils.h b/source/blender/blenlib/BLI_string_utils.h
index bb19ed574bb..a9fec5a1297 100644
--- a/source/blender/blenlib/BLI_string_utils.h
+++ b/source/blender/blenlib/BLI_string_utils.h
@@ -39,6 +39,7 @@ extern "C" {
 #endif
 
 #include "BLI_compiler_attrs.h"
+#include "BLI_utildefines.h"  /* only for _VA_NARGS_COUNT */
 
 struct ListBase;
 
@@ -49,6 +50,24 @@ size_t BLI_split_name_num(char *left, int *nr, const char *name, const char deli
 void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len);
 void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len);
 
+/* Join strings, return newly allocated string. */
+char *BLI_string_join_arrayN(
+        const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+char *BLI_string_join_array_by_sep_charN(
+        char sep, const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+char *BLI_string_join_array_by_sep_char_with_tableN(
+        char sep, char *table[], const char *strings[], uint strings_len) ATTR_NONNULL();
+/* Take multiple arguments, pass as (array, length). */
+#define BLI_string_joinN(...) \
+	BLI_string_join_arrayN( \
+	((const char *[]){__VA_ARGS__}), _VA_NARGS_COUNT(__VA_ARGS__))
+#define BLI_string_join_by_sep_charN(sep, ...) \
+	BLI_string_join_array_by_sep_charN( \
+	sep, ((const char *[]){__VA_ARGS__}), _VA_NARGS_COUNT(__VA_ARGS__))
+#define BLI_string_join_by_sep_char_with_tableN(sep, table, ...) \
+	BLI_string_join_array_by_sep_char_with_tableN( \
+	sep, table, ((const char *[]){__VA_ARGS__}), _VA_NARGS_COUNT(__VA_ARGS__))
+
 void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len);
 
 bool BLI_uniquename_cb(
diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c
index 8d91a55a5ad..a693463a302 100644
--- a/source/blender/blenlib/intern/string_utils.c
+++ b/source/blender/blenlib/intern/string_utils.c
@@ -383,3 +383,91 @@ bool BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim
 
 	return BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
 }
+
+/* ------------------------------------------------------------------------- */
+/** \name Join Strings
+ *
+ * For non array versions of these functions, use the macros:
+ * - #BLI_string_joinN
+ * - #BLI_string_join_by_sep_charN
+ * - #BLI_string_join_by_sep_char_with_tableN
+ *
+ * \{ */
+
+/**
+ * Join an array of strings into a newly allocated, null terminated string.
+ */
+char *BLI_string_join_arrayN(
+        const char *strings[], uint strings_len)
+{
+	uint total_len = 1;
+	for (uint i = 0; i < strings_len; i++) {
+		total_len += strlen(strings[i]);
+	}
+	char *result = MEM_mallocN(sizeof(char) * total_len, __func__); 
+	char *c = result;
+	for (uint i = 0; i < strings_len; i++) {
+		c += BLI_strcpy_rlen(c, strings[i]);
+	}
+	return result;
+}
+
+/**
+ * A version of #BLI_string_joinN that takes a separator which can be any character including '\0'.
+ */
+char *BLI_string_join_array_by_sep_charN(
+        char sep, const char *strings[], uint strings_len)
+{
+	uint total_len = 0;
+	for (uint i = 0; i < strings_len; i++) {
+		total_len += strlen(strings[i]) + 1;
+	}
+	if (total_len == 0) {
+		total_len = 1;
+	}
+
+	char *result = MEM_mallocN(sizeof(char) * total_len, __func__); 
+	char *c = result;
+	if (strings_len != 0) {
+		for (uint i = 0; i < strings_len; i++) {
+			c += BLI_strcpy_rlen(c, strings[i]);
+			*c = sep;
+			c++;
+		}
+		c--;
+	}
+	*c = '\0';
+	return result;
+}
+
+/**
+ * A version of #BLI_string_join_array_by_sep_charN that takes a table array.
+ * The new location of each string is written into this array.
+ */
+char *BLI_string_join_array_by_sep_char_with_tableN(
+        char sep, char *table[], const char *strings[], uint strings_len)
+{
+	uint total_len = 0;
+	for (uint i = 0; i < strings_len; i++) {
+		total_len += strlen(strings[i]) + 1;
+	}
+	if (total_len == 0) {
+		total_len = 1;
+	}
+
+	char *result = MEM_mallocN(sizeof(char) * total_len, __func__); 
+	char *c = result;
+	if (strings_len != 0) {
+		for (uint i = 0; i < strings_len; i++) {
+			table[i] = c;  /* <-- only difference to BLI_string_join_array_by_sep_charN. */
+			c += BLI_strcpy_rlen(c, strings[i]);
+			*c = sep;
+			c++;
+		}
+		c--;
+	}
+	*c = '\0';
+	return result;
+}
+
+/** \} */



More information about the Bf-blender-cvs mailing list