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:
authorCampbell Barton <ideasman42@gmail.com>2010-11-01 10:19:41 +0300
committerCampbell Barton <ideasman42@gmail.com>2010-11-01 10:19:41 +0300
commitdaa4feaaeae4312eb23f66b948b668a7e9dc1959 (patch)
treedabd2bedd213f9fdfbfc31e6710b2913707dfa1f /source/blender/blenlib
parent8bbcef4c7a377045f6b93580efda93eb4adf800d (diff)
bugfix [#24477] Can easily create bones with duplicate names
- fixed this error 7 different functions (deform groups, uv layers & similar). - support for numbers over 999. - renamed splitIDname() to BLI_split_name_num(), moved to BLI_path_utils
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_path_util.h1
-rw-r--r--source/blender/blenlib/intern/path_util.c99
2 files changed, 62 insertions, 38 deletions
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 5dbb137ec07..69b10661e23 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -120,6 +120,7 @@ void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], ch
void BLI_newname(char * name, int add);
int BLI_stringdec(const char *string, char *head, char *start, unsigned short *numlen);
void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic);
+int BLI_split_name_num(char *left, int *nr, const char *name);
void BLI_splitdirstring(char *di,char *fi);
/* make sure path separators conform to system one */
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 91558d4806e..466012eb9b8 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -136,6 +136,37 @@ void BLI_stringenc(char *string, const char *head, const char *tail, unsigned sh
sprintf(string, fmtstr, head, pic, tail);
}
+/* Foo.001 -> "Foo", 1
+ * Returns the length of "Foo" */
+int BLI_split_name_num(char *left, int *nr, const char *name)
+{
+ int a;
+
+ *nr= 0;
+ a= strlen(name);
+ memcpy(left, name, (a + 1) * sizeof(char));
+
+ if(a>1 && name[a-1]=='.') return a;
+
+ while(a--) {
+ if( name[a]=='.' ) {
+ left[a]= 0;
+ *nr= atol(name+a+1);
+ /* casting down to an int, can overflow for large numbers */
+ if(*nr < 0)
+ *nr= 0;
+ return a;
+ }
+ if( isdigit(name[a])==0 ) break;
+
+ left[a]= 0;
+ }
+
+ for(a= 0; name[a]; a++)
+ left[a]= name[a];
+
+ return a;
+}
void BLI_newname(char *name, int add)
{
@@ -174,15 +205,25 @@ void BLI_newname(char *name, int add)
* defname: the name that should be used by default if none is specified already
* delim: the character which acts as a delimeter between parts of the name
*/
-void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len)
+static int uniquename_find_dupe(ListBase *list, void *vlink, const char *name, short name_offs)
{
Link *link;
- char tempname[128];
- int number = 1, exists = 0;
- char *dot;
-
+
+ for (link = list->first; link; link= link->next) {
+ if (link != vlink) {
+ if (!strcmp(GIVE_STRADDR(link, name_offs), name)) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short name_len)
+{
/* Make sure length can be handled */
- if ((len < 0) || (len > 128))
+ if ((name_len < 0) || (name_len > 128))
return;
/* See if we are given an empty string */
@@ -191,45 +232,27 @@ void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char deli
if (GIVE_STRADDR(vlink, name_offs) == '\0') {
/* give it default name first */
- BLI_strncpy(GIVE_STRADDR(vlink, name_offs), defname, len);
+ BLI_strncpy(GIVE_STRADDR(vlink, name_offs), defname, name_len);
}
/* See if we even need to do this */
if (list == NULL)
return;
-
- for (link = list->first; link; link= link->next) {
- if (link != vlink) {
- if (!strcmp(GIVE_STRADDR(link, name_offs), GIVE_STRADDR(vlink, name_offs))) {
- exists = 1;
- break;
- }
- }
- }
- if (exists == 0)
- return;
- /* Strip off the suffix */
- dot = strrchr(GIVE_STRADDR(vlink, name_offs), delim);
- if (dot)
- *dot=0;
-
- for (number = 1; number <= 999; number++) {
- BLI_snprintf(tempname, sizeof(tempname), "%s%c%03d", GIVE_STRADDR(vlink, name_offs), delim, number);
-
- exists = 0;
- for (link= list->first; link; link= link->next) {
- if (vlink != link) {
- if (!strcmp(GIVE_STRADDR(link, name_offs), tempname)) {
- exists = 1;
- break;
- }
+ if(uniquename_find_dupe(list,vlink, GIVE_STRADDR(vlink, name_offs), name_offs)) {
+ /* note: this block is used in other places, when changing logic apply to all others, search this message */
+ char tempname[128];
+ char left[128];
+ int number;
+ int len= BLI_split_name_num(left, &number, GIVE_STRADDR(vlink, name_offs));
+ do { /* nested while loop looks bad but likely it wont run most times */
+ while(BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, number) >= name_len) {
+ if(len > 0) left[--len]= '\0'; /* word too long */
+ else number= 0; /* reset, must be a massive number */
}
- }
- if (exists == 0) {
- BLI_strncpy(GIVE_STRADDR(vlink, name_offs), tempname, len);
- return;
- }
+ } while(number++, uniquename_find_dupe(list, vlink, tempname, name_offs));
+
+ BLI_strncpy(GIVE_STRADDR(vlink, name_offs), tempname, name_len);
}
}