diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-11-01 10:19:41 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-11-01 10:19:41 +0300 |
commit | daa4feaaeae4312eb23f66b948b668a7e9dc1959 (patch) | |
tree | dabd2bedd213f9fdfbfc31e6710b2913707dfa1f /source/blender/blenlib | |
parent | 8bbcef4c7a377045f6b93580efda93eb4adf800d (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.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/path_util.c | 99 |
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); } } |