diff options
Diffstat (limited to 'source/blender/blenloader/intern/blend_validate.c')
-rw-r--r-- | source/blender/blenloader/intern/blend_validate.c | 274 |
1 files changed, 145 insertions, 129 deletions
diff --git a/source/blender/blenloader/intern/blend_validate.c b/source/blender/blenloader/intern/blend_validate.c index 4d4a20adbdf..1ca274dd68a 100644 --- a/source/blender/blenloader/intern/blend_validate.c +++ b/source/blender/blenloader/intern/blend_validate.c @@ -22,7 +22,7 @@ * \note Does not *fix* anything, only reports found errors. */ -#include <string.h> // for strrchr strncmp strstr +#include <string.h> // for strrchr strncmp strstr #include "BLI_utildefines.h" @@ -48,137 +48,153 @@ /** Check (but do *not* fix) that all linked data-blocks are still valid (i.e. pointing to the right library). */ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports) { - ListBase mainlist; - bool is_valid = true; - - BKE_main_lock(bmain); - - blo_split_main(&mainlist, bmain); - - ListBase *lbarray[MAX_LIBARRAY]; - int i = set_listbasepointers(bmain, lbarray); - while (i--) { - for (ID *id = lbarray[i]->first; id != NULL; id = id->next) { - if (id->lib != NULL) { - is_valid = false; - BKE_reportf(reports, RPT_ERROR, - "ID %s is in local database while being linked from library %s!", id->name, id->lib->name); - } - } - } - - for (Main *curmain = bmain->next; curmain != NULL; curmain = curmain->next) { - Library *curlib = curmain->curlib; - if (curlib == NULL) { - BKE_report(reports, RPT_ERROR, - "Library database with NULL library datablock!"); - continue; - } - - BKE_library_filepath_set(bmain, curlib, curlib->name); - BlendHandle *bh = BLO_blendhandle_from_file(curlib->filepath, reports); - - if (bh == NULL) { - BKE_reportf(reports, RPT_ERROR, - "Library ID %s not found at expected path %s!", curlib->id.name, curlib->filepath); - continue; - } - - i = set_listbasepointers(curmain, lbarray); - while (i--) { - ID *id = lbarray[i]->first; - if (id == NULL) { - continue; - } - - if (GS(id->name) == ID_LI) { - is_valid = false; - BKE_reportf(reports, RPT_ERROR, - "Library ID %s in library %s, this should not happen!", id->name, curlib->name); - continue; - } - - int totnames = 0; - LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), &totnames); - for (; id != NULL; id = id->next) { - if (id->lib == NULL) { - is_valid = false; - BKE_reportf(reports, RPT_ERROR, - "ID %s has NULL lib pointer while being in library %s!", id->name, curlib->name); - continue; - } - if (id->lib != curlib) { - is_valid = false; - BKE_reportf(reports, RPT_ERROR, - "ID %s has mismatched lib pointer!", id->name); - continue; - } - - LinkNode *name = names; - for (; name; name = name->next) { - char *str_name = (char *)name->link; - if (id->name[2] == str_name[0] && STREQ(str_name, id->name + 2)) { - break; - } - } - - if (name == NULL) { - is_valid = false; - BKE_reportf(reports, RPT_ERROR, - "ID %s not found in library %s anymore!", id->name, id->lib->name); - continue; - } - } - - BLI_linklist_free(names, free); - } - - BLO_blendhandle_close(bh); - } - - blo_join_main(&mainlist); - - BLI_assert(BLI_listbase_is_single(&mainlist)); - BLI_assert(mainlist.first == (void *)bmain); - - BKE_main_unlock(bmain); - - return is_valid; + ListBase mainlist; + bool is_valid = true; + + BKE_main_lock(bmain); + + blo_split_main(&mainlist, bmain); + + ListBase *lbarray[MAX_LIBARRAY]; + int i = set_listbasepointers(bmain, lbarray); + while (i--) { + for (ID *id = lbarray[i]->first; id != NULL; id = id->next) { + if (id->lib != NULL) { + is_valid = false; + BKE_reportf(reports, + RPT_ERROR, + "ID %s is in local database while being linked from library %s!", + id->name, + id->lib->name); + } + } + } + + for (Main *curmain = bmain->next; curmain != NULL; curmain = curmain->next) { + Library *curlib = curmain->curlib; + if (curlib == NULL) { + BKE_report(reports, RPT_ERROR, "Library database with NULL library datablock!"); + continue; + } + + BKE_library_filepath_set(bmain, curlib, curlib->name); + BlendHandle *bh = BLO_blendhandle_from_file(curlib->filepath, reports); + + if (bh == NULL) { + BKE_reportf(reports, + RPT_ERROR, + "Library ID %s not found at expected path %s!", + curlib->id.name, + curlib->filepath); + continue; + } + + i = set_listbasepointers(curmain, lbarray); + while (i--) { + ID *id = lbarray[i]->first; + if (id == NULL) { + continue; + } + + if (GS(id->name) == ID_LI) { + is_valid = false; + BKE_reportf(reports, + RPT_ERROR, + "Library ID %s in library %s, this should not happen!", + id->name, + curlib->name); + continue; + } + + int totnames = 0; + LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), &totnames); + for (; id != NULL; id = id->next) { + if (id->lib == NULL) { + is_valid = false; + BKE_reportf(reports, + RPT_ERROR, + "ID %s has NULL lib pointer while being in library %s!", + id->name, + curlib->name); + continue; + } + if (id->lib != curlib) { + is_valid = false; + BKE_reportf(reports, RPT_ERROR, "ID %s has mismatched lib pointer!", id->name); + continue; + } + + LinkNode *name = names; + for (; name; name = name->next) { + char *str_name = (char *)name->link; + if (id->name[2] == str_name[0] && STREQ(str_name, id->name + 2)) { + break; + } + } + + if (name == NULL) { + is_valid = false; + BKE_reportf(reports, + RPT_ERROR, + "ID %s not found in library %s anymore!", + id->name, + id->lib->name); + continue; + } + } + + BLI_linklist_free(names, free); + } + + BLO_blendhandle_close(bh); + } + + blo_join_main(&mainlist); + + BLI_assert(BLI_listbase_is_single(&mainlist)); + BLI_assert(mainlist.first == (void *)bmain); + + BKE_main_unlock(bmain); + + return is_valid; } /** Check (and fix if needed) that shape key's 'from' pointer is valid. */ bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports) { - ListBase *lb; - ID *id; - bool is_valid = true; - - BKE_main_lock(bmain); - - FOREACH_MAIN_LISTBASE_BEGIN(bmain, lb) - { - FOREACH_MAIN_LISTBASE_ID_BEGIN(lb, id) - { - if (!BKE_key_idtype_support(GS(id->name))) { - break; - } - if (id->lib == NULL) { - /* We assume lib data is valid... */ - Key *shapekey = BKE_key_from_id(id); - if (shapekey != NULL && shapekey->from != id) { - is_valid = false; - BKE_reportf(reports, RPT_ERROR, - "ID %s uses shapekey %s, but its 'from' pointer is invalid (%p), fixing...", - id->name, shapekey->id.name, shapekey->from); - shapekey->from = id; - } - } - } - FOREACH_MAIN_LISTBASE_ID_END; - } - FOREACH_MAIN_LISTBASE_END; - - BKE_main_unlock(bmain); - - return is_valid; + ListBase *lb; + ID *id; + bool is_valid = true; + + BKE_main_lock(bmain); + + FOREACH_MAIN_LISTBASE_BEGIN(bmain, lb) + { + FOREACH_MAIN_LISTBASE_ID_BEGIN(lb, id) + { + if (!BKE_key_idtype_support(GS(id->name))) { + break; + } + if (id->lib == NULL) { + /* We assume lib data is valid... */ + Key *shapekey = BKE_key_from_id(id); + if (shapekey != NULL && shapekey->from != id) { + is_valid = false; + BKE_reportf(reports, + RPT_ERROR, + "ID %s uses shapekey %s, but its 'from' pointer is invalid (%p), fixing...", + id->name, + shapekey->id.name, + shapekey->from); + shapekey->from = id; + } + } + } + FOREACH_MAIN_LISTBASE_ID_END; + } + FOREACH_MAIN_LISTBASE_END; + + BKE_main_unlock(bmain); + + return is_valid; } |