From 81c0e643a088f3e354e90b883f6704fb93ea535a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 23 Aug 2017 18:16:46 +1000 Subject: BLI_string_utils: string joining utility functions Includes a version that takes a separator and macros for convenience. --- source/blender/blenlib/BLI_string_utils.h | 19 ++++++ source/blender/blenlib/intern/string_utils.c | 88 ++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) (limited to 'source/blender') 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; +} + +/** \} */ -- cgit v1.2.3