Blender V5.0
bpath.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9/* TODO:
10 * currently there are some cases we don't support.
11 * - passing output paths to the visitor?, like render out.
12 * - passing sequence strips with many images.
13 * - passing directory paths - visitors don't know which path is a dir or a file.
14 */
15
16#include <sys/stat.h>
17
18#include <cstring>
19
20/* path/file handling stuff */
21#ifndef WIN32
22# include <dirent.h>
23# include <unistd.h>
24#else
25# include "BLI_winstuff.h"
26# include <io.h>
27#endif
28
29#include "MEM_guardedalloc.h"
30
31#include "BLI_fileops.h"
32#include "BLI_listbase.h"
33#include "BLI_path_utils.hh"
34#include "BLI_string.h"
35#include "BLI_utildefines.h"
36
37#include "DEG_depsgraph.hh"
38
39#include "BKE_idtype.hh"
40#include "BKE_library.hh"
41#include "BKE_main.hh"
42#include "BKE_node.hh"
43#include "BKE_report.hh"
44
45#include "BKE_bpath.hh" /* own include */
46
47#include "CLG_log.h"
48
49#ifndef _MSC_VER
50# include "BLI_strict_flags.h" /* IWYU pragma: keep. Keep last. */
51#endif
52
53static CLG_LogRef LOG = {"lib.bpath"};
54
55/* -------------------------------------------------------------------- */
58
59void BKE_bpath_summary_report(const BPathSummary &summary, ReportList *reports)
60{
61 BKE_reportf(reports,
63 "Total files %d | Changed %d | Failed %d",
64 summary.count_total,
65 summary.count_changed,
66 summary.count_failed);
67}
68
70
71/* -------------------------------------------------------------------- */
74
76{
77 const eBPathForeachFlag flag = bpath_data->flag;
78 const char *absbase = (flag & BKE_BPATH_FOREACH_PATH_ABSOLUTE) ?
79 ID_BLEND_PATH(bpath_data->bmain, id) :
80 nullptr;
81 bpath_data->absolute_base_path = absbase;
82 bpath_data->owner_id = id;
83 bpath_data->is_path_modified = false;
84
86 return;
87 }
88
89 if (id->library_weak_reference != nullptr &&
91 {
95 }
96
97 bNodeTree *embedded_node_tree = blender::bke::node_tree_from_id(id);
98 if (embedded_node_tree != nullptr) {
99 BKE_bpath_foreach_path_id(bpath_data, &embedded_node_tree->id);
100 }
101
102 const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
103
104 BLI_assert(id_type != nullptr);
105 if (id_type == nullptr || id_type->foreach_path == nullptr) {
106 return;
107 }
108
109 id_type->foreach_path(id, bpath_data);
110
111 if (bpath_data->is_path_modified) {
113 }
114}
115
117{
118 ID *id;
119 FOREACH_MAIN_ID_BEGIN (bpath_data->bmain, id) {
120 BKE_bpath_foreach_path_id(bpath_data, id);
121 }
123}
124
126 char *path,
127 size_t path_maxncpy)
128{
129 const char *absolute_base_path = bpath_data->absolute_base_path;
130
131 char path_src_buf[FILE_MAX];
132 const char *path_src;
133 char path_dst[FILE_MAX];
134
135 if (absolute_base_path) {
136 STRNCPY(path_src_buf, path);
137 BLI_path_abs(path_src_buf, absolute_base_path);
138 path_src = path_src_buf;
139 }
140 else {
141 path_src = path;
142 }
143
144 /* so functions can check old value */
145 STRNCPY(path_dst, path);
146
147 if (bpath_data->callback_function(bpath_data, path_dst, sizeof(path_dst), path_src)) {
148 BLI_strncpy(path, path_dst, path_maxncpy);
149 bpath_data->is_path_modified = true;
150 return true;
151 }
152
153 return false;
154}
155
157 char *path_dir,
158 size_t path_dir_maxncpy,
159 char *path_file,
160 size_t path_file_maxncpy)
161{
162 const char *absolute_base_path = bpath_data->absolute_base_path;
163
164 char path_src[FILE_MAX];
165 char path_dst[FILE_MAX];
166
167 BLI_path_join(path_src, sizeof(path_src), path_dir, path_file);
168
169 /* So that functions can access the old value. */
170 STRNCPY(path_dst, path_src);
171
172 if (absolute_base_path) {
173 BLI_path_abs(path_src, absolute_base_path);
174 }
175
176 if (bpath_data->callback_function(
177 bpath_data, path_dst, sizeof(path_dst), (const char *)path_src))
178 {
179 BLI_path_split_dir_file(path_dst, path_dir, path_dir_maxncpy, path_file, path_file_maxncpy);
180 bpath_data->is_path_modified = true;
181 return true;
182 }
183
184 return false;
185}
186
188{
189 const char *absolute_base_path = bpath_data->absolute_base_path;
190
191 char path_src_buf[FILE_MAX];
192 const char *path_src;
193 char path_dst[FILE_MAX];
194
195 if (absolute_base_path) {
196 STRNCPY(path_src_buf, *path);
197 BLI_path_abs(path_src_buf, absolute_base_path);
198 path_src = path_src_buf;
199 }
200 else {
201 path_src = *path;
202 }
203
204 if (bpath_data->callback_function(bpath_data, path_dst, sizeof(path_dst), path_src)) {
205 MEM_freeN(*path);
206 (*path) = BLI_strdup(path_dst);
207 bpath_data->is_path_modified = true;
208 return true;
209 }
210
211 return false;
212}
213
215
216/* -------------------------------------------------------------------- */
219
221 char * /*path_dst*/,
222 size_t /*path_dst_maxncpy*/,
223 const char *path_src)
224{
225 ReportList *reports = (ReportList *)bpath_data->user_data;
226
227 if (!BLI_exists(path_src)) {
228 ID *owner_id = bpath_data->owner_id;
229 if (owner_id) {
230 if (ID_IS_LINKED(owner_id)) {
231 BKE_reportf(reports,
233 "Path '%s' not found, from linked data-block '%s' (from library '%s')",
234 path_src,
235 owner_id->name,
236 owner_id->lib->runtime->filepath_abs);
237 }
238 else {
239 BKE_reportf(reports,
241 "Path '%s' not found, from local data-block '%s'",
242 path_src,
243 owner_id->name);
244 }
245 }
246 else {
248 reports, RPT_WARNING, "Path '%s' not found (no known owner data-block)", path_src);
249 }
250 }
251
252 return false;
253}
254
256{
257 BPathForeachPathData path_data{};
258 path_data.bmain = bmain;
262 path_data.user_data = reports;
263 BKE_bpath_foreach_path_main(&path_data);
264
265 if (BLI_listbase_is_empty(&reports->list)) {
266 BKE_reportf(reports, RPT_INFO, "No missing files");
267 }
268}
269
271
272/* -------------------------------------------------------------------- */
275
276#define MAX_DIR_RECURSE 16
277#define FILESIZE_INVALID_DIRECTORY -1
278
294static bool missing_files_find__recursive(const char *search_directory,
295 const char *filename_src,
296 char r_filepath_new[FILE_MAX],
297 int64_t *r_filesize,
298 int *r_recurse_depth)
299{
300 /* TODO: Move this function to BLI_path_utils? The 'biggest size' behavior is quite specific
301 * though... */
302 DIR *dir;
304 char path[FILE_MAX];
306 bool found = false;
307
308 BLI_assert(!BLI_path_is_rel(search_directory));
309 dir = opendir(search_directory);
310
311 if (dir == nullptr) {
312 return found;
313 }
314
315 if (*r_filesize == FILESIZE_INVALID_DIRECTORY) {
316 *r_filesize = 0; /* The directory opened fine. */
317 }
318
319 for (dirent *de = readdir(dir); de != nullptr; de = readdir(dir)) {
320 if (FILENAME_IS_CURRPAR(de->d_name)) {
321 continue;
322 }
323
324 BLI_path_join(path, sizeof(path), search_directory, de->d_name);
325
326 if (BLI_stat(path, &status) == -1) {
327 CLOG_WARN(&LOG, "Cannot get file status (`stat()`) of '%s'", path);
328 continue;
329 }
330
331 if (S_ISREG(status.st_mode)) { /* It is a file. */
332 if (BLI_path_ncmp(filename_src, de->d_name, FILE_MAX) == 0) { /* Names match. */
333 size = status.st_size;
334 if ((size > 0) && (size > *r_filesize)) { /* Find the biggest matching file. */
335 *r_filesize = size;
336 BLI_strncpy(r_filepath_new, path, FILE_MAX);
337 found = true;
338 }
339 }
340 }
341 else if (S_ISDIR(status.st_mode)) { /* It is a sub-directory. */
342 if (*r_recurse_depth <= MAX_DIR_RECURSE) {
343 (*r_recurse_depth)++;
345 path, filename_src, r_filepath_new, r_filesize, r_recurse_depth);
346 (*r_recurse_depth)--;
347 }
348 }
349 }
350
351 closedir(dir);
352 return found;
353}
354
356 const char *basedir;
357 const char *searchdir;
359 bool find_all; /* Also search for files which current path is still valid. */
360};
361
363 char *path_dst,
364 size_t path_dst_maxncpy,
365 const char *path_src)
366{
368 char filepath_new[FILE_MAX];
369
371 int recurse_depth = 0;
372 bool is_found;
373
374 if (!data->find_all && BLI_exists(path_src)) {
375 return false;
376 }
377
378 filepath_new[0] = '\0';
379
381 data->searchdir, BLI_path_basename(path_src), filepath_new, &filesize, &recurse_depth);
382
383 if (filesize == FILESIZE_INVALID_DIRECTORY) {
384 BKE_reportf(data->reports,
386 "Could not open the directory '%s'",
387 BLI_path_basename(data->searchdir));
388 return false;
389 }
390 if (is_found == false) {
391 BKE_reportf(data->reports,
393 "Could not find '%s' in '%s'",
394 BLI_path_basename(path_src),
395 data->searchdir);
396 return false;
397 }
398
399 /* Keep the path relative if the previous one was relative. */
400 if (BLI_path_is_rel(path_dst)) {
401 BLI_path_rel(filepath_new, data->basedir);
402 }
403 BLI_strncpy(path_dst, filepath_new, path_dst_maxncpy);
404 return true;
405}
406
408 const char *searchpath,
409 ReportList *reports,
410 const bool find_all)
411{
412 BPathFind_Data data = {nullptr};
415
416 data.basedir = BKE_main_blendfile_path(bmain);
417 data.reports = reports;
418 data.searchdir = searchpath;
419 data.find_all = find_all;
420
421 BPathForeachPathData path_data{};
422 path_data.bmain = bmain;
424 path_data.flag = eBPathForeachFlag(flag);
425 path_data.user_data = &data;
426 BKE_bpath_foreach_path_main(&path_data);
427}
428
429#undef MAX_DIR_RECURSE
430#undef FILESIZE_INVALID_DIRECTORY
431
433
434/* -------------------------------------------------------------------- */
437
445
447 char *path_dst,
448 size_t path_dst_maxncpy,
449 const char *path_src)
450{
452
453 data->summary.count_total++;
454
455 if (!BLI_path_is_rel(path_src)) {
456 /* Absolute, leave this as-is. */
457 return false;
458 }
459
460 char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
461 BLI_strncpy(filepath, path_src, FILE_MAX);
462 if (!BLI_path_abs(filepath, data->basedir_src)) {
463 BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
464 data->summary.count_failed++;
465 return false;
466 }
467
468 BLI_path_normalize(filepath);
469
470 /* This may fail, if so it's fine to leave absolute since the path is still valid. */
471 BLI_path_rel(filepath, data->basedir_dst);
472
473 BLI_strncpy(path_dst, filepath, path_dst_maxncpy);
474 data->summary.count_changed++;
475 return true;
476}
477
479 const char *basedir_src,
480 const char *basedir_dst,
481 ReportList *reports,
482 BPathSummary *r_summary)
483{
484 BPathRebase_Data data = {nullptr};
486
487 BLI_assert(basedir_src[0] != '\0');
488 BLI_assert(basedir_dst[0] != '\0');
489
490 data.basedir_src = basedir_src;
491 data.basedir_dst = basedir_dst;
492 data.reports = reports;
493
494 BPathForeachPathData path_data{};
495 path_data.bmain = bmain;
497 path_data.flag = eBPathForeachFlag(flag);
498 path_data.user_data = &data;
499 BKE_bpath_foreach_path_main(&path_data);
500
501 if (r_summary) {
502 *r_summary = data.summary;
503 }
504}
505
507
508/* -------------------------------------------------------------------- */
511
518
520 char *path_dst,
521 size_t path_dst_maxncpy,
522 const char *path_src)
523{
525
526 data->summary.count_total++;
527
528 if (BLI_path_is_rel(path_src)) {
529 return false; /* Already relative. */
530 }
531
532 char path_test[FILE_MAX];
533 STRNCPY(path_test, path_src);
534
535 BLI_path_rel(path_test, data->basedir);
536 if (!BLI_path_is_rel(path_test)) {
537 const char *type_name = BKE_idtype_get_info_from_id(bpath_data->owner_id)->name;
538 const char *id_name = bpath_data->owner_id->name + 2;
539 BKE_reportf(data->reports,
541 "Path '%s' cannot be made relative for %s '%s'",
542 path_src,
543 type_name,
544 id_name);
545 data->summary.count_failed++;
546 return false;
547 }
548
549 BLI_strncpy(path_dst, path_test, path_dst_maxncpy);
550 data->summary.count_changed++;
551 return true;
552}
553
555 char *path_dst,
556 size_t path_dst_maxncpy,
557 const char *path_src)
558{
560
561 data->summary.count_total++;
562
563 if (!BLI_path_is_rel(path_src)) {
564 return false; /* Already absolute. */
565 }
566
567 char path_test[FILE_MAX];
568 STRNCPY(path_test, path_src);
569 BLI_path_abs(path_test, data->basedir);
570 if (BLI_path_is_rel(path_test)) {
571 const char *type_name = BKE_idtype_get_info_from_id(bpath_data->owner_id)->name;
572 const char *id_name = bpath_data->owner_id->name + 2;
573 BKE_reportf(data->reports,
575 "Path '%s' cannot be made absolute for %s '%s'",
576 path_src,
577 type_name,
578 id_name);
579 data->summary.count_failed++;
580 return false;
581 }
582
583 BLI_strncpy(path_dst, path_test, path_dst_maxncpy);
584 data->summary.count_changed++;
585 return true;
586}
587
589 const char *basedir,
590 ReportList *reports,
591 BPathForeachPathFunctionCallback callback_function,
592 BPathSummary *r_summary)
593{
594 BPathRemap_Data data = {nullptr};
596
597 BLI_assert(basedir[0] != '\0');
598 if (basedir[0] == '\0') {
599 CLOG_ERROR(&LOG, "basedir='', this is a bug");
600 return;
601 }
602
603 data.basedir = basedir;
604 data.reports = reports;
605
606 BPathForeachPathData path_data{};
607 path_data.bmain = bmain;
608 path_data.callback_function = callback_function;
609 path_data.flag = eBPathForeachFlag(flag);
610 path_data.user_data = &data;
611 BKE_bpath_foreach_path_main(&path_data);
612
613 if (r_summary) {
614 *r_summary = data.summary;
615 }
616}
617
619 const char *basedir,
620 ReportList *reports,
621 BPathSummary *r_summary)
622{
624 bmain, basedir, reports, relative_convert_foreach_path_cb, r_summary);
625}
626
628 const char *basedir,
629 ReportList *reports,
630 BPathSummary *r_summary)
631{
633 bmain, basedir, reports, absolute_convert_foreach_path_cb, r_summary);
634}
635
637
638/* -------------------------------------------------------------------- */
642
643struct PathStore {
646 char filepath[0];
647};
648
650 char * /*path_dst*/,
651 size_t /*path_dst_maxncpy*/,
652 const char *path_src)
653{
654 ListBase *path_list = static_cast<ListBase *>(bpath_data->user_data);
655 size_t path_size = strlen(path_src) + 1;
656
657 /* NOTE: the PathStore and its string are allocated together in a single alloc. */
658 PathStore *path_store = static_cast<PathStore *>(
659 MEM_mallocN(sizeof(PathStore) + path_size, __func__));
660
661 char *filepath = path_store->filepath;
662
663 memcpy(filepath, path_src, path_size);
664 BLI_addtail(path_list, path_store);
665 return false;
666}
667
669 char *path_dst,
670 size_t path_dst_maxncpy,
671 const char *path_src)
672{
673 ListBase *path_list = static_cast<ListBase *>(bpath_data->user_data);
674
675 /* `ls->first` should never be nullptr, because the number of paths should not change.
676 * If this happens, there is a bug in caller code. */
678
679 PathStore *path_store = static_cast<PathStore *>(path_list->first);
680 const char *filepath = path_store->filepath;
681 bool is_path_changed = false;
682
683 if (!STREQ(path_src, filepath)) {
684 BLI_strncpy(path_dst, filepath, path_dst_maxncpy);
685 is_path_changed = true;
686 }
687
688 BLI_freelinkN(path_list, path_store);
689 return is_path_changed;
690}
691
693{
694 ListBase *path_list = MEM_callocN<ListBase>(__func__);
695
696 BPathForeachPathData path_data{};
697 path_data.bmain = bmain;
699 path_data.flag = flag;
700 path_data.user_data = path_list;
701 BKE_bpath_foreach_path_main(&path_data);
702
703 return path_list;
704}
705
706void BKE_bpath_list_restore(Main *bmain, const eBPathForeachFlag flag, void *path_list_handle)
707{
708 ListBase *path_list = static_cast<ListBase *>(path_list_handle);
709
710 BPathForeachPathData path_data{};
711 path_data.bmain = bmain;
713 path_data.flag = flag;
714 path_data.user_data = path_list;
715 BKE_bpath_foreach_path_main(&path_data);
716}
717
718void BKE_bpath_list_free(void *path_list_handle)
719{
720 ListBase *path_list = static_cast<ListBase *>(path_list_handle);
721 /* The whole list should have been consumed by #BKE_bpath_list_restore, see also comment in
722 * #bpath_list_restore. */
724
725 BLI_freelistN(path_list);
726 MEM_freeN(path_list);
727}
728
bool(*)(BPathForeachPathData *bpath_data, char *path_dst, size_t path_dst_maxncpy, const char *path_src) BPathForeachPathFunctionCallback
Definition BKE_bpath.hh:92
eBPathForeachFlag
Definition BKE_bpath.hh:32
@ BKE_BPATH_TRAVERSE_SKIP_WEAK_REFERENCES
Definition BKE_bpath.hh:55
@ BKE_BPATH_FOREACH_PATH_SKIP_LINKED
Definition BKE_bpath.hh:40
@ BKE_BPATH_FOREACH_PATH_ABSOLUTE
Definition BKE_bpath.hh:38
@ BKE_BPATH_FOREACH_PATH_SKIP_PACKED
Definition BKE_bpath.hh:42
@ BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE
Definition BKE_bpath.hh:69
@ BKE_BPATH_FOREACH_PATH_RESOLVE_TOKEN
Definition BKE_bpath.hh:47
@ BKE_BPATH_FOREACH_PATH_RELOAD_EDITED
Definition BKE_bpath.hh:74
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
Definition idtype.cc:146
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:583
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:577
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:887
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_INFO
Definition BKE_report.hh:35
@ RPT_WARNING
Definition BKE_report.hh:38
#define BLI_assert(a)
Definition BLI_assert.h:46
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:360
int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
struct stat BLI_stat_t
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:270
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define BLI_path_ncmp
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define FILE_MAXFILE
#define FILE_MAX
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
#define BLI_path_join(...)
#define FILENAME_IS_CURRPAR(_n)
void BLI_path_split_dir_file(const char *filepath, char *dir, size_t dir_maxncpy, char *file, size_t file_maxncpy) ATTR_NONNULL(1
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool void BLI_path_rel(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1)
#define FILE_MAXDIR
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STREQ(a, b)
Compatibility-like things for windows.
struct __dirstream DIR
struct dirent * readdir(DIR *dp)
int closedir(DIR *dp)
#define S_ISDIR(x)
DIR * opendir(const char *path)
#define S_ISREG(x)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:188
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:189
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SOURCE
Definition DNA_ID.h:1143
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
#define ID_BLEND_PATH(_bmain, _id)
Definition DNA_ID.h:685
Read Guarded memory(de)allocation.
BMesh const char void * data
static bool bpath_list_restore(BPathForeachPathData *bpath_data, char *path_dst, size_t path_dst_maxncpy, const char *path_src)
Definition bpath.cc:668
static bool missing_files_find_foreach_path_cb(BPathForeachPathData *bpath_data, char *path_dst, size_t path_dst_maxncpy, const char *path_src)
Definition bpath.cc:362
static bool relative_convert_foreach_path_cb(BPathForeachPathData *bpath_data, char *path_dst, size_t path_dst_maxncpy, const char *path_src)
Definition bpath.cc:519
bool BKE_bpath_foreach_path_dirfile_fixed_process(BPathForeachPathData *bpath_data, char *path_dir, size_t path_dir_maxncpy, char *path_file, size_t path_file_maxncpy)
Definition bpath.cc:156
static void bpath_absolute_relative_convert(Main *bmain, const char *basedir, ReportList *reports, BPathForeachPathFunctionCallback callback_function, BPathSummary *r_summary)
Definition bpath.cc:588
#define MAX_DIR_RECURSE
Definition bpath.cc:276
void * BKE_bpath_list_backup(Main *bmain, const eBPathForeachFlag flag)
Definition bpath.cc:692
void BKE_bpath_summary_report(const BPathSummary &summary, ReportList *reports)
Definition bpath.cc:59
bool BKE_bpath_foreach_path_fixed_process(BPathForeachPathData *bpath_data, char *path, size_t path_maxncpy)
Definition bpath.cc:125
void BKE_bpath_relative_rebase(Main *bmain, const char *basedir_src, const char *basedir_dst, ReportList *reports, BPathSummary *r_summary)
Definition bpath.cc:478
void BKE_bpath_list_restore(Main *bmain, const eBPathForeachFlag flag, void *path_list_handle)
Definition bpath.cc:706
void BKE_bpath_foreach_path_id(BPathForeachPathData *bpath_data, ID *id)
Definition bpath.cc:75
void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports, BPathSummary *r_summary)
Definition bpath.cc:618
static bool absolute_convert_foreach_path_cb(BPathForeachPathData *bpath_data, char *path_dst, size_t path_dst_maxncpy, const char *path_src)
Definition bpath.cc:554
static bool relative_rebase_foreach_path_cb(BPathForeachPathData *bpath_data, char *path_dst, size_t path_dst_maxncpy, const char *path_src)
Definition bpath.cc:446
void BKE_bpath_list_free(void *path_list_handle)
Definition bpath.cc:718
static bool check_missing_files_foreach_path_cb(BPathForeachPathData *bpath_data, char *, size_t, const char *path_src)
Definition bpath.cc:220
#define FILESIZE_INVALID_DIRECTORY
Definition bpath.cc:277
void BKE_bpath_missing_files_check(Main *bmain, ReportList *reports)
Definition bpath.cc:255
bool BKE_bpath_foreach_path_allocated_process(BPathForeachPathData *bpath_data, char **path)
Definition bpath.cc:187
static bool missing_files_find__recursive(const char *search_directory, const char *filename_src, char r_filepath_new[FILE_MAX], int64_t *r_filesize, int *r_recurse_depth)
Definition bpath.cc:294
void BKE_bpath_foreach_path_main(BPathForeachPathData *bpath_data)
Definition bpath.cc:116
static bool bpath_list_append(BPathForeachPathData *bpath_data, char *, size_t, const char *path_src)
Definition bpath.cc:649
void BKE_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports, BPathSummary *r_summary)
Definition bpath.cc:627
void BKE_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports, const bool find_all)
Definition bpath.cc:407
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define LOG(level)
Definition log.h:97
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
bNodeTree * node_tree_from_id(ID *id)
Definition node.cc:4568
const int status
const char * searchdir
Definition bpath.cc:357
const char * basedir
Definition bpath.cc:356
ReportList * reports
Definition bpath.cc:358
bool find_all
Definition bpath.cc:359
const char * absolute_base_path
Definition BKE_bpath.hh:112
eBPathForeachFlag flag
Definition BKE_bpath.hh:102
BPathForeachPathFunctionCallback callback_function
Definition BKE_bpath.hh:101
BPathSummary summary
Definition bpath.cc:443
const char * basedir_dst
Definition bpath.cc:440
ReportList * reports
Definition bpath.cc:441
const char * basedir_src
Definition bpath.cc:439
BPathSummary summary
Definition bpath.cc:516
ReportList * reports
Definition bpath.cc:514
const char * basedir
Definition bpath.cc:513
const char * name
IDTypeForeachPathFunction foreach_path
Definition DNA_ID.h:414
struct Library * lib
Definition DNA_ID.h:420
char name[258]
Definition DNA_ID.h:432
struct LibraryWeakReference * library_weak_reference
Definition DNA_ID.h:526
char library_filepath[1024]
Definition DNA_ID.h:608
LibraryRuntimeHandle * runtime
Definition DNA_ID.h:579
void * first
PathStore * next
Definition bpath.cc:644
char filepath[0]
Definition bpath.cc:646
PathStore * prev
Definition bpath.cc:644
ListBase list
Definition BKE_report.hh:75
uint8_t flag
Definition wm_window.cc:145