py/library api: raise an error if a requested member isn't found.
authorCampbell Barton <ideasman42@gmail.com>
Sun, 13 Mar 2011 01:15:14 +0000 (01:15 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 13 Mar 2011 01:15:14 +0000 (01:15 +0000)
source/blender/blenloader/BLO_readfile.h
source/blender/blenloader/intern/readfile.c
source/blender/python/intern/bpy_library.c

index bbe444eff5c2c27d5a63d72b143cd8e3827fa38a..891dc47b4aedfc3cbd1a43a96242f68247e2730a 100644 (file)
@@ -208,7 +208,19 @@ int BLO_has_bfile_extension(char *str);
 int BLO_is_a_library(const char *path, char *dir, char *group);
 
 struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, char *dir);
-void BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag);
+
+/**
+ * Link/Append a named datablock from an external blend file.
+ *
+ * @param C The context, when NULL instancing object in the scene isnt done.
+ * @param mainl The main database to link from (not the active one).
+ * @param bh The blender file handle.
+ * @param name The name of the datablock (without the 2 char ID prefix)
+ * @param idcode The kind of datablock to link.
+ * @param flag Options for linking, used for instancing.
+ * @return Boolean, 0 when the datablock could not be found.
+ */
+int BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag);
 void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag);
 
 /* deprecated */
index d5da98499bc683c517c8af1fb40d6ef40d5b1da5..eb5d2de738394634b0c3e9efb9d3ef06a6451008 100644 (file)
@@ -12698,7 +12698,9 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
        }
 }
 
-static void append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag)
+/* returns true if the item was found
+ * but it may already have already been appended/linked */
+static int append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag)
 {
        Scene *scene= CTX_data_scene(C);
        Object *ob;
@@ -12706,6 +12708,7 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
        BHead *bhead;
        ID *id;
        int endloop=0;
+       int found=0;
 
        bhead = blo_firstbhead(fd);
        while(bhead && endloop==0) {
@@ -12715,7 +12718,7 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
                        char *idname= bhead_id_name(fd, bhead);
                                
                        if(strcmp(idname+2, name)==0) {
-
+                               found= 1;
                                id= is_yet_read(fd, mainl, bhead);
                                if(id==NULL) {
                                        read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
@@ -12762,12 +12765,14 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
 
                bhead = blo_nextbhead(fd, bhead);
        }
+
+       return found;
 }
 
-void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag)
+int BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag)
 {
        FileData *fd= (FileData*)(*bh);
-       append_named_part(C, mainl, fd, name, idcode, flag);
+       return append_named_part(C, mainl, fd, name, idcode, flag);
 }
 
 static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
index f6bbd259df22f60d74b934c78edf8ada7c5d0fe3..977bcabe69452d411852b8ad13c58565ee0fbc4c 100644 (file)
@@ -258,6 +258,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
 static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
 {
        Main *mainl= NULL;
+       int err= 0;
 
        flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
 
@@ -285,7 +286,11 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
                                                // printf("  %s\n", item_str);
 
                                                if(item_str) {
-                                                       BLO_library_append_named_part(NULL, mainl, &(self->blo_handle), item_str, code, self->flag);
+                                                       if(!BLO_library_append_named_part(NULL, mainl, &(self->blo_handle), item_str, code, self->flag)) {
+                                                               PyErr_Format(PyExc_KeyError, "load: %s does not contain %s[\"%s\"]", self->abspath, name_plural, item_str);
+                                                               err= -1;
+                                                               break;
+                                                       }
                                                }
                                                else {
                                                        /* XXX, could complain about this */
@@ -297,26 +302,33 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
                }
        }
 
-       BLO_library_append_end(NULL, mainl, &(self->blo_handle), 0, self->flag);
-       BLO_blendhandle_close(self->blo_handle);
-
-       {       /* copied from wm_operator.c */
-               /* mark all library linked objects to be updated */
-               recalc_all_library_objects(G.main);
-
-               /* append, rather than linking */
-               if((self->flag & FILE_LINK)==0) {
-                       Library *lib= BLI_findstring(&G.main->library, self->abspath, offsetof(Library, name));
-                       if(lib) all_local(lib, 1);
-                       else    BLI_assert(!"cant find name of just added library!");
-               }
+       if(err == -1) {
+               /* exception raised above, XXX, this leaks some memory */
+               BLO_blendhandle_close(self->blo_handle);
+               self->blo_handle= NULL;
+               return NULL;
        }
+       else {
+               BLO_library_append_end(NULL, mainl, &(self->blo_handle), 0, self->flag);
+               BLO_blendhandle_close(self->blo_handle);
+               self->blo_handle= NULL;
+
+               {       /* copied from wm_operator.c */
+                       /* mark all library linked objects to be updated */
+                       recalc_all_library_objects(G.main);
+
+                       /* append, rather than linking */
+                       if((self->flag & FILE_LINK)==0) {
+                               Library *lib= BLI_findstring(&G.main->library, self->abspath, offsetof(Library, name));
+                               if(lib) all_local(lib, 1);
+                               else    BLI_assert(!"cant find name of just added library!");
+                       }
+               }
 
-       flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
-
-       self->blo_handle= NULL;
+               flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
 
-       Py_RETURN_NONE;
+               Py_RETURN_NONE;
+       }
 }
 
 int bpy_lib_init(PyObject *mod_par)