BLI_string: C++ support for string joining macros

C++ doesn't support taking the temporary address of a temporary array,
use inline functions instead.

Also change array joining functions to return the length of the string
instead of returning the pointer (matching BLI_path_join).
This commit is contained in:
Campbell Barton 2022-11-03 14:17:54 +11:00
parent 5ba045af7b
commit 92b2f4d249
3 changed files with 363 additions and 47 deletions

View File

@ -47,33 +47,6 @@ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, size
*/
void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, size_t str_len);
/**
* Join strings, return newly allocated string.
*/
char *BLI_string_join_array(char *result,
size_t result_len,
const char *strings[],
uint strings_len) ATTR_NONNULL();
/**
* A version of #BLI_string_join that takes a separator which can be any character including '\0'.
*/
char *BLI_string_join_array_by_sep_char(char *result,
size_t result_len,
char sep,
const char *strings[],
uint strings_len) ATTR_NONNULL();
/**
* Join an array of strings into a newly allocated, null terminated string.
*/
char *BLI_string_join_arrayN(const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
/**
* 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) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/**
* 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.
@ -82,17 +55,7 @@ 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_join(result, result_len, ...) \
BLI_string_join_array( \
result, result_len, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
#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__))
@ -149,6 +112,360 @@ bool BLI_uniquename(struct ListBase *list,
int name_offset,
size_t name_len);
/* Expand array functions. */
/* Intentionally no comma after `_BLI_STRING_ARGS_0` to allow it to be empty. */
#define _BLI_STRING_ARGS_1 _BLI_STRING_ARGS_0 const char *a
#define _BLI_STRING_ARGS_2 _BLI_STRING_ARGS_1, const char *b
#define _BLI_STRING_ARGS_3 _BLI_STRING_ARGS_2, const char *c
#define _BLI_STRING_ARGS_4 _BLI_STRING_ARGS_3, const char *d
#define _BLI_STRING_ARGS_5 _BLI_STRING_ARGS_4, const char *e
#define _BLI_STRING_ARGS_6 _BLI_STRING_ARGS_5, const char *f
#define _BLI_STRING_ARGS_7 _BLI_STRING_ARGS_6, const char *g
#define _BLI_STRING_ARGS_8 _BLI_STRING_ARGS_7, const char *h
#define _BLI_STRING_ARGS_9 _BLI_STRING_ARGS_8, const char *i
#define _BLI_STRING_ARGS_10 _BLI_STRING_ARGS_9, const char *j
/* ------------------------------------------------------------------------- */
/** \name Implement: `BLI_string_join(..)`
* \{ */
#define _BLI_STRING_ARGS_0 char *__restrict dst, const size_t dst_len,
/**
* Join strings, return the length of the resulting string.
*/
size_t BLI_string_join_array(char *result,
size_t result_len,
const char *strings[],
uint strings_len) ATTR_NONNULL();
#define BLI_string_join(...) VA_NARGS_CALL_OVERLOAD(_BLI_string_join_, __VA_ARGS__)
BLI_INLINE size_t _BLI_string_join_3(_BLI_STRING_ARGS_1) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_4(_BLI_STRING_ARGS_2) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_5(_BLI_STRING_ARGS_3) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_6(_BLI_STRING_ARGS_4) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_7(_BLI_STRING_ARGS_5) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_8(_BLI_STRING_ARGS_6) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_9(_BLI_STRING_ARGS_7) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_10(_BLI_STRING_ARGS_8) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_11(_BLI_STRING_ARGS_9) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_12(_BLI_STRING_ARGS_10) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_3(_BLI_STRING_ARGS_1)
{
const char *string_array[] = {a};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_4(_BLI_STRING_ARGS_2)
{
const char *string_array[] = {a, b};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_5(_BLI_STRING_ARGS_3)
{
const char *string_array[] = {a, b, c};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_6(_BLI_STRING_ARGS_4)
{
const char *string_array[] = {a, b, c, d};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_7(_BLI_STRING_ARGS_5)
{
const char *string_array[] = {a, b, c, d, e};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_8(_BLI_STRING_ARGS_6)
{
const char *string_array[] = {a, b, c, d, e, f};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_9(_BLI_STRING_ARGS_7)
{
const char *string_array[] = {a, b, c, d, e, f, g};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_10(_BLI_STRING_ARGS_8)
{
const char *string_array[] = {a, b, c, d, e, f, g, h};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_11(_BLI_STRING_ARGS_9)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_12(_BLI_STRING_ARGS_10)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
}
#undef _BLI_STRING_ARGS_0
/** \} */
/* ------------------------------------------------------------------------- */
/** \name Implement: `BLI_string_joinN(..)`
* \{ */
/**
* Join an array of strings into a newly allocated, null terminated string.
*/
char *BLI_string_join_arrayN(const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
#define BLI_string_joinN(...) VA_NARGS_CALL_OVERLOAD(_BLI_string_joinN_, __VA_ARGS__)
#define _BLI_STRING_ARGS_0
BLI_INLINE char *_BLI_string_joinN_1(_BLI_STRING_ARGS_1) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_2(_BLI_STRING_ARGS_2) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_3(_BLI_STRING_ARGS_3) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_4(_BLI_STRING_ARGS_4) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_5(_BLI_STRING_ARGS_5) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_6(_BLI_STRING_ARGS_6) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_7(_BLI_STRING_ARGS_7) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_8(_BLI_STRING_ARGS_8) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_9(_BLI_STRING_ARGS_9) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_10(_BLI_STRING_ARGS_10) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_joinN_1(_BLI_STRING_ARGS_1)
{
const char *string_array[] = {a};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_2(_BLI_STRING_ARGS_2)
{
const char *string_array[] = {a, b};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_3(_BLI_STRING_ARGS_3)
{
const char *string_array[] = {a, b, c};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_4(_BLI_STRING_ARGS_4)
{
const char *string_array[] = {a, b, c, d};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_5(_BLI_STRING_ARGS_5)
{
const char *string_array[] = {a, b, c, d, e};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_6(_BLI_STRING_ARGS_6)
{
const char *string_array[] = {a, b, c, d, e, f};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_7(_BLI_STRING_ARGS_7)
{
const char *string_array[] = {a, b, c, d, e, f, g};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_8(_BLI_STRING_ARGS_8)
{
const char *string_array[] = {a, b, c, d, e, f, g, h};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_9(_BLI_STRING_ARGS_9)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_joinN_10(_BLI_STRING_ARGS_10)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
}
#undef _BLI_STRING_ARGS_0
/** \} */
/* ------------------------------------------------------------------------- */
/** \name Implement: `BLI_string_join_by_sep_char(..)`
* \{ */
/**
* A version of #BLI_string_join_array that takes a separator which can be any character
* including '\0'.
*/
size_t BLI_string_join_array_by_sep_char(char *result,
size_t result_len,
char sep,
const char *strings[],
uint strings_len) ATTR_NONNULL();
#define BLI_string_join_by_sep_char(...) \
VA_NARGS_CALL_OVERLOAD(_BLI_string_join_by_sep_char_, __VA_ARGS__)
#define _BLI_STRING_ARGS_0 char *__restrict dst, const size_t dst_len, const char sep,
BLI_INLINE size_t _BLI_string_join_by_sep_char_4(_BLI_STRING_ARGS_1) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_5(_BLI_STRING_ARGS_2) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_6(_BLI_STRING_ARGS_3) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_7(_BLI_STRING_ARGS_4) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_8(_BLI_STRING_ARGS_5) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_9(_BLI_STRING_ARGS_6) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_10(_BLI_STRING_ARGS_7) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_11(_BLI_STRING_ARGS_8) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_12(_BLI_STRING_ARGS_9) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_13(_BLI_STRING_ARGS_10) ATTR_NONNULL();
BLI_INLINE size_t _BLI_string_join_by_sep_char_4(_BLI_STRING_ARGS_1)
{
const char *string_array[] = {a};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_5(_BLI_STRING_ARGS_2)
{
const char *string_array[] = {a, b};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_6(_BLI_STRING_ARGS_3)
{
const char *string_array[] = {a, b, c};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_7(_BLI_STRING_ARGS_4)
{
const char *string_array[] = {a, b, c, d};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_8(_BLI_STRING_ARGS_5)
{
const char *string_array[] = {a, b, c, d, e};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_9(_BLI_STRING_ARGS_6)
{
const char *string_array[] = {a, b, c, d, e, f};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_10(_BLI_STRING_ARGS_7)
{
const char *string_array[] = {a, b, c, d, e, f, g};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_11(_BLI_STRING_ARGS_8)
{
const char *string_array[] = {a, b, c, d, e, f, g, h};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_12(_BLI_STRING_ARGS_9)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE size_t _BLI_string_join_by_sep_char_13(_BLI_STRING_ARGS_10)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
return BLI_string_join_array_by_sep_char(
dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
}
#undef _BLI_STRING_ARGS_0
/** \} */
/* ------------------------------------------------------------------------- */
/** \name Implement: `BLI_string_join_by_sep_charN(..)`
* \{ */
/**
* A version of #BLI_string_join_by_sep_char 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) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#define BLI_string_join_by_sep_charN(...) \
VA_NARGS_CALL_OVERLOAD(_BLI_string_join_by_sep_charN_, __VA_ARGS__)
#define _BLI_STRING_ARGS_0 const char sep,
BLI_INLINE char *_BLI_string_join_by_sep_charN_2(_BLI_STRING_ARGS_1) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_3(_BLI_STRING_ARGS_2) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_4(_BLI_STRING_ARGS_3) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_5(_BLI_STRING_ARGS_4) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_6(_BLI_STRING_ARGS_5) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_7(_BLI_STRING_ARGS_6) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_8(_BLI_STRING_ARGS_7) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_9(_BLI_STRING_ARGS_8) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_10(_BLI_STRING_ARGS_9) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_11(_BLI_STRING_ARGS_10) ATTR_NONNULL();
BLI_INLINE char *_BLI_string_join_by_sep_charN_2(_BLI_STRING_ARGS_1)
{
const char *string_array[] = {a};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_3(_BLI_STRING_ARGS_2)
{
const char *string_array[] = {a, b};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_4(_BLI_STRING_ARGS_3)
{
const char *string_array[] = {a, b, c};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_5(_BLI_STRING_ARGS_4)
{
const char *string_array[] = {a, b, c, d};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_6(_BLI_STRING_ARGS_5)
{
const char *string_array[] = {a, b, c, d, e};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_7(_BLI_STRING_ARGS_6)
{
const char *string_array[] = {a, b, c, d, e, f};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_8(_BLI_STRING_ARGS_7)
{
const char *string_array[] = {a, b, c, d, e, f, g};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_9(_BLI_STRING_ARGS_8)
{
const char *string_array[] = {a, b, c, d, e, f, g, h};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_10(_BLI_STRING_ARGS_9)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
BLI_INLINE char *_BLI_string_join_by_sep_charN_11(_BLI_STRING_ARGS_10)
{
const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
}
/** \} */
#undef _BLI_STRING_ARGS_0
#ifdef __cplusplus
}
#endif

View File

@ -344,10 +344,10 @@ bool BLI_uniquename(
*
* \{ */
char *BLI_string_join_array(char *result,
size_t result_len,
const char *strings[],
uint strings_len)
size_t BLI_string_join_array(char *result,
size_t result_len,
const char *strings[],
uint strings_len)
{
char *c = result;
char *c_end = &result[result_len - 1];
@ -358,10 +358,10 @@ char *BLI_string_join_array(char *result,
}
}
*c = '\0';
return c;
return (size_t)(c - result);
}
char *BLI_string_join_array_by_sep_char(
size_t BLI_string_join_array_by_sep_char(
char *result, size_t result_len, char sep, const char *strings[], uint strings_len)
{
char *c = result;
@ -378,7 +378,7 @@ char *BLI_string_join_array_by_sep_char(
}
}
*c = '\0';
return c;
return (size_t)(c - result);
}
char *BLI_string_join_arrayN(const char *strings[], uint strings_len)

View File

@ -890,8 +890,7 @@ static size_t draw_seq_text_get_overlay_string(const Scene *scene,
BLI_assert(i <= ARRAY_SIZE(text_array));
return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i) -
r_overlay_string;
return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i);
}
/* Draw info text on a sequence strip. */