code cleanup: remove redundant NULL checks and avoid writing to the source string.

also rename BLI_replacestr() -> BLI_replacestrN() since it returns an allocated buffer.
This commit is contained in:
Campbell Barton
2013-07-27 14:05:59 +00:00
parent d403537fc4
commit 6aa001f48d
2 changed files with 19 additions and 26 deletions

View File

@@ -86,7 +86,7 @@ __attribute__((nonnull))
#endif
;
char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))

View File

@@ -305,34 +305,30 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
}
/**
* string with all instances of substr_old replaced with substr_new,
* Returns a copy of the cstring \a str into a newly mallocN'd
* string with all instances of oldText replaced with newText,
* 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 oldText in
* \param oldText The text in the string to find and replace
* \param newText The text in the string to find and replace
* \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_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
{
DynStr *ds = NULL;
size_t lenOld = strlen(oldText);
char *match;
/* sanity checks */
if ((str == NULL) || (str[0] == 0))
return NULL;
else if ((oldText == NULL) || (newText == NULL) || (oldText[0] == 0))
return BLI_strdup(str);
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 substring that we're searching for,
* keep dicing and replacing
*/
while ( (match = strstr(str, oldText)) ) {
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();
@@ -341,27 +337,24 @@ char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const
* copy the text up to this position and advance the current position in the string
*/
if (str != match) {
/* replace the token at the 'match' position with \0 so that the copied string will be ok,
* add the segment of the string from str to match to the buffer, then restore the value at match
/* add the segment of the string from str to match to the buffer, then restore the value at match
*/
match[0] = 0;
BLI_dynstr_append(ds, str);
match[0] = oldText[0];
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, newText);
BLI_dynstr_append(ds, substr_new);
/* advance the current position of the string up to the end of the replaced segment */
str += lenOld;
str += len_old;
}
/* finish off and return a new string that has had all occurrences of */
if (ds) {
char *newStr;
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
@@ -370,10 +363,10 @@ char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const
BLI_dynstr_append(ds, str);
/* convert to new c-string (MEM_malloc'd), and free the buffer */
newStr = BLI_dynstr_get_cstring(ds);
str_new = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
return newStr;
return str_new;
}
else {
/* just create a new copy of the entire string - we avoid going through the assembly buffer