Cleanup: move BLI_str_replace into BLI_string_utils.h
String search & replace is a higher level function (unlike BLI_string.h) which handlers lower level replacements for printing and string copying. Also use BLI_string_* prefix (matching other utilities). This makes it possible to use BLI_string in Blender's internal utilities without depending on DynStr, MemArena... etc.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_polyfill_2d.h"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
@@ -2686,7 +2687,7 @@ static void make_element_name(const char *obname, const char *name, const int ma
|
||||
SNPRINTF(str, "%s_%s", obname, name);
|
||||
|
||||
/* Replace any point by underscore. */
|
||||
BLI_str_replace_char(str, '.', '_');
|
||||
BLI_string_replace_char(str, '.', '_');
|
||||
|
||||
BLI_strncpy_utf8(r_name, str, maxlen);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
@@ -3586,11 +3587,11 @@ char *BKE_image_get_tile_strformat(const char *filepath, eUDIM_TILE_FORMAT *r_ti
|
||||
|
||||
if (strstr(filepath, "<UDIM>") != nullptr) {
|
||||
*r_tile_format = UDIM_TILE_FORMAT_UDIM;
|
||||
return BLI_str_replaceN(filepath, "<UDIM>", "%d");
|
||||
return BLI_string_replaceN(filepath, "<UDIM>", "%d");
|
||||
}
|
||||
if (strstr(filepath, "<UVTILE>") != nullptr) {
|
||||
*r_tile_format = UDIM_TILE_FORMAT_UVTILE;
|
||||
return BLI_str_replaceN(filepath, "<UVTILE>", "u%d_v%d");
|
||||
return BLI_string_replaceN(filepath, "<UVTILE>", "u%d_v%d");
|
||||
}
|
||||
|
||||
*r_tile_format = UDIM_TILE_FORMAT_NONE;
|
||||
|
||||
@@ -2503,7 +2503,7 @@ static void viewlayer_aov_make_name_unique(ViewLayer *view_layer)
|
||||
|
||||
/* Don't allow dots, it's incompatible with OpenEXR convention to store channels
|
||||
* as "layer.pass.channel". */
|
||||
BLI_str_replace_char(aov->name, '.', '_');
|
||||
BLI_string_replace_char(aov->name, '.', '_');
|
||||
BLI_uniquename(
|
||||
&view_layer->aovs, aov, DATA_("AOV"), '_', offsetof(ViewLayerAOV, name), sizeof(aov->name));
|
||||
}
|
||||
@@ -2620,7 +2620,7 @@ static void viewlayer_lightgroup_make_name_unique(ViewLayer *view_layer,
|
||||
{
|
||||
/* Don't allow dots, it's incompatible with OpenEXR convention to store channels
|
||||
* as "layer.pass.channel". */
|
||||
BLI_str_replace_char(lightgroup->name, '.', '_');
|
||||
BLI_string_replace_char(lightgroup->name, '.', '_');
|
||||
BLI_uniquename(&view_layer->lightgroups,
|
||||
lightgroup,
|
||||
DATA_("Lightgroup"),
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "BLI_fileops.hh"
|
||||
#include "BLI_hash_md5.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
namespace blender::bke::sim {
|
||||
|
||||
@@ -78,7 +79,7 @@ void ModifierSimulationCache::try_discover_bake(const StringRefNull absolute_bak
|
||||
}
|
||||
char modified_file_name[FILE_MAX];
|
||||
STRNCPY(modified_file_name, dir_entry.relname);
|
||||
BLI_str_replace_char(modified_file_name, '_', '.');
|
||||
BLI_string_replace_char(modified_file_name, '_', '.');
|
||||
|
||||
const SubFrame frame = std::stof(modified_file_name);
|
||||
|
||||
|
||||
@@ -541,7 +541,7 @@ void BKE_workspace_tool_id_replace_table(WorkSpace *workspace,
|
||||
}
|
||||
idname_suffix += idname_prefix_len;
|
||||
}
|
||||
BLI_str_replace_table_exact(
|
||||
BLI_string_replace_table_exact(
|
||||
idname_suffix, idname_suffix_len, replace_table, replace_table_num);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,53 +160,6 @@ bool BLI_str_quoted_substr(const char *__restrict str,
|
||||
const char *__restrict prefix,
|
||||
char *result,
|
||||
size_t result_maxncpy);
|
||||
/**
|
||||
* string with all instances of substr_old replaced with substr_new,
|
||||
* Returns a copy of the c-string \a str into a newly #MEM_mallocN'd
|
||||
* and returns it.
|
||||
*
|
||||
* \note A rather wasteful string-replacement utility, though this shall do for now.
|
||||
* Feel free to replace this with an even safe + nicer alternative
|
||||
*
|
||||
* \param str: The string to replace occurrences of substr_old in
|
||||
* \param substr_old: The text in the string to find and replace
|
||||
* \param substr_new: The text in the string to find and replace
|
||||
* \retval Returns the duplicated string
|
||||
*/
|
||||
char *BLI_str_replaceN(const char *__restrict str,
|
||||
const char *__restrict substr_old,
|
||||
const char *__restrict substr_new) ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_NONNULL(1, 2, 3) ATTR_MALLOC;
|
||||
|
||||
/**
|
||||
* In-place replace every \a src to \a dst in \a str.
|
||||
*
|
||||
* \param str: The string to operate on.
|
||||
* \param src: The character to replace.
|
||||
* \param dst: The character to replace with.
|
||||
*/
|
||||
void BLI_str_replace_char(char *str, char src, char dst) ATTR_NONNULL(1);
|
||||
|
||||
/**
|
||||
* Simple exact-match string replacement.
|
||||
*
|
||||
* \param replace_table: Array of source, destination pairs.
|
||||
*
|
||||
* \note Larger tables should use a hash table.
|
||||
*/
|
||||
bool BLI_str_replace_table_exact(char *string,
|
||||
size_t string_len,
|
||||
const char *replace_table[][2],
|
||||
int replace_table_len);
|
||||
|
||||
/**
|
||||
* Write `dst` into the range between `src_beg` & `src_end`,
|
||||
* resize within `string_maxncpy` limits, ensure null terminated.
|
||||
*
|
||||
* \return the length of `string`.
|
||||
*/
|
||||
size_t BLI_str_replace_range(
|
||||
char *string, size_t string_maxncpy, int src_beg, int src_end, const char *dst);
|
||||
|
||||
/**
|
||||
* Portable replacement for #snprintf
|
||||
|
||||
@@ -21,6 +21,64 @@ struct ListBase;
|
||||
|
||||
typedef bool (*UniquenameCheckCallback)(void *arg, const char *name);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/** \name String Replace
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* string with all instances of substr_old replaced with substr_new,
|
||||
* Returns a copy of the c-string \a str into a newly #MEM_mallocN'd
|
||||
* and returns it.
|
||||
*
|
||||
* \note A rather wasteful string-replacement utility, though this shall do for now.
|
||||
* Feel free to replace this with an even safe + nicer alternative
|
||||
*
|
||||
* \param str: The string to replace occurrences of substr_old in
|
||||
* \param substr_old: The text in the string to find and replace
|
||||
* \param substr_new: The text in the string to find and replace
|
||||
* \retval Returns the duplicated string
|
||||
*/
|
||||
char *BLI_string_replaceN(const char *__restrict str,
|
||||
const char *__restrict substr_old,
|
||||
const char *__restrict substr_new) ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_NONNULL(1, 2, 3) ATTR_MALLOC;
|
||||
|
||||
/**
|
||||
* In-place replace every \a src to \a dst in \a str.
|
||||
*
|
||||
* \param str: The string to operate on.
|
||||
* \param src: The character to replace.
|
||||
* \param dst: The character to replace with.
|
||||
*/
|
||||
void BLI_string_replace_char(char *str, char src, char dst) ATTR_NONNULL(1);
|
||||
|
||||
/**
|
||||
* Simple exact-match string replacement.
|
||||
*
|
||||
* \param replace_table: Array of source, destination pairs.
|
||||
*
|
||||
* \note Larger tables should use a hash table.
|
||||
*/
|
||||
bool BLI_string_replace_table_exact(char *string,
|
||||
size_t string_len,
|
||||
const char *replace_table[][2],
|
||||
int replace_table_len);
|
||||
|
||||
/**
|
||||
* Write `dst` into the range between `src_beg` & `src_end`,
|
||||
* resize within `string_maxncpy` limits, ensure null terminated.
|
||||
*
|
||||
* \return the length of `string`.
|
||||
*/
|
||||
size_t BLI_string_replace_range(
|
||||
char *string, size_t string_maxncpy, int src_beg, int src_end, const char *dst);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/** \name String Split
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Looks for a numeric suffix preceded by `delim` character on the end of
|
||||
* name, puts preceding part into *left and value of suffix into *nr.
|
||||
@@ -51,6 +109,8 @@ void BLI_string_split_suffix(const char *string, size_t string_maxlen, char *r_b
|
||||
void BLI_string_split_prefix(const char *string, size_t string_maxlen, char *r_pre, char *r_body)
|
||||
ATTR_NONNULL(1, 3, 4);
|
||||
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -723,8 +724,8 @@ void BLI_path_rel(char path[FILE_MAX], const char *basepath)
|
||||
STRNCPY(temp, basepath);
|
||||
#endif
|
||||
|
||||
BLI_str_replace_char(temp + BLI_path_unc_prefix_len(temp), '\\', '/');
|
||||
BLI_str_replace_char(path + BLI_path_unc_prefix_len(path), '\\', '/');
|
||||
BLI_string_replace_char(temp + BLI_path_unc_prefix_len(temp), '\\', '/');
|
||||
BLI_string_replace_char(path + BLI_path_unc_prefix_len(path), '\\', '/');
|
||||
|
||||
/* Remove `/./` which confuse the following slash counting. */
|
||||
BLI_path_normalize(path);
|
||||
@@ -790,7 +791,7 @@ void BLI_path_rel(char path[FILE_MAX], const char *basepath)
|
||||
r += BLI_strncpy_rlen(r, q + 1, sizeof(res) - (r - res));
|
||||
|
||||
#ifdef WIN32
|
||||
BLI_str_replace_char(res + 2, '/', '\\');
|
||||
BLI_string_replace_char(res + 2, '/', '\\');
|
||||
#endif
|
||||
BLI_strncpy(path, res, FILE_MAX);
|
||||
}
|
||||
@@ -964,7 +965,7 @@ bool BLI_path_frame(char *path, size_t path_maxncpy, int frame, int digits)
|
||||
char frame_str[FILENAME_FRAME_CHARS_MAX + 1]; /* One for null. */
|
||||
const int ch_span = MIN2(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX);
|
||||
SNPRINTF(frame_str, "%.*d", ch_span, frame);
|
||||
BLI_str_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str);
|
||||
BLI_string_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -984,7 +985,7 @@ bool BLI_path_frame_range(char *path, size_t path_maxncpy, int sta, int end, int
|
||||
char frame_str[(FILENAME_FRAME_CHARS_MAX * 2) + 1 + 1]; /* One for null, one for the '-' */
|
||||
const int ch_span = MIN2(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX);
|
||||
SNPRINTF(frame_str, "%.*d-%.*d", ch_span, sta, ch_span, end);
|
||||
BLI_str_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str);
|
||||
BLI_string_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1066,7 +1067,7 @@ void BLI_path_to_display_name(char *display_name, int display_name_maxncpy, cons
|
||||
BLI_strncpy(display_name, name + strip_offset, display_name_maxncpy);
|
||||
|
||||
/* Replace underscores with spaces. */
|
||||
BLI_str_replace_char(display_name, '_', ' ');
|
||||
BLI_string_replace_char(display_name, '_', ' ');
|
||||
|
||||
BLI_path_extension_strip(display_name);
|
||||
|
||||
@@ -1150,7 +1151,7 @@ bool BLI_path_abs(char path[FILE_MAX], const char *basepath)
|
||||
* NOTE(@elubie): For UNC paths the first characters containing the UNC prefix
|
||||
* shouldn't be switched as we need to distinguish them from
|
||||
* paths relative to the `.blend` file. */
|
||||
BLI_str_replace_char(tmp + BLI_path_unc_prefix_len(tmp), '\\', '/');
|
||||
BLI_string_replace_char(tmp + BLI_path_unc_prefix_len(tmp), '\\', '/');
|
||||
|
||||
/* Paths starting with `//` will get the blend file as their base,
|
||||
* this isn't standard in any OS but is used in blender all over the place. */
|
||||
@@ -1161,7 +1162,7 @@ bool BLI_path_abs(char path[FILE_MAX], const char *basepath)
|
||||
/* File component is ignored, so don't bother with the trailing slash. */
|
||||
BLI_path_normalize(base);
|
||||
lslash = BLI_path_slash_rfind(base);
|
||||
BLI_str_replace_char(base + BLI_path_unc_prefix_len(base), '\\', '/');
|
||||
BLI_string_replace_char(base + BLI_path_unc_prefix_len(base), '\\', '/');
|
||||
|
||||
if (lslash) {
|
||||
/* Length up to and including last `/`. */
|
||||
@@ -1187,7 +1188,7 @@ bool BLI_path_abs(char path[FILE_MAX], const char *basepath)
|
||||
/* NOTE(@jesterking): Skip first two chars, which in case of absolute path will
|
||||
* be `drive:/blabla` and in case of `relpath` `//blabla/`.
|
||||
* So `relpath` `//` will be retained, rest will be nice and shiny WIN32 backward slashes. */
|
||||
BLI_str_replace_char(path + 2, '/', '\\');
|
||||
BLI_string_replace_char(path + 2, '/', '\\');
|
||||
#endif
|
||||
|
||||
/* Ensure this is after correcting for path switch. */
|
||||
@@ -1968,10 +1969,10 @@ void BLI_path_slash_native(char *path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (path && BLI_strnlen(path, 3) > 2) {
|
||||
BLI_str_replace_char(path + 2, ALTSEP, SEP);
|
||||
BLI_string_replace_char(path + 2, ALTSEP, SEP);
|
||||
}
|
||||
#else
|
||||
BLI_str_replace_char(path + BLI_path_unc_prefix_len(path), ALTSEP, SEP);
|
||||
BLI_string_replace_char(path + BLI_path_unc_prefix_len(path), ALTSEP, SEP);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
@@ -528,142 +527,6 @@ bool BLI_str_quoted_substr(const char *__restrict str,
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name String Replace
|
||||
* \{ */
|
||||
|
||||
char *BLI_str_replaceN(const char *__restrict str,
|
||||
const char *__restrict substr_old,
|
||||
const char *__restrict substr_new)
|
||||
{
|
||||
DynStr *ds = NULL;
|
||||
size_t len_old = strlen(substr_old);
|
||||
const char *match;
|
||||
|
||||
BLI_assert(substr_old[0] != '\0');
|
||||
|
||||
/* While we can still find a match for the old sub-string that we're searching for,
|
||||
* keep dicing and replacing. */
|
||||
while ((match = strstr(str, substr_old))) {
|
||||
/* the assembly buffer only gets created when we actually need to rebuild the string */
|
||||
if (ds == NULL) {
|
||||
ds = BLI_dynstr_new();
|
||||
}
|
||||
|
||||
/* If the match position does not match the current position in the string,
|
||||
* copy the text up to this position and advance the current position in the string. */
|
||||
if (str != match) {
|
||||
/* Add the segment of the string from `str` to match to the buffer,
|
||||
* then restore the value at match. */
|
||||
BLI_dynstr_nappend(ds, str, (match - str));
|
||||
|
||||
/* now our current position should be set on the start of the match */
|
||||
str = match;
|
||||
}
|
||||
|
||||
/* Add the replacement text to the accumulation buffer. */
|
||||
BLI_dynstr_append(ds, substr_new);
|
||||
|
||||
/* Advance the current position of the string up to the end of the replaced segment. */
|
||||
str += len_old;
|
||||
}
|
||||
|
||||
/* Finish off and return a new string that has had all occurrences of. */
|
||||
if (ds) {
|
||||
char *str_new;
|
||||
|
||||
/* Add what's left of the string to the assembly buffer
|
||||
* - we've been adjusting `str` to point at the end of the replaced segments. */
|
||||
BLI_dynstr_append(ds, str);
|
||||
|
||||
/* Convert to new c-string (MEM_malloc'd), and free the buffer. */
|
||||
str_new = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
return str_new;
|
||||
}
|
||||
/* Just create a new copy of the entire string - we avoid going through the assembly buffer
|
||||
* for what should be a bit more efficiency. */
|
||||
return BLI_strdup(str);
|
||||
}
|
||||
|
||||
void BLI_str_replace_char(char *str, char src, char dst)
|
||||
{
|
||||
while (*str) {
|
||||
if (*str == src) {
|
||||
*str = dst;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
bool BLI_str_replace_table_exact(char *string,
|
||||
const size_t string_maxncpy,
|
||||
const char *replace_table[][2],
|
||||
int replace_table_len)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(string, string_maxncpy);
|
||||
|
||||
for (int i = 0; i < replace_table_len; i++) {
|
||||
if (STREQ(string, replace_table[i][0])) {
|
||||
BLI_strncpy(string, replace_table[i][1], string_maxncpy);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t BLI_str_replace_range(
|
||||
char *string, size_t string_maxncpy, int src_beg, int src_end, const char *dst)
|
||||
{
|
||||
int string_len = strlen(string);
|
||||
BLI_assert(src_beg <= src_end);
|
||||
BLI_assert(src_end <= string_len);
|
||||
const int src_len = src_end - src_beg;
|
||||
int dst_len = strlen(dst);
|
||||
|
||||
if (src_len < dst_len) {
|
||||
/* Grow, first handle special cases. */
|
||||
|
||||
/* Special case, the src_end is entirely clipped. */
|
||||
if (UNLIKELY(string_maxncpy <= src_beg + dst_len)) {
|
||||
/* There is only room for the destination. */
|
||||
dst_len = ((int)string_maxncpy - src_beg) - 1;
|
||||
string_len = src_end;
|
||||
string[string_len] = '\0';
|
||||
}
|
||||
|
||||
const int ofs = dst_len - src_len;
|
||||
/* Clip the string when inserting the destination string exceeds `string_maxncpy`. */
|
||||
if (string_len + ofs >= string_maxncpy) {
|
||||
string_len = ((int)string_maxncpy - ofs) - 1;
|
||||
string[string_len] = '\0';
|
||||
BLI_assert(src_end <= string_len);
|
||||
}
|
||||
|
||||
/* Grow. */
|
||||
memmove(string + (src_end + ofs), string + src_end, (size_t)(string_len - src_end) + 1);
|
||||
string_len += ofs;
|
||||
}
|
||||
else if (src_len > dst_len) {
|
||||
/* Shrink. */
|
||||
const int ofs = src_len - dst_len;
|
||||
memmove(string + (src_end - ofs), string + src_end, (size_t)(string_len - src_end) + 1);
|
||||
string_len -= ofs;
|
||||
}
|
||||
else { /* Simple case, no resizing. */
|
||||
BLI_assert(src_len == dst_len);
|
||||
}
|
||||
|
||||
if (dst_len > 0) {
|
||||
memcpy(string + src_beg, dst, (size_t)dst_len);
|
||||
}
|
||||
BLI_assert(string[string_len] == '\0');
|
||||
return (size_t)string_len;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name String Comparison/Matching
|
||||
* \{ */
|
||||
|
||||
@@ -17,12 +17,150 @@
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_dynstr.h"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic error "-Wsign-conversion"
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name String Replace
|
||||
* \{ */
|
||||
|
||||
char *BLI_string_replaceN(const char *__restrict str,
|
||||
const char *__restrict substr_old,
|
||||
const char *__restrict substr_new)
|
||||
{
|
||||
DynStr *ds = NULL;
|
||||
size_t len_old = strlen(substr_old);
|
||||
const char *match;
|
||||
|
||||
BLI_assert(substr_old[0] != '\0');
|
||||
|
||||
/* While we can still find a match for the old sub-string that we're searching for,
|
||||
* keep dicing and replacing. */
|
||||
while ((match = strstr(str, substr_old))) {
|
||||
/* the assembly buffer only gets created when we actually need to rebuild the string */
|
||||
if (ds == NULL) {
|
||||
ds = BLI_dynstr_new();
|
||||
}
|
||||
|
||||
/* If the match position does not match the current position in the string,
|
||||
* copy the text up to this position and advance the current position in the string. */
|
||||
if (str != match) {
|
||||
/* Add the segment of the string from `str` to match to the buffer,
|
||||
* then restore the value at match. */
|
||||
BLI_dynstr_nappend(ds, str, (match - str));
|
||||
|
||||
/* now our current position should be set on the start of the match */
|
||||
str = match;
|
||||
}
|
||||
|
||||
/* Add the replacement text to the accumulation buffer. */
|
||||
BLI_dynstr_append(ds, substr_new);
|
||||
|
||||
/* Advance the current position of the string up to the end of the replaced segment. */
|
||||
str += len_old;
|
||||
}
|
||||
|
||||
/* Finish off and return a new string that has had all occurrences of. */
|
||||
if (ds) {
|
||||
char *str_new;
|
||||
|
||||
/* Add what's left of the string to the assembly buffer
|
||||
* - we've been adjusting `str` to point at the end of the replaced segments. */
|
||||
BLI_dynstr_append(ds, str);
|
||||
|
||||
/* Convert to new c-string (MEM_malloc'd), and free the buffer. */
|
||||
str_new = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
return str_new;
|
||||
}
|
||||
/* Just create a new copy of the entire string - we avoid going through the assembly buffer
|
||||
* for what should be a bit more efficiency. */
|
||||
return BLI_strdup(str);
|
||||
}
|
||||
|
||||
void BLI_string_replace_char(char *str, char src, char dst)
|
||||
{
|
||||
while (*str) {
|
||||
if (*str == src) {
|
||||
*str = dst;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
bool BLI_string_replace_table_exact(char *string,
|
||||
const size_t string_maxncpy,
|
||||
const char *replace_table[][2],
|
||||
int replace_table_len)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(string, string_maxncpy);
|
||||
|
||||
for (int i = 0; i < replace_table_len; i++) {
|
||||
if (STREQ(string, replace_table[i][0])) {
|
||||
BLI_strncpy(string, replace_table[i][1], string_maxncpy);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t BLI_string_replace_range(
|
||||
char *string, size_t string_maxncpy, int src_beg, int src_end, const char *dst)
|
||||
{
|
||||
int string_len = strlen(string);
|
||||
BLI_assert(src_beg <= src_end);
|
||||
BLI_assert(src_end <= string_len);
|
||||
const int src_len = src_end - src_beg;
|
||||
int dst_len = strlen(dst);
|
||||
|
||||
if (src_len < dst_len) {
|
||||
/* Grow, first handle special cases. */
|
||||
|
||||
/* Special case, the src_end is entirely clipped. */
|
||||
if (UNLIKELY(string_maxncpy <= src_beg + dst_len)) {
|
||||
/* There is only room for the destination. */
|
||||
dst_len = ((int)string_maxncpy - src_beg) - 1;
|
||||
string_len = src_end;
|
||||
string[string_len] = '\0';
|
||||
}
|
||||
|
||||
const int ofs = dst_len - src_len;
|
||||
/* Clip the string when inserting the destination string exceeds `string_maxncpy`. */
|
||||
if (string_len + ofs >= string_maxncpy) {
|
||||
string_len = ((int)string_maxncpy - ofs) - 1;
|
||||
string[string_len] = '\0';
|
||||
BLI_assert(src_end <= string_len);
|
||||
}
|
||||
|
||||
/* Grow. */
|
||||
memmove(string + (src_end + ofs), string + src_end, (size_t)(string_len - src_end) + 1);
|
||||
string_len += ofs;
|
||||
}
|
||||
else if (src_len > dst_len) {
|
||||
/* Shrink. */
|
||||
const int ofs = src_len - dst_len;
|
||||
memmove(string + (src_end - ofs), string + src_end, (size_t)(string_len - src_end) + 1);
|
||||
string_len -= ofs;
|
||||
}
|
||||
else { /* Simple case, no resizing. */
|
||||
BLI_assert(src_len == dst_len);
|
||||
}
|
||||
|
||||
if (dst_len > 0) {
|
||||
memcpy(string + src_beg, dst, (size_t)dst_len);
|
||||
}
|
||||
BLI_assert(string[string_len] == '\0');
|
||||
return (size_t)string_len;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
size_t BLI_string_split_name_number(const char *name,
|
||||
const char delim,
|
||||
char *r_name_left,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "BLI_array_utils.h"
|
||||
#include "BLI_memiter.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "BLI_ressource_strings.h"
|
||||
#include "BLI_string.h"
|
||||
@@ -100,7 +101,7 @@ static void memiter_words10k_test(const char split_char, const int chunk_size)
|
||||
{
|
||||
const int words_len = sizeof(words10k) - 1;
|
||||
char *words = BLI_strdupn(words10k, words_len);
|
||||
BLI_str_replace_char(words, split_char, '\0');
|
||||
BLI_string_replace_char(words, split_char, '\0');
|
||||
|
||||
BLI_memiter *mi = BLI_memiter_create(chunk_size);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Local Utilities
|
||||
@@ -25,7 +26,7 @@ static void str_replace_char_with_relative_exception(char *str, char src, char d
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_str_replace_char(str, src, dst);
|
||||
BLI_string_replace_char(str, src, dst);
|
||||
}
|
||||
|
||||
static char *str_replace_char_strdup(const char *str, char src, char dst)
|
||||
@@ -34,7 +35,7 @@ static char *str_replace_char_strdup(const char *str, char src, char dst)
|
||||
return nullptr;
|
||||
}
|
||||
char *str_dupe = strdup(str);
|
||||
BLI_str_replace_char(str_dupe, src, dst);
|
||||
BLI_string_replace_char(str_dupe, src, dst);
|
||||
return str_dupe;
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ static char *str_replace_char_strdup(const char *str, char src, char dst)
|
||||
} \
|
||||
const int path_len_test = BLI_path_normalize(path); \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(path, '\\', '/'); \
|
||||
BLI_string_replace_char(path, '\\', '/'); \
|
||||
} \
|
||||
EXPECT_STREQ(path, output_expect); \
|
||||
EXPECT_EQ(path_len_test, strlen(path)); \
|
||||
@@ -190,11 +191,11 @@ TEST(path_util, CompareNormalized)
|
||||
{ \
|
||||
char path[FILE_MAX] = input; \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(path, '/', '\\'); \
|
||||
BLI_string_replace_char(path, '/', '\\'); \
|
||||
} \
|
||||
BLI_path_parent_dir(path); \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(path, '\\', '/'); \
|
||||
BLI_string_replace_char(path, '\\', '/'); \
|
||||
} \
|
||||
EXPECT_STREQ(path, output_expect); \
|
||||
} \
|
||||
@@ -251,7 +252,7 @@ TEST(path_util, ParentDir_Complex)
|
||||
char path[] = str_input; \
|
||||
/* Test input assumes forward slash, support back-slash on WIN32. */ \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(path, '/', '\\'); \
|
||||
BLI_string_replace_char(path, '/', '\\'); \
|
||||
} \
|
||||
const char *expect = str_expect; \
|
||||
int index_output, len_output; \
|
||||
@@ -469,7 +470,7 @@ TEST(path_util, NameAtIndex_NoneComplexNeg)
|
||||
char *input_back_slash[ARRAY_SIZE(input_forward_slash)] = {nullptr}; \
|
||||
for (int i = 0; i < ARRAY_SIZE(input_forward_slash); i++) { \
|
||||
input_back_slash[i] = strdup(input_forward_slash[i]); \
|
||||
BLI_str_replace_char(input_back_slash[i], '/', '\\'); \
|
||||
BLI_string_replace_char(input_back_slash[i], '/', '\\'); \
|
||||
} \
|
||||
/* Check we don't write past the last byte. */ \
|
||||
result[out_size] = '\0'; \
|
||||
@@ -477,7 +478,7 @@ TEST(path_util, NameAtIndex_NoneComplexNeg)
|
||||
out_size, \
|
||||
const_cast<const char **>(input_back_slash), \
|
||||
ARRAY_SIZE(input_back_slash)); \
|
||||
BLI_str_replace_char(result, '\\', '/'); \
|
||||
BLI_string_replace_char(result, '\\', '/'); \
|
||||
EXPECT_STREQ(result, expect); \
|
||||
EXPECT_EQ(result[out_size], '\0'); \
|
||||
for (int i = 0; i < ARRAY_SIZE(input_forward_slash); i++) { \
|
||||
@@ -599,12 +600,12 @@ TEST(path_util, JoinRelativePrefix)
|
||||
char filename_native[] = filename; \
|
||||
/* Check we don't write past the last byte. */ \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(filename_native, '/', '\\'); \
|
||||
BLI_str_replace_char(result, '/', '\\'); \
|
||||
BLI_string_replace_char(filename_native, '/', '\\'); \
|
||||
BLI_string_replace_char(result, '/', '\\'); \
|
||||
} \
|
||||
BLI_path_append(result, size, filename_native); \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(result, '\\', '/'); \
|
||||
BLI_string_replace_char(result, '\\', '/'); \
|
||||
} \
|
||||
EXPECT_STREQ(result, expect); \
|
||||
} \
|
||||
@@ -1215,12 +1216,12 @@ TEST(path_util, Suffix)
|
||||
const char *ref_path_test = ref_path; \
|
||||
STRNCPY(path, abs_path); \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(path, '/', '\\'); \
|
||||
BLI_string_replace_char(path, '/', '\\'); \
|
||||
ref_path_test = str_replace_char_strdup(ref_path_test, '/', '\\'); \
|
||||
} \
|
||||
BLI_path_rel(path, ref_path_test); \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(path, '\\', '/'); \
|
||||
BLI_string_replace_char(path, '\\', '/'); \
|
||||
free((void *)ref_path_test); \
|
||||
} \
|
||||
EXPECT_STREQ(path, rel_path_expect); \
|
||||
|
||||
@@ -162,7 +162,7 @@ TEST(string, StrReplaceRange)
|
||||
#define STR_REPLACE_RANGE(src, size, beg, end, dst, result_expect) \
|
||||
{ \
|
||||
char string[size] = src; \
|
||||
BLI_str_replace_range(string, sizeof(string), beg, end, dst); \
|
||||
BLI_string_replace_range(string, sizeof(string), beg, end, dst); \
|
||||
EXPECT_STREQ(string, result_expect); \
|
||||
}
|
||||
|
||||
|
||||
@@ -364,10 +364,10 @@ static char *replace_bbone_easing_rnapath(char *old_path)
|
||||
* which happen be named after the bbone property id's
|
||||
*/
|
||||
if (strstr(old_path, "bbone_in")) {
|
||||
new_path = BLI_str_replaceN(old_path, "bbone_in", "bbone_easein");
|
||||
new_path = BLI_string_replaceN(old_path, "bbone_in", "bbone_easein");
|
||||
}
|
||||
else if (strstr(old_path, "bbone_out")) {
|
||||
new_path = BLI_str_replaceN(old_path, "bbone_out", "bbone_easeout");
|
||||
new_path = BLI_string_replaceN(old_path, "bbone_out", "bbone_easeout");
|
||||
}
|
||||
|
||||
if (new_path) {
|
||||
|
||||
@@ -462,7 +462,7 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis
|
||||
}
|
||||
}
|
||||
if (substr) {
|
||||
char *new_path = BLI_str_replaceN(fcu->rna_path, "speed_factor", substr);
|
||||
char *new_path = BLI_string_replaceN(fcu->rna_path, "speed_factor", substr);
|
||||
MEM_freeN(fcu->rna_path);
|
||||
fcu->rna_path = new_path;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
@@ -708,10 +709,10 @@ void blo_do_versions_userdef(UserDef *userdef)
|
||||
};
|
||||
const int replace_table_len = ARRAY_SIZE(replace_table);
|
||||
|
||||
BLI_str_replace_table_exact(
|
||||
BLI_string_replace_table_exact(
|
||||
userdef->keyconfigstr, sizeof(userdef->keyconfigstr), replace_table, replace_table_len);
|
||||
LISTBASE_FOREACH (wmKeyConfigPref *, kpt, &userdef->user_keyconfig_prefs) {
|
||||
BLI_str_replace_table_exact(
|
||||
BLI_string_replace_table_exact(
|
||||
kpt->idname, sizeof(kpt->idname), replace_table, replace_table_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ static void updateDuplicateActionConstraintSettings(
|
||||
|
||||
char *old_path = new_curve->rna_path;
|
||||
|
||||
new_curve->rna_path = BLI_str_replaceN(old_path, orig_bone->name, dup_bone->name);
|
||||
new_curve->rna_path = BLI_string_replaceN(old_path, orig_bone->name, dup_bone->name);
|
||||
MEM_freeN(old_path);
|
||||
|
||||
/* Flip the animation */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "BLI_fileops.hh"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_serialize.hh"
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "PIL_time.h"
|
||||
@@ -286,7 +287,7 @@ static void bake_simulation_job_startjob(void *customdata,
|
||||
|
||||
char frame_file_c_str[64];
|
||||
SNPRINTF(frame_file_c_str, "%011.5f", double(frame));
|
||||
BLI_str_replace_char(frame_file_c_str, '.', '_');
|
||||
BLI_string_replace_char(frame_file_c_str, '.', '_');
|
||||
const StringRefNull frame_file_str = frame_file_c_str;
|
||||
|
||||
BKE_scene_graph_update_for_newframe(job.depsgraph);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
@@ -1144,7 +1145,7 @@ static int view_layer_add_lightgroup_exec(bContext *C, wmOperator *op)
|
||||
if (RNA_struct_property_is_set(op->ptr, "name")) {
|
||||
RNA_string_get(op->ptr, "name", name);
|
||||
/* Ensure that there are no dots in the name. */
|
||||
BLI_str_replace_char(name, '.', '_');
|
||||
BLI_string_replace_char(name, '.', '_');
|
||||
LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
|
||||
if (STREQ(lightgroup->name, name)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "GPU_platform.h"
|
||||
|
||||
@@ -45,8 +46,8 @@ static char *create_key(eGPUSupportLevel support_level,
|
||||
|
||||
char *support_key = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
BLI_str_replace_char(support_key, '\n', ' ');
|
||||
BLI_str_replace_char(support_key, '\r', ' ');
|
||||
BLI_string_replace_char(support_key, '\n', ' ');
|
||||
BLI_string_replace_char(support_key, '\r', ' ');
|
||||
return support_key;
|
||||
}
|
||||
|
||||
@@ -57,8 +58,8 @@ static char *create_gpu_name(const char *vendor, const char *renderer, const cha
|
||||
|
||||
char *gpu_name = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
BLI_str_replace_char(gpu_name, '\n', ' ');
|
||||
BLI_str_replace_char(gpu_name, '\r', ' ');
|
||||
BLI_string_replace_char(gpu_name, '\n', ' ');
|
||||
BLI_string_replace_char(gpu_name, '\r', ' ');
|
||||
return gpu_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ static bool uri_from_filename(const char *path, char *uri)
|
||||
/* Not a correct absolute path with a drive letter or UNC prefix. */
|
||||
return false;
|
||||
}
|
||||
BLI_str_replace_char(orig_uri, '\\', '/');
|
||||
BLI_string_replace_char(orig_uri, '\\', '/');
|
||||
#else
|
||||
SNPRINTF(orig_uri, "file://%s", path);
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "BLI_memory_utils.hh"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
@@ -659,7 +660,7 @@ static std::string get_tex_image_asset_filepath(bNode *node,
|
||||
BLI_path_split_dir_part(stage_path.c_str(), dir_path, FILE_MAX);
|
||||
BLI_path_join(exp_path, FILE_MAX, dir_path, "textures", file_path);
|
||||
}
|
||||
BLI_str_replace_char(exp_path, '\\', '/');
|
||||
BLI_string_replace_char(exp_path, '\\', '/');
|
||||
return exp_path;
|
||||
}
|
||||
|
||||
@@ -678,7 +679,7 @@ static std::string get_tex_image_asset_filepath(bNode *node,
|
||||
if (!BLI_path_is_rel(rel_path)) {
|
||||
return path;
|
||||
}
|
||||
BLI_str_replace_char(rel_path, '\\', '/');
|
||||
BLI_string_replace_char(rel_path, '\\', '/');
|
||||
return rel_path + 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
|
||||
@@ -23,7 +24,7 @@ static std::string replace_all(const StringRefNull str,
|
||||
if (from.is_empty()) {
|
||||
return str;
|
||||
}
|
||||
char *new_str_ptr = BLI_str_replaceN(str.c_str(), from.c_str(), to.c_str());
|
||||
char *new_str_ptr = BLI_string_replaceN(str.c_str(), from.c_str(), to.c_str());
|
||||
std::string new_str{new_str_ptr};
|
||||
MEM_freeN(new_str_ptr);
|
||||
return new_str;
|
||||
|
||||
Reference in New Issue
Block a user