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:
authorKen Hughes <khughes@pacific.edu>2007-03-29 08:55:29 +0400
committerKen Hughes <khughes@pacific.edu>2007-03-29 08:55:29 +0400
commitb8e425af7c24ee24ee43205b0ce6e66e6a6a0c22 (patch)
tree7a61333dbc47eaa5c9d9bc53dd8d3b1309bf7900
parent42fa2ba00b4c5dc2427be616d64d30eaaab433f5 (diff)
Revisions to previous change of new_id().
Note: the intent of the original modification (and these updates) is not to change how new_id() functions. What has been done is to pull out the code which calculates a new name for an ID in the case of duplicate, as would happen when you copy any datablock, into a separate function. This code is necessary in the new Python Library module, since it otherwise is extremely difficult to locate a new datablock appended from a library. new_id() calls this separate function to generate a name for the new ID if necessary, just as it previously did. To make the purpose of this new function clearer, I renamed it check_for_dupid() and added more extensive comments. I repeat, it's not meant to be a substitute for new_id().
-rw-r--r--source/blender/blenkernel/BKE_library.h2
-rw-r--r--source/blender/blenkernel/intern/library.c180
-rw-r--r--source/blender/python/api2_2x/Library.c21
3 files changed, 107 insertions, 96 deletions
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index b0e82a3b7f7..f73c1b23a8a 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -47,7 +47,7 @@ void *copy_libblock(void *rt);
void id_lib_extern(struct ID *id);
void id_us_plus(struct ID *id);
-int dup_id(struct ListBase *lb, struct ID *id, const char *name);
+int check_for_dupid(struct ListBase *lb, struct ID *id, char *name);
int new_id(struct ListBase *lb, struct ID *id, const char *name);
struct ListBase *wich_libbase(struct Main *mainlib, short type);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 4468ec684c0..2a10d44d9e6 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -788,106 +788,122 @@ static void sort_alpha_id(ListBase *lb, ID *id)
}
-int dup_id(ListBase *lb, ID *id, const char *tname)
-/* only for local blocks: external en indirect blocks already have a unique ID */
-/* return 1: created a new name */
+/*
+ * Check to see if an ID name is already used, and find a new one if so.
+ * Return 1 if created a new name (returned in name).
+ *
+ * Normally the ID that's being check is already in the ListBase, so ID *id
+ * points at the new entry. The Python Library module needs to know what
+ * the name of a datablock will be before it is appended; in this case ID *id
+ * id is NULL;
+ */
+
+int check_for_dupid(ListBase *lb, ID *id, char *name)
{
ID *idtest;
- int nr= 0, nrtest, maxtest=32, a;
- char aname[32], *name, left[32], leftest[32], in_use[32];
+ int nr= 0, nrtest, a;
+ const int maxtest=32;
+ char left[32], leftest[32], in_use[32];
- /* - split name
- * - search
- */
-
- if(id->lib) return 0;
-
- if(tname==0) name= id->name+2;
- else {
- /* tname can be const */
- strncpy(aname, tname, 21);
- name= aname;
-
- if( strlen(name) > 21 ) name[21]= 0;
- }
-
- if(lb==NULL) lb= wich_libbase(G.main, GS(id->name));
-
- /* phase 1: id already exists? */
- idtest= lb->first;
- while(idtest) {
-
- if(id!=idtest && idtest->lib==0) {
-
- /* do not test alphabetic! */
- /* optimized */
- if( idtest->name[2] == name[0] ) {
- if(strcmp(name, idtest->name+2)==0) break;
+ /* make sure input name is terminated properly */
+ if( strlen(name) > 21 ) name[21]= 0;
+
+ while (1) {
+
+ /* phase 1: id already exists? */
+ for( idtest = lb->first; idtest; idtest = idtest->next ) {
+ /* if idtest is not a lib */
+ if( id != idtest && idtest->lib == NULL ) {
+ /* do not test alphabetic! */
+ /* optimized */
+ if( idtest->name[2] == name[0] ) {
+ if(strcmp(name, idtest->name+2)==0) break;
+ }
}
}
-
- idtest= idtest->next;
- }
- /* if there is no double return */
- if(idtest==0) {
- strncpy(id->name+2, name, 21);
- return 0;
- }
-
- memset(in_use, 0, maxtest);
-
- splitIDname(name, left, &nr);
- if(nr>999 && strlen(left)>16) left[16]= 0;
- else if(strlen(left)>17) left[17]= 0;
-
-
- idtest= lb->first;
- while(idtest) {
-
- if(id!=idtest && idtest->lib==0) {
-
- splitIDname(idtest->name+2, leftest, &nrtest);
- if(strcmp(left, leftest)==0) {
-
- if(nrtest<maxtest) in_use[nrtest]= 1;
- if(nr <= nrtest) nr= nrtest+1;
+ /* if there is no double, done */
+ if( idtest == NULL ) return 0;
+
+ /* we have a dup; need to make a new name */
+ /* quick check so we can reuse one of first 32 ids if vacant */
+ memset(in_use, 0, maxtest);
+
+ /* get name portion, number portion ("name.number") */
+ splitIDname( name, left, &nr);
+
+ /* if new name will be too long, truncate it */
+ if(nr>999 && strlen(left)>16) left[16]= 0;
+ else if(strlen(left)>17) left[17]= 0;
+
+ for( idtest = lb->first; idtest; idtest = idtest->next ) {
+ if( id != idtest && idtest->lib == NULL ) {
+ splitIDname(idtest->name+2, leftest, &nrtest);
+ /* if base names match... */
+ /* optimized */
+ if( idtest->name[2] == name[0] &&
+ strcmp(left, leftest)==0 ) {
+ if(nrtest < maxtest)
+ in_use[nrtest]= 1; /* mark as used */
+ if(nr <= nrtest)
+ nr= nrtest+1; /* track largest unused */
+ }
}
}
-
- idtest= idtest->next;
- }
-
- for(a=0; a<maxtest; a++) {
- if(a>=nr) break;
- if( in_use[a]==0 ) {
- nr= a;
- break;
+
+ /* decide which value of nr to use */
+ for(a=0; a<maxtest; a++) {
+ if(a>=nr) break; /* stop when we've check up to biggest */
+ if( in_use[a]==0 ) { /* found an unused value */
+ nr = a;
+ break;
+ }
}
- }
-
- if(nr==0) strncpy(id->name+2, left, 21);
- else {
- if (nr >= 1000 && strlen(left) > 16) {
- // this would overflow name buffer
- left[16]= 0;
- return (new_id(lb, id, left));
+
+ /* if non-numbered name was not in use, reuse it */
+ if(nr==0) strcpy( name, left );
+ else {
+ if(nr > 999 && strlen(left) > 16) {
+ /* this would overflow name buffer */
+ left[16] = 0;
+ strcpy( name, left );
+ continue;
+ }
+ /* this format specifier is from hell... */
+ sprintf(name, "%s.%.3d", left, nr);
}
- /* this format specifier is from hell... */
- sprintf(id->name+2, "%s.%.3d", left, nr);
+ return 1;
}
- return 1;
}
+/*
+ * Only for local blocks: external en indirect blocks already have a
+ * unique ID.
+ *
+ * return 1: created a new name
+ */
+
int new_id(ListBase *lb, ID *id, const char *tname)
-/* only for local blocks: external en indirect blocks already have a unique ID */
-/* return 1: created a new name */
{
int result;
+ char name[22];
+ /* if library, don't rename */
+ if(id->lib) return 0;
+
+ /* if no libdata given, look up based on ID */
if(lb==NULL) lb= wich_libbase(G.main, GS(id->name));
-
- result = dup_id( lb, id, tname );
+
+ if(tname==0) /* if no name given, use name of current ID */
+ strncpy(name, id->name+2, 21);
+ else /* else make a copy (tname args can be const) */
+ strncpy(name, tname, 21);
+
+ if( strlen(name) > 21 ) name[21]= 0;
+
+ result = check_for_dupid( lb, id, name );
+ strcpy( id->name+2, name );
+
if( result )
sort_alpha_id(lb, id);
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
index 4251b83585d..5251f405ff5 100644
--- a/source/blender/python/api2_2x/Library.c
+++ b/source/blender/python/api2_2x/Library.c
@@ -570,12 +570,12 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
int mode, Scene *scene )
{
char longFilename[FILE_MAX];
- char *finalName;
BlendHandle *openlib;
Library *lib;
LinkNode *names, *ptr;
ID idtest, *id;
ListBase *lb;
+ char newName[32];
/* try to open the library */
openlib = open_library( self->filename, longFilename );
@@ -603,16 +603,11 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
* be renamed to.
*/
- if( mode == FILE_LINK )
- finalName = name;
- else { /* for appends, build a fake ID block, then try to dup it */
- strncpy( idtest.name+2, name, strlen(name)+1 );
- *((short *)&idtest.name) = self->type;
- idtest.newid = NULL;
- idtest.lib = NULL;
- dup_id( NULL, &idtest, self->name );
- finalName = idtest.name+2;
- }
+ strncpy( newName, name, strlen(name)+1 );
+
+ /* for appends, see what new block will be called */
+ if( mode != FILE_LINK )
+ check_for_dupid( wich_libbase(G.main, self->type), NULL, newName );
/* import from the libary */
BLO_script_library_append( openlib, longFilename, name, self->type, mode,
@@ -642,8 +637,8 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
* otherwise it's NULL.
*/
for( id = lb->first; id; id = id->next ) {
- if( id->lib == lib && id->name[2]==finalName[0] &&
- strcmp(id->name+2, finalName)==0 )
+ if( id->lib == lib && id->name[2]==newName[0] &&
+ strcmp(id->name+2, newName)==0 )
return GetPyObjectFromID( id );
}