UVEdit: Add back uv angle stretch aspect correction
[blender.git] / source / blender / blenloader / intern / blend_validate.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Bastien Montagne
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  *
22  */
23
24 /** \file blender/blenloader/intern/blend_validate.c
25  *  \ingroup blenloader
26  *
27  * Utils to check/validate a Main is in sane state, only checks relations between datablocks and libraries for now.
28  *
29  * \note Does not *fix* anything, only reports found errors.
30  *
31  */
32
33 #include <string.h> // for strrchr strncmp strstr
34
35 #include "BLI_utildefines.h"
36
37 #include "BLI_blenlib.h"
38 #include "BLI_linklist.h"
39
40 #include "MEM_guardedalloc.h"
41
42 #include "DNA_sdna_types.h"
43 #include "DNA_windowmanager_types.h"
44
45 #include "BKE_library.h"
46 #include "BKE_main.h"
47 #include "BKE_report.h"
48
49 #include "BLO_readfile.h"
50 #include "BLO_writefile.h"
51
52 #include "readfile.h"
53
54 /* Does not fix anything, but checks that all linked data-blocks are still valid (i.e. pointing to the right library). */
55 bool BLO_main_validate_libraries(struct Main *bmain, struct ReportList *reports)
56 {
57         ListBase mainlist;
58         bool is_valid = true;
59
60         BKE_main_lock(bmain);
61
62         blo_split_main(&mainlist, bmain);
63
64         ListBase *lbarray[MAX_LIBARRAY];
65         int i = set_listbasepointers(bmain, lbarray);
66         while (i--) {
67                 for (ID *id = lbarray[i]->first; id != NULL; id = id->next) {
68                         if (id->lib != NULL) {
69                                 is_valid = false;
70                                 BKE_reportf(reports, RPT_ERROR,
71                                             "ID %s is in local database while being linked from library %s!", id->name, id->lib->name);
72                         }
73                 }
74         }
75
76         for (Main *curmain = bmain->next; curmain != NULL; curmain = curmain->next) {
77                 Library *curlib = curmain->curlib;
78                 if (curlib == NULL) {
79                         BKE_reportf(reports, RPT_ERROR,
80                                     "Library database with NULL library datablock!");
81                         continue;
82                 }
83
84                 BKE_library_filepath_set(bmain, curlib, curlib->name);
85                 BlendHandle *bh = BLO_blendhandle_from_file(curlib->filepath, reports);
86
87                 if (bh == NULL) {
88                         BKE_reportf(reports, RPT_ERROR,
89                                     "Library ID %s not found at expected path %s!", curlib->id.name, curlib->filepath);
90                         continue;
91                 }
92
93                 i = set_listbasepointers(curmain, lbarray);
94                 while (i--) {
95                         ID *id = lbarray[i]->first;
96                         if (id == NULL) {
97                                 continue;
98                         }
99
100                         if (GS(id->name) == ID_LI) {
101                                 is_valid = false;
102                                 BKE_reportf(reports, RPT_ERROR,
103                                             "Library ID %s in library %s, this should not happen!", id->name, curlib->name);
104                                 continue;
105                         }
106
107                         int totnames = 0;
108                         LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), &totnames);
109                         for (; id != NULL; id = id->next) {
110                                 if (id->lib == NULL) {
111                                         is_valid = false;
112                                         BKE_reportf(reports, RPT_ERROR,
113                                                     "ID %s has NULL lib pointer while being in library %s!", id->name, curlib->name);
114                                         continue;
115                                 }
116                                 if (id->lib != curlib) {
117                                         is_valid = false;
118                                         BKE_reportf(reports, RPT_ERROR,
119                                                     "ID %s has mismatched lib pointer!", id->name);
120                                         continue;
121                                 }
122
123                                 LinkNode *name = names;
124                                 for (; name; name = name->next) {
125                                         char *str_name = (char *)name->link;
126                                         if (id->name[2] == str_name[0] && STREQ(str_name, id->name + 2)) {
127                                                 break;
128                                         }
129                                 }
130
131                                 if (name == NULL) {
132                                         is_valid = false;
133                                         BKE_reportf(reports, RPT_ERROR,
134                                                     "ID %s not found in library %s anymore!", id->name, id->lib->name);
135                                         continue;
136                                 }
137                         }
138
139                         BLI_linklist_free(names, free);
140                 }
141
142                 BLO_blendhandle_close(bh);
143         }
144
145         blo_join_main(&mainlist);
146
147         BLI_assert(BLI_listbase_is_single(&mainlist));
148         BLI_assert(mainlist.first == (void *)bmain);
149
150         BKE_main_unlock(bmain);
151
152         return is_valid;
153 }