From cd852ce1a199da11f119394ea719f9699c76c995 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Oct 2011 01:25:07 +0000 Subject: - remove bpath iterator and replace all uses with visitor. - added flag to optionally receive all paths as absolute. --- source/blender/blenlib/intern/bpath.c | 941 ++++++---------------------------- 1 file changed, 153 insertions(+), 788 deletions(-) (limited to 'source/blender/blenlib/intern/bpath.c') 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) -- cgit v1.2.3