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:
authorCampbell Barton <ideasman42@gmail.com>2011-10-27 05:25:07 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-10-27 05:25:07 +0400
commitcd852ce1a199da11f119394ea719f9699c76c995 (patch)
tree4c23079e83b758bce8ffb9a3c4bb030d3c5d3fbf /source/blender/blenlib/intern/bpath.c
parent4772b72951513d6554a79b94d401414265698daf (diff)
- remove bpath iterator and replace all uses with visitor.
- added flag to optionally receive all paths as absolute.
Diffstat (limited to 'source/blender/blenlib/intern/bpath.c')
-rw-r--r--source/blender/blenlib/intern/bpath.c941
1 files changed, 153 insertions, 788 deletions
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
index 9b1f2ca69bc..36b81d9b9c8 100644
--- a/source/blender/blenlib/intern/bpath.c
+++ b/source/blender/blenlib/intern/bpath.c
@@ -54,7 +54,6 @@
#include "DNA_sound_types.h"
#include "DNA_sequence_types.h"
#include "DNA_vfont_types.h"
-#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
#include "DNA_object_fluidsim.h"
@@ -62,7 +61,6 @@
#include "BLI_bpath.h"
#include "BLI_utildefines.h"
-#include "BKE_global.h"
#include "BKE_image.h" /* so we can check the image's type */
#include "BKE_sequencer.h"
#include "BKE_main.h"
@@ -70,768 +68,116 @@
#include "BKE_report.h"
#include "BKE_library.h"
-typedef struct BPathIteratorSeqData
+static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
{
- int totseq;
- int seq;
- struct Sequence **seqar; /* Sequence */
- struct Scene *scene; /* Current scene */
-} BPathIteratorSeqData;
+ ReportList *reports= (ReportList *)userdata;
-typedef struct BPathIterator
-{
- char* _path; /* never access directly, use BLI_bpathIterator_getPath */
- const char* _lib;
- const char* _name;
- void* data;
- int len;
- int type;
- int flag; /* iterator options */
-
- void (*setpath_callback)(struct BPathIterator *, const char *);
- void (*getpath_callback)(struct BPathIterator *, char *);
-
- const char* base_path; /* base path, the directory the blend file is in - normally bmain->name */
-
- Main *bmain;
-
- /* only for seq data */
- struct BPathIteratorSeqData seqdata;
-} BPathIterator;
-
-#define FILE_MAX 240
-
-
-/* TODO - BPATH_PLUGIN, BPATH_SEQ */
-enum BPathTypes {
- BPATH_IMAGE= 0,
- BPATH_TEXTURE,
- BPATH_TEXT,
- BPATH_SOUND,
- BPATH_FONT,
- BPATH_LIB,
- BPATH_SEQ,
- BPATH_CDATA,
-
- BPATH_DONE
-};
-
-void BLI_bpathIterator_init(struct BPathIterator **bpi_pt, Main *bmain, const char *basedir, const int flag)
-{
- BPathIterator *bpi;
-
- bpi= MEM_mallocN(sizeof(BPathIterator), "BLI_bpathIterator_init");
- *bpi_pt= bpi;
-
- bpi->type= BPATH_IMAGE;
- bpi->data= NULL;
-
- bpi->getpath_callback= NULL;
- bpi->setpath_callback= NULL;
-
- /* Sequencer specific */
- bpi->seqdata.totseq= 0;
- bpi->seqdata.seq= 0;
- bpi->seqdata.seqar= NULL;
- bpi->seqdata.scene= NULL;
-
- bpi->flag= flag;
-
- bpi->base_path= basedir; /* normally bmain->name */
- bpi->bmain= bmain;
-
- BLI_bpathIterator_step(bpi);
-}
-
-#if 0
-static void BLI_bpathIterator_alloc(struct BPathIterator **bpi)
-{
- *bpi= MEM_mallocN(sizeof(BPathIterator), "BLI_bpathIterator_alloc");
-}
-#endif
-
-void BLI_bpathIterator_free(struct BPathIterator *bpi)
-{
- if (bpi->seqdata.seqar)
- MEM_freeN((void *)bpi->seqdata.seqar);
- bpi->seqdata.seqar= NULL;
- bpi->seqdata.scene= NULL;
-
- MEM_freeN(bpi);
-}
-
-void BLI_bpathIterator_getPath(struct BPathIterator *bpi, char *path)
-{
- if (bpi->getpath_callback) {
- bpi->getpath_callback(bpi, path);
+ if (!BLI_exists(path_src)) {
+ BKE_reportf(reports, RPT_WARNING, "Path Not Found \"%s\"", path_src);
}
- else {
- strcpy(path, bpi->_path); /* warning, we assume 'path' are long enough */
- }
-}
-void BLI_bpathIterator_setPath(struct BPathIterator *bpi, const char *path)
-{
- if (bpi->setpath_callback) {
- bpi->setpath_callback(bpi, path);
- }
- else {
- strcpy(bpi->_path, path); /* warning, we assume 'path' are long enough */
- }
+ return FALSE;
}
-void BLI_bpathIterator_getPathExpanded(struct BPathIterator *bpi, char *path_expanded)
-{
- const char *libpath;
-
- BLI_bpathIterator_getPath(bpi, path_expanded);
- libpath= BLI_bpathIterator_getLib(bpi);
-
- if (libpath) { /* check the files location relative to its library path */
- BLI_path_abs(path_expanded, libpath);
- }
- else { /* local data, use the blend files path */
- BLI_path_abs(path_expanded, bpi->base_path);
- }
- BLI_cleanup_file(NULL, path_expanded);
-}
-const char* BLI_bpathIterator_getLib(struct BPathIterator *bpi)
-{
- return bpi->_lib;
-}
-const char* BLI_bpathIterator_getName(struct BPathIterator *bpi)
-{
- return bpi->_name;
-}
-int BLI_bpathIterator_getType(struct BPathIterator *bpi)
-{
- return bpi->type;
-}
-unsigned int BLI_bpathIterator_getPathMaxLen(struct BPathIterator *bpi)
-{
- return bpi->len;
-}
-const char* BLI_bpathIterator_getBasePath(struct BPathIterator *bpi)
-{
- return bpi->base_path;
-}
-
-/* gets the first or the next image that has a path - not a viewer node or generated image */
-static struct Image *ima_stepdata__internal(struct Image *ima, const int step_next, const int flag)
-{
- if (ima==NULL)
- return NULL;
-
- if (step_next)
- ima= ima->id.next;
-
- while (ima) {
- if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
- if(ima->packedfile==NULL || (flag & BPATH_USE_PACKED)) {
- break;
- }
- }
- /* image is not a image with a path, skip it */
- ima= ima->id.next;
- }
- return ima;
-}
-
-static struct Tex *tex_stepdata__internal(struct Tex *tex, const int step_next, const int UNUSED(flag))
-{
- if (tex==NULL)
- return NULL;
-
- if (step_next)
- tex= tex->id.next;
-
- while (tex) {
- if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format))
- break;
- /* image is not a image with a path, skip it */
- tex= tex->id.next;
- }
- return tex;
-}
-
-static struct Text *text_stepdata__internal(struct Text *text, const int step_next, const int UNUSED(flag))
-{
- if (text==NULL)
- return NULL;
-
- if (step_next)
- text= text->id.next;
-
- while (text) {
- if (text->name)
- break;
- /* image is not a image with a path, skip it */
- text= text->id.next;
- }
- return text;
-}
-
-static struct VFont *vf_stepdata__internal(struct VFont *vf, const int step_next, const int flag)
+/* high level function */
+void checkMissingFiles(Main *bmain, ReportList *reports)
{
- if (vf==NULL)
- return NULL;
-
- if (step_next)
- vf= vf->id.next;
-
- while (vf) {
- if (strcmp(vf->name, FO_BUILTIN_NAME)!=0) {
- if(vf->packedfile==NULL || (flag & BPATH_USE_PACKED)) {
- break;
- }
- }
-
- /* font with no path, skip it */
- vf= vf->id.next;
- }
- return vf;
+ bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BPATH_TRAVERSE_ABS, reports);
}
-static struct bSound *snd_stepdata__internal(struct bSound *snd, int step_next, const int flag)
+typedef struct BPathRemap_Data
{
- if (snd==NULL)
- return NULL;
-
- if (step_next)
- snd= snd->id.next;
+ const char *basedir;
+ ReportList *reports;
- while (snd) {
- if(snd->packedfile==NULL || (flag & BPATH_USE_PACKED)) {
- break;
- }
+ int count_tot;
+ int count_changed;
+ int count_failed;
+} BPathRemap_Data;
- /* font with no path, skip it */
- snd= snd->id.next;
- }
- return snd;
-}
-
-static struct Sequence *seq_stepdata__internal(struct BPathIterator *bpi, int step_next)
+static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char *path_src)
{
- Editing *ed;
- Sequence *seq;
-
- /* Initializing */
- if (bpi->seqdata.scene==NULL) {
- bpi->seqdata.scene= bpi->bmain->scene.first;
- }
-
- if (step_next) {
- bpi->seqdata.seq++;
- }
-
- while (bpi->seqdata.scene) {
- ed= seq_give_editing(bpi->seqdata.scene, 0);
- if (ed) {
- if (bpi->seqdata.seqar == NULL) {
- /* allocate the sequencer array */
- seq_array(ed, &bpi->seqdata.seqar, &bpi->seqdata.totseq, 0);
- bpi->seqdata.seq= 0;
- }
-
- if (bpi->seqdata.seq >= bpi->seqdata.totseq) {
- seq= NULL;
- }
- else {
- seq= bpi->seqdata.seqar[bpi->seqdata.seq];
- while (!SEQ_HAS_PATH(seq) && seq->plugin==NULL) {
- bpi->seqdata.seq++;
- if (bpi->seqdata.seq >= bpi->seqdata.totseq) {
- seq= NULL;
- break;
- }
- seq= bpi->seqdata.seqar[bpi->seqdata.seq];
- }
- }
- if (seq) {
- return seq;
- }
- else {
- /* keep looking through the next scene, reallocate seq array */
- if (bpi->seqdata.seqar) {
- MEM_freeN((void *)bpi->seqdata.seqar);
- bpi->seqdata.seqar= NULL;
- }
- bpi->seqdata.scene= bpi->seqdata.scene->id.next;
- }
- }
- else {
- /* no seq data in this scene, next */
- bpi->seqdata.scene= bpi->seqdata.scene->id.next;
- }
- }
+ BPathRemap_Data *data= (BPathRemap_Data *)userdata;
- return NULL;
-}
+ data->count_tot++;
-static void seq_getpath(struct BPathIterator *bpi, char *path)
-{
- Sequence *seq= (Sequence *)bpi->data;
-
-
- path[0]= '\0'; /* incase we cant get the path */
- if (seq==NULL) return;
- if (SEQ_HAS_PATH(seq)) {
- if (ELEM3(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SOUND)) {
- BLI_strncpy(path, seq->strip->dir, FILE_MAX);
- BLI_add_slash(path); /* incase its missing */
- if (seq->strip->stripdata) { /* should always be true! */
- /* Using the first image is weak for image sequences */
- strcat(path, seq->strip->stripdata->name);
- }
- }
- else {
- /* simple case */
- BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir));
- }
- }
- else if (seq->plugin) {
- BLI_strncpy(seq->plugin->name, path, sizeof(seq->plugin->name));
+ if(strncmp(path_src, "//", 2)==0) {
+ return FALSE; /* already relative */
}
-}
-
-static void seq_setpath(struct BPathIterator *bpi, const char *path)
-{
- Sequence *seq= (Sequence *)bpi->data;
- if (seq==NULL) return;
-
- if (SEQ_HAS_PATH(seq)) {
- if (ELEM3(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SOUND)) {
- BLI_split_dirfile(path, seq->strip->dir, seq->strip->stripdata->name, sizeof(seq->strip->dir), sizeof(seq->strip->stripdata->name));
+ else {
+ strcpy(path_dst, path_src);
+ BLI_path_rel(path_dst, data->basedir);
+ if (strncmp(path_dst, "//", 2)==0) {
+ data->count_changed++;
}
else {
- /* simple case */
- BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir));
- }
- }
- else if (seq->plugin) {
- BLI_strncpy(seq->plugin->name, path, sizeof(seq->plugin->name));
- }
-}
-
-static void text_getpath(struct BPathIterator *bpi, char *path)
-{
- Text *text= (Text *)bpi->data;
- path[0]= '\0'; /* incase we cant get the path */
- if(text->name) {
- strcpy(path, text->name);
- }
-}
-
-static void text_setpath(struct BPathIterator *bpi, const char *path)
-{
- Text *text= (Text *)bpi->data;
- if (text==NULL) return;
-
- if(text->name) {
- MEM_freeN(text->name);
- }
-
- text->name= BLI_strdup(path);
-}
-
-static struct Mesh *cdata_stepdata__internal(struct Mesh *me, int step_next)
-{
- if (me==NULL)
- return NULL;
-
- if (step_next)
- me= me->id.next;
-
- while (me) {
- if (me->fdata.external) {
- break;
- }
-
- me= me->id.next;
- }
- return me;
-}
-
-static void bpi_type_step__internal(struct BPathIterator *bpi)
-{
- bpi->type++; /* advance to the next type */
- bpi->data= NULL;
-
- switch (bpi->type) {
- case BPATH_SEQ:
- bpi->getpath_callback= seq_getpath;
- bpi->setpath_callback= seq_setpath;
- break;
- case BPATH_TEXT: /* path is malloc'd */
- bpi->getpath_callback= text_getpath;
- bpi->setpath_callback= text_setpath;
- break;
- default:
- bpi->getpath_callback= NULL;
- bpi->setpath_callback= NULL;
- break;
- }
-}
-
-void BLI_bpathIterator_step(struct BPathIterator *bpi)
-{
- while (bpi->type != BPATH_DONE) {
-
- if ((bpi->type) == BPATH_IMAGE) {
- /*if (bpi->data) bpi->data= ((ID *)bpi->data)->next;*/
- if (bpi->data) bpi->data= ima_stepdata__internal((Image *)bpi->data, 1, bpi->flag); /* must skip images that have no path */
- else bpi->data= ima_stepdata__internal(bpi->bmain->image.first, 0, bpi->flag);
-
- if (bpi->data) {
- /* get the path info from this datatype */
- Image *ima= (Image *)bpi->data;
-
- bpi->_lib= ima->id.lib ? ima->id.lib->filepath : NULL;
- bpi->_path= ima->name;
- bpi->_name= ima->id.name+2;
- bpi->len= sizeof(ima->name);
-
- /* we are done, advancing to the next item, this type worked fine */
- break;
-
- }
- else {
- bpi_type_step__internal(bpi);
- }
- }
-
- if ((bpi->type) == BPATH_TEXTURE) {
- /*if (bpi->data) bpi->data= ((ID *)bpi->data)->next;*/
- if (bpi->data) bpi->data= tex_stepdata__internal( (Tex *)bpi->data, 1, bpi->flag); /* must skip images that have no path */
- else bpi->data= tex_stepdata__internal(bpi->bmain->tex.first, 0, bpi->flag);
-
- if (bpi->data) {
- /* get the path info from this datatype */
- Tex *tex= (Tex *)bpi->data;
-
- if(tex->type == TEX_VOXELDATA) {
- bpi->_lib= tex->id.lib ? tex->id.lib->filepath : NULL;
- bpi->_path= tex->vd->source_path;
- bpi->_name= tex->id.name+2;
- bpi->len= sizeof(tex->vd->source_path);
- }
- else {
- assert(!"Texture has no path, incorrect step 'tex_stepdata__internal'");
- }
-
- /* we are done, advancing to the next item, this type worked fine */
- break;
-
- }
- else {
- bpi_type_step__internal(bpi);
- }
- }
-
- if ((bpi->type) == BPATH_TEXT) {
- /*if (bpi->data) bpi->data= ((ID *)bpi->data)->next;*/
- if (bpi->data) bpi->data= text_stepdata__internal((Text *)bpi->data, 1, bpi->flag); /* must skip images that have no path */
- else bpi->data= text_stepdata__internal(bpi->bmain->text.first, 0, bpi->flag);
-
- if (bpi->data) {
- /* get the path info from this datatype */
- Text *text= (Text *)bpi->data;
-
- bpi->_lib= text->id.lib ? text->id.lib->filepath : NULL;
- bpi->_path= NULL; /* bpi->path= text->name; */ /* get/set functions override. */
- bpi->_name= text->id.name+2;
- bpi->len= FILE_MAX; /* malloc'd but limit anyway since large paths may mess up other areas */
-
- /* we are done, advancing to the next item, this type worked fine */
- break;
-
- }
- else {
- bpi_type_step__internal(bpi);
- }
- }
- else if ((bpi->type) == BPATH_SOUND) {
- if (bpi->data) bpi->data= snd_stepdata__internal((bSound *)bpi->data, 1, bpi->flag); /* must skip images that have no path */
- else bpi->data= snd_stepdata__internal(bpi->bmain->sound.first, 0, bpi->flag);
-
- if (bpi->data) {
- /* get the path info from this datatype */
- bSound *snd= (bSound *)bpi->data;
-
- bpi->_lib= snd->id.lib ? snd->id.lib->filepath : NULL;
- bpi->_path= snd->name;
- bpi->_name= snd->id.name+2;
- bpi->len= sizeof(snd->name);
-
- /* we are done, advancing to the next item, this type worked fine */
- break;
- }
- else {
- bpi_type_step__internal(bpi);
- }
- }
- else if ((bpi->type) == BPATH_FONT) {
-
- if (bpi->data) bpi->data= vf_stepdata__internal((VFont *)bpi->data, 1, bpi->flag);
- else bpi->data= vf_stepdata__internal(bpi->bmain->vfont.first, 0, bpi->flag);
-
- if (bpi->data) {
- /* get the path info from this datatype */
- VFont *vf= (VFont *)bpi->data;
-
- bpi->_lib= vf->id.lib ? vf->id.lib->filepath : NULL;
- bpi->_path= vf->name;
- bpi->_name= vf->id.name+2;
- bpi->len= sizeof(vf->name);
-
- /* we are done, advancing to the next item, this type worked fine */
- break;
- }
- else {
- bpi_type_step__internal(bpi);
- }
-
- }
- else if ((bpi->type) == BPATH_LIB) {
- if (bpi->data) bpi->data= ((ID *)bpi->data)->next;
- else bpi->data= bpi->bmain->library.first;
-
- if (bpi->data) {
- /* get the path info from this datatype */
- Library *lib= (Library *)bpi->data;
-
- bpi->_lib= NULL;
- bpi->_path= lib->name;
- bpi->_name= NULL;
- bpi->len= sizeof(lib->name);
-
- /* we are done, advancing to the next item, this type worked fine */
- break;
- }
- else {
- bpi_type_step__internal(bpi);
- }
- }
- else if ((bpi->type) == BPATH_SEQ) {
- if (bpi->data) bpi->data= seq_stepdata__internal( bpi, 1 );
- else bpi->data= seq_stepdata__internal( bpi, 0 );
- if (bpi->data) {
- Sequence *seq= (Sequence *)bpi->data;
- bpi->_lib= NULL;
- bpi->_name= seq->name+2;
- bpi->len= seq->plugin ? sizeof(seq->plugin->name) : sizeof(seq->strip->dir) + sizeof(seq->strip->stripdata->name);
- break;
- }
- else {
- bpi_type_step__internal(bpi);
- }
- }
- else if ((bpi->type) == BPATH_CDATA) {
- if (bpi->data) bpi->data= cdata_stepdata__internal( bpi->data, 1 );
- else bpi->data= cdata_stepdata__internal( bpi->bmain->mesh.first, 0 );
-
- if (bpi->data) {
- Mesh *me= (Mesh *)bpi->data;
- bpi->_lib= me->id.lib ? me->id.lib->filepath : NULL;
- bpi->_path= me->fdata.external->filename;
- bpi->_name= me->id.name+2;
- bpi->len= sizeof(me->fdata.external->filename);
- break;
- }
- else {
- bpi_type_step__internal(bpi);
- }
+ BKE_reportf(data->reports, RPT_WARNING, "Path cant be made relative \"%s\"", path_src);
+ data->count_failed++;
}
+ return TRUE;
}
}
-int BLI_bpathIterator_isDone( struct BPathIterator *bpi)
-{
- return bpi->type==BPATH_DONE;
-}
-
-/* include the path argument */
-static void bpath_as_report(struct BPathIterator *bpi, const char *message, ReportList *reports)
+void makeFilesRelative(Main *bmain, const char *basedir, ReportList *reports)
{
- const char *prefix;
- const char *name;
- char path_expanded[FILE_MAXDIR*2];
+ BPathRemap_Data data= {0};
- if(reports==NULL)
+ if(basedir[0] == '\0') {
+ printf("%s: basedir='', this is a bug\n", __func__);
return;
-
- switch(BLI_bpathIterator_getType(bpi)) {
- case BPATH_IMAGE:
- prefix= "Image";
- break;
- case BPATH_TEXTURE:
- prefix= "Texture";
- break;
- case BPATH_TEXT:
- prefix= "Text";
- break;
- case BPATH_SOUND:
- prefix= "Sound";
- break;
- case BPATH_FONT:
- prefix= "Font";
- break;
- case BPATH_LIB:
- prefix= "Library";
- break;
- case BPATH_SEQ:
- prefix= "Sequence";
- break;
- case BPATH_CDATA:
- prefix= "Mesh Data";
- break;
- default:
- prefix= "Unknown";
- break;
}
- name= BLI_bpathIterator_getName(bpi);
- BLI_bpathIterator_getPathExpanded(bpi, path_expanded);
+ data.basedir= basedir;
+ data.reports= reports;
- if(reports) {
- if (name) BKE_reportf(reports, RPT_WARNING, "%s \"%s\", \"%s\": %s", prefix, name, path_expanded, message);
- else BKE_reportf(reports, RPT_WARNING, "%s \"%s\": %s", prefix, path_expanded, message);
- }
+ bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data);
+ BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
+ "Total files %d|Changed %d|Failed %d",
+ data.count_tot, data.count_changed, data.count_failed);
}
-/* high level function */
-void checkMissingFiles(Main *bmain, ReportList *reports)
+static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char *path_src)
{
- struct BPathIterator *bpi;
+ BPathRemap_Data *data= (BPathRemap_Data *)userdata;
- /* be sure there is low chance of the path being too short */
- char filepath_expanded[FILE_MAXDIR*2];
+ data->count_tot++;
- BLI_bpathIterator_init(&bpi, bmain, bmain->name, 0);
- while (!BLI_bpathIterator_isDone(bpi)) {
- BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded);
-
- if (!BLI_exists(filepath_expanded))
- bpath_as_report(bpi, "file not found", reports);
-
- BLI_bpathIterator_step(bpi);
+ if(strncmp(path_src, "//", 2)!=0) {
+ return FALSE; /* already absolute */
}
- BLI_bpathIterator_free(bpi);
-}
-
-/* dont log any errors at the moment, should probably do this */
-void makeFilesRelative(Main *bmain, const char *basedir, ReportList *reports)
-{
- int tot= 0, changed= 0, failed= 0, linked= 0;
- struct BPathIterator *bpi;
- char filepath[FILE_MAX];
- const char *libpath;
-
- /* be sure there is low chance of the path being too short */
- char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE];
-
- if(basedir[0] == '\0') {
- printf("makeFilesRelative: basedir='', this is a bug\n");
- return;
- }
-
- BLI_bpathIterator_init(&bpi, bmain, basedir, 0);
- while (!BLI_bpathIterator_isDone(bpi)) {
- BLI_bpathIterator_getPath(bpi, filepath);
- libpath= BLI_bpathIterator_getLib(bpi);
-
- if(strncmp(filepath, "//", 2)) {
- if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */
- linked++;
- }
- else { /* local data, use the blend files path */
- BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative));
- /* Important BLI_cleanup_dir runs before the path is made relative
- * because it wont work for paths that start with "//../" */
- BLI_cleanup_file(bpi->base_path, filepath_relative); /* fix any /foo/../foo/ */
- BLI_path_rel(filepath_relative, bpi->base_path);
- /* be safe and check the length */
- if (BLI_bpathIterator_getPathMaxLen(bpi) <= strlen(filepath_relative)) {
- bpath_as_report(bpi, "couldn't make path relative (too long)", reports);
- failed++;
- }
- else {
- if(strncmp(filepath_relative, "//", 2)==0) {
- BLI_bpathIterator_setPath(bpi, filepath_relative);
- changed++;
- }
- else {
- bpath_as_report(bpi, "couldn't make path relative", reports);
- failed++;
- }
- }
- }
+ else {
+ strcpy(path_dst, path_src);
+ BLI_path_abs(path_dst, data->basedir);
+ if (strncmp(path_dst, "//", 2)!=0) {
+ data->count_changed++;
+ }
+ else {
+ BKE_reportf(data->reports, RPT_WARNING, "Path cant be made absolute \"%s\"", path_src);
+ data->count_failed++;
}
- BLI_bpathIterator_step(bpi);
- tot++;
+ return TRUE;
}
- BLI_bpathIterator_free(bpi);
-
- if(reports)
- BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
}
-/* dont log any errors at the moment, should probably do this -
- * Verry similar to makeFilesRelative - keep in sync! */
+/* similar to makeFilesRelative - keep in sync! */
void makeFilesAbsolute(Main *bmain, const char *basedir, ReportList *reports)
{
- int tot= 0, changed= 0, failed= 0, linked= 0;
-
- struct BPathIterator *bpi;
- char filepath[FILE_MAX];
- const char *libpath;
-
- /* be sure there is low chance of the path being too short */
- char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE];
+ BPathRemap_Data data= {0};
if(basedir[0] == '\0') {
- printf("makeFilesAbsolute: basedir='', this is a bug\n");
+ printf("%s: basedir='', this is a bug\n", __func__);
return;
}
- BLI_bpathIterator_init(&bpi, bmain, basedir, 0);
- while (!BLI_bpathIterator_isDone(bpi)) {
- BLI_bpathIterator_getPath(bpi, filepath);
- libpath= BLI_bpathIterator_getLib(bpi);
+ data.basedir= basedir;
+ data.reports= reports;
- if(strncmp(filepath, "//", 2)==0) {
- if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */
- linked++;
- }
- else { /* get the expanded path and check it is relative or too long */
- BLI_bpathIterator_getPathExpanded(bpi, filepath_absolute);
- BLI_cleanup_file(bpi->base_path, filepath_absolute); /* fix any /foo/../foo/ */
- /* to be safe, check the length */
- if (BLI_bpathIterator_getPathMaxLen(bpi) <= strlen(filepath_absolute)) {
- bpath_as_report(bpi, "couldn't make absolute (too long)", reports);
- failed++;
- }
- else {
- if(strncmp(filepath_absolute, "//", 2)) {
- BLI_bpathIterator_setPath(bpi, filepath_absolute);
- changed++;
- }
- else {
- bpath_as_report(bpi, "couldn't make absolute", reports);
- failed++;
- }
- }
- }
- }
- BLI_bpathIterator_step(bpi);
- tot++;
- }
- BLI_bpathIterator_free(bpi);
+ bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data);
- if(reports)
- BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+ BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
+ "Total files %d|Changed %d|Failed %d",
+ data.count_tot, data.count_changed, data.count_failed);
}
@@ -890,77 +236,64 @@ static int findFileRecursive(char *filename_new, const char *dirname, const char
return 1;
}
-/* high level function - call from fileselector */
-void findMissingFiles(Main *bmain, const char *str)
+typedef struct BPathFind_Data
{
- struct BPathIterator *bpi;
-
- /* be sure there is low chance of the path being too short */
- char filepath_expanded[FILE_MAXDIR*2];
- char filepath[FILE_MAX];
- const char *libpath;
- int filesize, recur_depth;
-
- char dirname[FILE_MAX], filename_new[FILE_MAX];
-
- //XXX waitcursor( 1 );
-
- BLI_split_dir_part(str, dirname, sizeof(dirname));
+ const char *basedir;
+ char searchdir[FILE_MAX];
+ ReportList *reports;
+} BPathFind_Data;
- BLI_bpathIterator_init(&bpi, bmain, bmain->name, 0);
-
- while (!BLI_bpathIterator_isDone(bpi)) {
- BLI_bpathIterator_getPath(bpi, filepath);
- libpath= BLI_bpathIterator_getLib(bpi);
-
- /* Check if esc was pressed because searching files can be slow */
- /*XXX if (blender_test_break()) {
- break;
- }*/
-
- if (libpath==NULL) {
-
- BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded);
+static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char *path_src)
+{
+ BPathFind_Data *data= (BPathFind_Data *)userdata;
+ char filename_new[FILE_MAX];
- if (!BLI_exists(filepath_expanded)) {
- /* can the dir be opened? */
- filesize= -1;
- recur_depth= 0;
+ int filesize= -1;
+ int recur_depth= 0;
- findFileRecursive(filename_new, dirname, BLI_path_basename(filepath), &filesize, &recur_depth);
- if (filesize == -1) { /* could not open dir */
- printf("Could not open dir \"%s\"\n", dirname);
- return;
- }
+ findFileRecursive(filename_new,
+ data->searchdir, BLI_path_basename((char *)path_src),
+ &filesize, &recur_depth);
- if (filesize > 0) {
+ if (filesize == -1) { /* could not open dir */
+ BKE_reportf(data->reports, RPT_WARNING,
+ "Could not find \"%s\" in \"%s\"",
+ BLI_path_basename((char *)path_src), data->searchdir);
+ return FALSE;
+ }
+ else {
+ strcpy(path_dst, filename_new);
+ return TRUE;
+ }
+}
- if (BLI_bpathIterator_getPathMaxLen(bpi) < strlen(filename_new)) {
- printf("cannot set path \"%s\" too long!", filename_new);
- }
- else {
- /* copy the found path into the old one */
- if (G.relbase_valid)
- BLI_path_rel(filename_new, bpi->base_path);
+void findMissingFiles(Main *bmain, const char *searchpath, ReportList *reports)
+{
+ struct BPathFind_Data data= {0};
- BLI_bpathIterator_setPath(bpi, filename_new);
- }
- }
- }
- }
- BLI_bpathIterator_step(bpi);
- }
- BLI_bpathIterator_free(bpi);
+ data.reports= reports;
+ BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir));
- //XXX waitcursor( 0 );
+ bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data);
}
/* Run a visitor on a string, replacing the contents of the string as needed. */
-static int rewrite_path_fixed(char path[FILE_MAX], BPathVisitor visit_cb, void *userdata)
+static int rewrite_path_fixed(char *path, BPathVisitor visit_cb, const char *absbase, void *userdata)
{
+ char path_src_buf[FILE_MAX];
+ const char *path_src;
char path_dst[FILE_MAX];
- if (visit_cb(userdata, path_dst, (const char *)path)) {
+ if (absbase) {
+ BLI_strncpy(path_src_buf, path, sizeof(path_src_buf));
+ BLI_path_abs(path_src_buf, absbase);
+ path_src= path_src_buf;
+ }
+ else {
+ path_src= path;
+ }
+
+ if (visit_cb(userdata, path_dst, path_src)) {
BLI_strncpy(path, path_dst, FILE_MAX);
return TRUE;
}
@@ -969,13 +302,17 @@ static int rewrite_path_fixed(char path[FILE_MAX], BPathVisitor visit_cb, void *
}
}
-static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], char path_file[FILE_MAXFILE], BPathVisitor visit_cb, void *userdata)
+static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], char path_file[FILE_MAXFILE], BPathVisitor visit_cb, const char *absbase, void *userdata)
{
char path_src[FILE_MAX];
char path_dst[FILE_MAX];
BLI_join_dirfile(path_src, sizeof(path_src), path_dir, path_file);
+ if (absbase) {
+ BLI_path_abs(path_src, absbase);
+ }
+
if (visit_cb(userdata, path_dst, (const char *)path_src)) {
BLI_split_dirfile(path_dst, path_dir, path_file,
sizeof(path_dir), sizeof(path_file));
@@ -986,11 +323,22 @@ static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], char path_file
}
}
-static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, void *userdata)
+static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *absbase, void *userdata)
{
+ char path_src_buf[FILE_MAX];
+ const char *path_src;
char path_dst[FILE_MAX];
- if (visit_cb(userdata, path_dst, (const char *)(*path))) {
+ if (absbase) {
+ BLI_strncpy(path_src_buf, *path, sizeof(path_src_buf));
+ BLI_path_abs(path_src_buf, absbase);
+ path_src= path_src_buf;
+ }
+ else {
+ path_src= *path;
+ }
+
+ if (visit_cb(userdata, path_dst, path_src)) {
MEM_freeN((*path));
(*path)= BLI_strdup(path_dst);
return TRUE;
@@ -1001,36 +349,38 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, void *userdata
}
/* Run visitor function 'visit' on all paths contained in 'id'. */
-void bpath_traverse_id(ID *id, BPathVisitor visit_cb, void *userdata)
+void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, int flag, void *userdata)
{
Image *ima;
+ const char *absbase= (flag & BPATH_TRAVERSE_ABS) ? (id->lib ? id->lib->filepath : bmain->name) : NULL;
+
switch(GS(id->name)) {
case ID_IM:
ima = (Image *)id;
if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
- rewrite_path_fixed(ima->name, visit_cb, userdata);
+ rewrite_path_fixed(ima->name, visit_cb, absbase, userdata);
break;
case ID_OB:
{
Object *ob= (Object *)id;
if (ob->fluidsimSettings) {
- rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, userdata);
+ rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, userdata);
}
/* TODO: add modifiers, e.g. point cache for particles. */
}
break;
case ID_SO:
- rewrite_path_fixed(((bSound *)id)->name, visit_cb, userdata);
+ rewrite_path_fixed(((bSound *)id)->name, visit_cb, absbase, userdata);
break;
case ID_TXT:
if (((Text*)id)->name) {
- rewrite_path_alloc(&((Text *)id)->name, visit_cb, userdata);
+ rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, userdata);
}
break;
case ID_VF:
if (strcmp(((VFont*)id)->name, FO_BUILTIN_NAME) != 0) {
- rewrite_path_fixed(((VFont *)id)->name, visit_cb, userdata);
+ rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, userdata);
}
break;
case ID_TE:
@@ -1042,7 +392,7 @@ void bpath_traverse_id(ID *id, BPathVisitor visit_cb, void *userdata)
//rewrite_path(tex->plugin->name, visit_cb, userdata);
}
if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) {
- rewrite_path_fixed(tex->vd->source_path, visit_cb, userdata);
+ rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, userdata);
}
}
break;
@@ -1056,15 +406,15 @@ void bpath_traverse_id(ID *id, BPathVisitor visit_cb, void *userdata)
SEQ_BEGIN(scene->ed, seq) {
if (SEQ_HAS_PATH(seq)) {
if (ELEM3(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SOUND)) {
- rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, visit_cb, userdata);
+ rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, visit_cb, absbase, userdata);
}
else {
/* simple case */
- rewrite_path_fixed(seq->strip->dir, visit_cb, userdata);
+ rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, userdata);
}
}
else if (seq->plugin) {
- rewrite_path_fixed(seq->plugin->name, visit_cb, userdata);
+ rewrite_path_fixed(seq->plugin->name, visit_cb, absbase, userdata);
}
}
@@ -1076,14 +426,14 @@ void bpath_traverse_id(ID *id, BPathVisitor visit_cb, void *userdata)
{
Mesh *me= (Mesh *)id;
if (me->fdata.external) {
- rewrite_path_fixed(me->fdata.external->filename, visit_cb, userdata);
+ rewrite_path_fixed(me->fdata.external->filename, visit_cb, absbase, userdata);
}
}
break;
case ID_LI:
{
Library *lib= (Library *)id;
- if(rewrite_path_fixed(lib->name, visit_cb, userdata)) {
+ if(rewrite_path_fixed(lib->name, visit_cb, absbase, userdata)) {
BKE_library_filepath_set(lib, lib->name);
}
}
@@ -1095,6 +445,21 @@ void bpath_traverse_id(ID *id, BPathVisitor visit_cb, void *userdata)
}
}
+void bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, int flag, void *userdata)
+{
+ ID *id;
+ for(id= lb->first; id; id= id->next) {
+ bpath_traverse_id(bmain, id, visit_cb, flag, userdata);
+ }
+}
+
+void bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, int flag, void *userdata)
+{
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a= set_listbasepointers(bmain, lbarray);
+ while(a--) bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, userdata);
+}
+
/* Rewrites a relative path to be relative to the main file - unless the path is
absolute, in which case it is not altered. */
int bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src)