Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern/string_utils.c')
-rw-r--r--source/blender/blenlib/intern/string_utils.c589
1 files changed, 300 insertions, 289 deletions
diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c
index 46472d8125d..9b6ffd85341 100644
--- a/source/blender/blenlib/intern/string_utils.c
+++ b/source/blender/blenlib/intern/string_utils.c
@@ -34,7 +34,6 @@
#include "DNA_listBase.h"
-
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
#endif
@@ -55,37 +54,37 @@
*/
size_t BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
{
- const size_t name_len = strlen(name);
-
- *nr = 0;
- memcpy(left, name, (name_len + 1) * sizeof(char));
-
- /* name doesn't end with a delimiter "foo." */
- if ((name_len > 1 && name[name_len - 1] == delim) == 0) {
- size_t a = name_len;
- while (a--) {
- if (name[a] == delim) {
- left[a] = '\0'; /* truncate left part here */
- *nr = atol(name + a + 1);
- /* casting down to an int, can overflow for large numbers */
- if (*nr < 0) {
- *nr = 0;
- }
- return a;
- }
- else if (isdigit(name[a]) == 0) {
- /* non-numeric suffix - give up */
- break;
- }
- }
- }
-
- return name_len;
+ const size_t name_len = strlen(name);
+
+ *nr = 0;
+ memcpy(left, name, (name_len + 1) * sizeof(char));
+
+ /* name doesn't end with a delimiter "foo." */
+ if ((name_len > 1 && name[name_len - 1] == delim) == 0) {
+ size_t a = name_len;
+ while (a--) {
+ if (name[a] == delim) {
+ left[a] = '\0'; /* truncate left part here */
+ *nr = atol(name + a + 1);
+ /* casting down to an int, can overflow for large numbers */
+ if (*nr < 0) {
+ *nr = 0;
+ }
+ return a;
+ }
+ else if (isdigit(name[a]) == 0) {
+ /* non-numeric suffix - give up */
+ break;
+ }
+ }
+ }
+
+ return name_len;
}
static bool is_char_sep(const char c)
{
- return ELEM(c, '.', ' ', '-', '_');
+ return ELEM(c, '.', ' ', '-', '_');
}
/**
@@ -94,20 +93,20 @@ static bool is_char_sep(const char c)
*/
void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len)
{
- size_t len = BLI_strnlen(string, str_len);
- size_t i;
+ size_t len = BLI_strnlen(string, str_len);
+ size_t i;
- r_body[0] = r_suf[0] = '\0';
+ r_body[0] = r_suf[0] = '\0';
- for (i = len; i > 0; i--) {
- if (is_char_sep(string[i])) {
- BLI_strncpy(r_body, string, i + 1);
- BLI_strncpy(r_suf, string + i, (len + 1) - i);
- return;
- }
- }
+ for (i = len; i > 0; i--) {
+ if (is_char_sep(string[i])) {
+ BLI_strncpy(r_body, string, i + 1);
+ BLI_strncpy(r_suf, string + i, (len + 1) - i);
+ return;
+ }
+ }
- memcpy(r_body, string, len + 1);
+ memcpy(r_body, string, len + 1);
}
/**
@@ -115,21 +114,21 @@ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, cons
*/
void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len)
{
- size_t len = BLI_strnlen(string, str_len);
- size_t i;
+ size_t len = BLI_strnlen(string, str_len);
+ size_t i;
- r_body[0] = r_pre[0] = '\0';
+ r_body[0] = r_pre[0] = '\0';
- for (i = 1; i < len; i++) {
- if (is_char_sep(string[i])) {
- i++;
- BLI_strncpy(r_pre, string, i + 1);
- BLI_strncpy(r_body, string + i, (len + 1) - i);
- return;
- }
- }
+ for (i = 1; i < len; i++) {
+ if (is_char_sep(string[i])) {
+ i++;
+ BLI_strncpy(r_pre, string, i + 1);
+ BLI_strncpy(r_body, string + i, (len + 1) - i);
+ return;
+ }
+ }
- BLI_strncpy(r_body, string, len);
+ BLI_strncpy(r_body, string, len);
}
/**
@@ -139,129 +138,127 @@ void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, cons
* \param from_name: original name, assumed to be a pointer to a string of at least \a name_len size.
* \param strip_number: If set, remove number extensions.
*/
-void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len)
+void BLI_string_flip_side_name(char *r_name,
+ const char *from_name,
+ const bool strip_number,
+ const size_t name_len)
{
- size_t len;
- char *prefix = alloca(name_len); /* The part before the facing */
- char *suffix = alloca(name_len); /* The part after the facing */
- char *replace = alloca(name_len); /* The replacement string */
- char *number = alloca(name_len); /* The number extension string */
- char *index = NULL;
- bool is_set = false;
-
- *prefix = *suffix = *replace = *number = '\0';
-
- /* always copy the name, since this can be called with an uninitialized string */
- BLI_strncpy(r_name, from_name, name_len);
-
- len = BLI_strnlen(from_name, name_len);
- if (len < 3) {
- /* we don't do names like .R or .L */
- return;
- }
-
- /* We first check the case with a .### extension, let's find the last period */
- if (isdigit(r_name[len - 1])) {
- index = strrchr(r_name, '.'); // last occurrence
- if (index && isdigit(index[1])) { // doesnt handle case bone.1abc2 correct..., whatever!
- if (strip_number == false) {
- BLI_strncpy(number, index, name_len);
- }
- *index = 0;
- len = BLI_strnlen(r_name, name_len);
- }
- }
-
- BLI_strncpy(prefix, r_name, name_len);
-
- /* first case; separator . - _ with extensions r R l L */
- if ((len > 1) && is_char_sep(r_name[len - 2])) {
- is_set = true;
- switch (r_name[len - 1]) {
- case 'l':
- prefix[len - 1] = 0;
- strcpy(replace, "r");
- break;
- case 'r':
- prefix[len - 1] = 0;
- strcpy(replace, "l");
- break;
- case 'L':
- prefix[len - 1] = 0;
- strcpy(replace, "R");
- break;
- case 'R':
- prefix[len - 1] = 0;
- strcpy(replace, "L");
- break;
- default:
- is_set = false;
- }
- }
-
- /* case; beginning with r R l L, with separator after it */
- if (!is_set && is_char_sep(r_name[1])) {
- is_set = true;
- switch (r_name[0]) {
- case 'l':
- strcpy(replace, "r");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- case 'r':
- strcpy(replace, "l");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- case 'L':
- strcpy(replace, "R");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- case 'R':
- strcpy(replace, "L");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- default:
- is_set = false;
- }
- }
-
- if (!is_set && len > 5) {
- /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
- if (((index = BLI_strcasestr(prefix, "right")) == prefix) ||
- (index == prefix + len - 5))
- {
- is_set = true;
- if (index[0] == 'r') {
- strcpy(replace, "left");
- }
- else {
- strcpy(replace, (index[1] == 'I') ? "LEFT" : "Left");
- }
- *index = 0;
- BLI_strncpy(suffix, index + 5, name_len);
- }
- else if (((index = BLI_strcasestr(prefix, "left")) == prefix) ||
- (index == prefix + len - 4))
- {
- is_set = true;
- if (index[0] == 'l') {
- strcpy(replace, "right");
- }
- else {
- strcpy(replace, (index[1] == 'E') ? "RIGHT" : "Right");
- }
- *index = 0;
- BLI_strncpy(suffix, index + 4, name_len);
- }
- }
-
- BLI_snprintf(r_name, name_len, "%s%s%s%s", prefix, replace, suffix, number);
+ size_t len;
+ char *prefix = alloca(name_len); /* The part before the facing */
+ char *suffix = alloca(name_len); /* The part after the facing */
+ char *replace = alloca(name_len); /* The replacement string */
+ char *number = alloca(name_len); /* The number extension string */
+ char *index = NULL;
+ bool is_set = false;
+
+ *prefix = *suffix = *replace = *number = '\0';
+
+ /* always copy the name, since this can be called with an uninitialized string */
+ BLI_strncpy(r_name, from_name, name_len);
+
+ len = BLI_strnlen(from_name, name_len);
+ if (len < 3) {
+ /* we don't do names like .R or .L */
+ return;
+ }
+
+ /* We first check the case with a .### extension, let's find the last period */
+ if (isdigit(r_name[len - 1])) {
+ index = strrchr(r_name, '.'); // last occurrence
+ if (index && isdigit(index[1])) { // doesnt handle case bone.1abc2 correct..., whatever!
+ if (strip_number == false) {
+ BLI_strncpy(number, index, name_len);
+ }
+ *index = 0;
+ len = BLI_strnlen(r_name, name_len);
+ }
+ }
+
+ BLI_strncpy(prefix, r_name, name_len);
+
+ /* first case; separator . - _ with extensions r R l L */
+ if ((len > 1) && is_char_sep(r_name[len - 2])) {
+ is_set = true;
+ switch (r_name[len - 1]) {
+ case 'l':
+ prefix[len - 1] = 0;
+ strcpy(replace, "r");
+ break;
+ case 'r':
+ prefix[len - 1] = 0;
+ strcpy(replace, "l");
+ break;
+ case 'L':
+ prefix[len - 1] = 0;
+ strcpy(replace, "R");
+ break;
+ case 'R':
+ prefix[len - 1] = 0;
+ strcpy(replace, "L");
+ break;
+ default:
+ is_set = false;
+ }
+ }
+
+ /* case; beginning with r R l L, with separator after it */
+ if (!is_set && is_char_sep(r_name[1])) {
+ is_set = true;
+ switch (r_name[0]) {
+ case 'l':
+ strcpy(replace, "r");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ case 'r':
+ strcpy(replace, "l");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ case 'L':
+ strcpy(replace, "R");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ case 'R':
+ strcpy(replace, "L");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ default:
+ is_set = false;
+ }
+ }
+
+ if (!is_set && len > 5) {
+ /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
+ if (((index = BLI_strcasestr(prefix, "right")) == prefix) || (index == prefix + len - 5)) {
+ is_set = true;
+ if (index[0] == 'r') {
+ strcpy(replace, "left");
+ }
+ else {
+ strcpy(replace, (index[1] == 'I') ? "LEFT" : "Left");
+ }
+ *index = 0;
+ BLI_strncpy(suffix, index + 5, name_len);
+ }
+ else if (((index = BLI_strcasestr(prefix, "left")) == prefix) || (index == prefix + len - 4)) {
+ is_set = true;
+ if (index[0] == 'l') {
+ strcpy(replace, "right");
+ }
+ else {
+ strcpy(replace, (index[1] == 'E') ? "RIGHT" : "Right");
+ }
+ *index = 0;
+ BLI_strncpy(suffix, index + 4, name_len);
+ }
+ }
+
+ BLI_snprintf(r_name, name_len, "%s%s%s%s", prefix, replace, suffix, number);
}
-
/* Unique name utils. */
/**
@@ -276,47 +273,51 @@ void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool s
* \param name_len: Maximum length of name area
* \return true if there if the name was changed
*/
-bool BLI_uniquename_cb(
- UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len)
+bool BLI_uniquename_cb(UniquenameCheckCallback unique_check,
+ void *arg,
+ const char *defname,
+ char delim,
+ char *name,
+ size_t name_len)
{
- if (name[0] == '\0') {
- BLI_strncpy(name, defname, name_len);
- }
-
- if (unique_check(arg, name)) {
- char numstr[16];
- char *tempname = alloca(name_len);
- char *left = alloca(name_len);
- int number;
- size_t len = BLI_split_name_num(left, &number, name, delim);
- do {
- /* add 1 to account for \0 */
- const size_t numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number) + 1;
-
- /* highly unlikely the string only has enough room for the number
- * but support anyway */
- if ((len == 0) || (numlen >= name_len)) {
- /* number is know not to be utf-8 */
- BLI_strncpy(tempname, numstr, name_len);
- }
- else {
- char *tempname_buf;
- tempname_buf = tempname + BLI_strncpy_utf8_rlen(tempname, left, name_len - numlen);
- memcpy(tempname_buf, numstr, numlen);
- }
- } while (unique_check(arg, tempname));
-
- BLI_strncpy(name, tempname, name_len);
-
- return true;
- }
-
- return false;
+ if (name[0] == '\0') {
+ BLI_strncpy(name, defname, name_len);
+ }
+
+ if (unique_check(arg, name)) {
+ char numstr[16];
+ char *tempname = alloca(name_len);
+ char *left = alloca(name_len);
+ int number;
+ size_t len = BLI_split_name_num(left, &number, name, delim);
+ do {
+ /* add 1 to account for \0 */
+ const size_t numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number) + 1;
+
+ /* highly unlikely the string only has enough room for the number
+ * but support anyway */
+ if ((len == 0) || (numlen >= name_len)) {
+ /* number is know not to be utf-8 */
+ BLI_strncpy(tempname, numstr, name_len);
+ }
+ else {
+ char *tempname_buf;
+ tempname_buf = tempname + BLI_strncpy_utf8_rlen(tempname, left, name_len - numlen);
+ memcpy(tempname_buf, numstr, numlen);
+ }
+ } while (unique_check(arg, tempname));
+
+ BLI_strncpy(name, tempname, name_len);
+
+ return true;
+ }
+
+ return false;
}
/* little helper macro for BLI_uniquename */
#ifndef GIVE_STRADDR
-# define GIVE_STRADDR(data, offset) ( ((char *)data) + offset)
+# define GIVE_STRADDR(data, offset) (((char *)data) + offset)
#endif
/**
@@ -329,23 +330,27 @@ bool BLI_uniquename_cb(
*/
static bool uniquename_find_dupe(ListBase *list, void *vlink, const char *name, int name_offs)
{
- Link *link;
+ Link *link;
- for (link = list->first; link; link = link->next) {
- if (link != vlink) {
- if (STREQ(GIVE_STRADDR(link, name_offs), name)) {
- return true;
- }
- }
- }
+ for (link = list->first; link; link = link->next) {
+ if (link != vlink) {
+ if (STREQ(GIVE_STRADDR(link, name_offs), name)) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
static bool uniquename_unique_check(void *arg, const char *name)
{
- struct {ListBase *lb; void *vlink; int name_offs; } *data = arg;
- return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
+ struct {
+ ListBase *lb;
+ void *vlink;
+ int name_offs;
+ } *data = arg;
+ return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
}
/**
@@ -359,21 +364,27 @@ static bool uniquename_unique_check(void *arg, const char *name)
* \param name_offs: Offset of name within block structure
* \param name_len: Maximum length of name area
*/
-bool BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim, int name_offs, size_t name_len)
+bool BLI_uniquename(
+ ListBase *list, void *vlink, const char *defname, char delim, int name_offs, size_t name_len)
{
- struct {ListBase *lb; void *vlink; int name_offs; } data;
- data.lb = list;
- data.vlink = vlink;
- data.name_offs = name_offs;
-
- BLI_assert(name_len > 1);
-
- /* See if we are given an empty string */
- if (ELEM(NULL, vlink, defname)) {
- return false;
- }
-
- return BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
+ struct {
+ ListBase *lb;
+ void *vlink;
+ int name_offs;
+ } data;
+ data.lb = list;
+ data.vlink = vlink;
+ data.name_offs = name_offs;
+
+ BLI_assert(name_len > 1);
+
+ /* See if we are given an empty string */
+ if (ELEM(NULL, vlink, defname)) {
+ return false;
+ }
+
+ return BLI_uniquename_cb(
+ uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
}
/* ------------------------------------------------------------------------- */
@@ -389,77 +400,77 @@ bool BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim
/**
* Join an array of strings into a newly allocated, null terminated string.
*/
-char *BLI_string_join_arrayN(
- const char *strings[], uint strings_len)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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;
}
/** \} */