- remove bpath iterator and replace all uses with visitor.
authorCampbell Barton <ideasman42@gmail.com>
Thu, 27 Oct 2011 01:25:07 +0000 (01:25 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 27 Oct 2011 01:25:07 +0000 (01:25 +0000)
- added flag to optionally receive all paths as absolute.

source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/library.c
source/blender/blenlib/BLI_bpath.h
source/blender/blenlib/intern/bpath.c
source/blender/editors/space_info/info_ops.c
source/blender/python/intern/bpy.c

index 4cbdbeb..6e343e8 100644 (file)
@@ -160,22 +160,19 @@ static void clear_global(void)
        G.main= NULL;
 }
 
+static int clean_paths_visit_cb(void *UNUSED(userdata), char *path_dst, const char *path_src)
+{
+       strcpy(path_dst, path_src);
+       BLI_clean(path_dst);
+       return (strcmp(path_dst, path_src) == 0) ? FALSE : TRUE;
+}
+
 /* make sure path names are correct for OS */
 static void clean_paths(Main *main)
 {
-       struct BPathIterator *bpi;
-       char filepath_expanded[1024];
        Scene *scene;
 
-       for(BLI_bpathIterator_init(&bpi, main, main->name, BPATH_USE_PACKED); !BLI_bpathIterator_isDone(bpi); BLI_bpathIterator_step(bpi)) {
-               BLI_bpathIterator_getPath(bpi, filepath_expanded);
-
-               BLI_clean(filepath_expanded);
-
-               BLI_bpathIterator_setPath(bpi, filepath_expanded);
-       }
-
-       BLI_bpathIterator_free(bpi);
+       bpath_traverse_main(main, clean_paths_visit_cb, 0, NULL);
 
        for(scene= main->scene.first; scene; scene= scene->id.next) {
                BLI_clean(scene->r.pic);
index 986b3ac..d60d32a 100644 (file)
@@ -391,7 +391,7 @@ void make_local_image(struct Image *ima)
                iman->id.us= 0;
 
                /* Remap paths of new ID using old library as base. */
-               bpath_traverse_id(&iman->id, bpath_relocate_visitor, user_data);
+               bpath_traverse_id(bmain, &iman->id, bpath_relocate_visitor, 0, user_data);
 
                tex= bmain->tex.first;
                while(tex) {
index f6a5a7f..be495a7 100644 (file)
@@ -1253,7 +1253,7 @@ int new_id(ListBase *lb, ID *id, const char *tname)
 void id_clear_lib_data(Main *bmain, ID *id)
 {
        char *user_data[2]= {bmain->name, id->lib->filepath};
-       bpath_traverse_id(id, bpath_relocate_visitor, user_data);
+       bpath_traverse_id(bmain, id, bpath_relocate_visitor, 0, user_data);
        id->lib= NULL;
        id->flag= LIB_LOCAL;
        new_id(which_libbase(bmain, GS(id->name)), id, NULL);
index 478fe0a..6a167d6 100644 (file)
 #ifndef BLI_BPATH_H
 #define BLI_BPATH_H
 
-struct BPathIterator;
 struct ReportList;
 struct Main;
 struct ID;
 
-void                   BLI_bpathIterator_init                          (struct BPathIterator **bpi, struct Main *bmain, const char *basedir, const int flag);
-void                   BLI_bpathIterator_free                          (struct BPathIterator *bpi);
-const char*            BLI_bpathIterator_getLib                        (struct BPathIterator *bpi);
-const char*            BLI_bpathIterator_getName                       (struct BPathIterator *bpi);
-int                            BLI_bpathIterator_getType                       (struct BPathIterator *bpi);
-unsigned int   BLI_bpathIterator_getPathMaxLen         (struct BPathIterator *bpi);
-const char*            BLI_bpathIterator_getBasePath           (struct BPathIterator *bpi);
-void                   BLI_bpathIterator_step                          (struct BPathIterator *bpi);
-int                            BLI_bpathIterator_isDone                        (struct BPathIterator *bpi);
-void                   BLI_bpathIterator_getPath                       (struct BPathIterator *bpi, char *path);
-void                   BLI_bpathIterator_getPathExpanded       (struct BPathIterator *bpi, char *path_expanded);
-void                   BLI_bpathIterator_setPath                       (struct BPathIterator *bpi, const char *path);
-
 /* Function that does something with an ID's file path. Should return 1 if the
    path has changed, and in that case, should write the result to pathOut. */
 typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src);
 /* Executes 'visit' for each path associated with 'id'. */
-void bpath_traverse_id(struct ID *id, BPathVisitor visit, void *userdata);
+void bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, int flag, void *userdata);
+void bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, int flag, void *userdata);
+void bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, int flag, void *userdata);
 int bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
 
+#define BPATH_TRAVERSE_ABS 1 /* convert paths to absolute */
+
 /* high level funcs */
 
 /* creates a text file with missing files if there are any */
 void checkMissingFiles(struct Main *bmain, struct ReportList *reports);
 void makeFilesRelative(struct Main *bmain, const char *basedir, struct ReportList *reports);
 void makeFilesAbsolute(struct Main *bmain, const char *basedir, struct ReportList *reports);
-void findMissingFiles(struct Main *bmain, const char *str);
+void findMissingFiles(struct Main *bmain, const char *searchpath, struct ReportList *reports);
 
 #define BPATH_USE_PACKED 1
 
index 9b1f2ca..36b81d9 100644 (file)
@@ -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"
 #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)
index 2b3785e..deff1c7 100644 (file)
@@ -253,10 +253,12 @@ void FILE_OT_make_paths_absolute(wmOperatorType *ot)
 
 /********************* report missing files operator *********************/
 
-static int report_missing_files_exec(bContext *UNUSED(C), wmOperator *op)
+static int report_missing_files_exec(bContext *C, wmOperator *op)
 {
+       Main *bmain= CTX_data_main(C);
+
        /* run the missing file check */
-       checkMissingFiles(G.main, op->reports);
+       checkMissingFiles(bmain, op->reports);
        
        return OPERATOR_FINISHED;
 }
@@ -276,13 +278,12 @@ void FILE_OT_report_missing_files(wmOperatorType *ot)
 
 /********************* find missing files operator *********************/
 
-static int find_missing_files_exec(bContext *UNUSED(C), wmOperator *op)
+static int find_missing_files_exec(bContext *C, wmOperator *op)
 {
-       char *path;
-       
-       path= RNA_string_get_alloc(op->ptr, "filepath", NULL, 0);
-       findMissingFiles(G.main, path);
-       MEM_freeN(path);
+       Main *bmain= CTX_data_main(C);
+       const char *searchpath= RNA_string_get_alloc(op->ptr, "filepath", NULL, 0);
+       findMissingFiles(bmain, searchpath, op->reports);
+       MEM_freeN((void *)searchpath);
 
        return OPERATOR_FINISHED;
 }
index d9d1c16..d740f7c 100644 (file)
@@ -81,6 +81,15 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self))
        return ret;
 }
 
+static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
+{
+       PyObject *list= (PyObject *)userdata;
+       PyObject *item= PyUnicode_DecodeFSDefault(path_src);
+       PyList_Append(list, item);
+       Py_DECREF(item);
+       return FALSE; /* never edits the path */
+}
+
 PyDoc_STRVAR(bpy_blend_paths_doc,
 ".. function:: blend_paths(absolute=False)\n"
 "\n"
@@ -93,11 +102,8 @@ PyDoc_STRVAR(bpy_blend_paths_doc,
 );
 static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
 {
-       struct BPathIterator *bpi;
-       PyObject *list, *st; /* stupidly big string to be safe */
-       /* be sure there is low chance of the path being too short */
-       char filepath_expanded[1024];
-       const char *lib;
+       int flag= 0;
+       PyObject *list;
 
        int absolute= 0;
        static const char *kwlist[]= {"absolute", NULL};
@@ -105,29 +111,13 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
        if (!PyArg_ParseTupleAndKeywords(args, kw, "|i:blend_paths", (char **)kwlist, &absolute))
                return NULL;
 
-       list= PyList_New(0);
-
-       for (BLI_bpathIterator_init(&bpi, G.main, G.main->name, 0); !BLI_bpathIterator_isDone(bpi); BLI_bpathIterator_step(bpi)) {
-               /* build the list */
-               if (absolute) {
-                       BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded);
-               }
-               else {
-                       lib= BLI_bpathIterator_getLib(bpi);
-                       if (lib && (BLI_path_cmp(lib, BLI_bpathIterator_getBasePath(bpi)))) { /* relative path to the library is NOT the same as our blendfile path, return an absolute path */
-                               BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded);
-                       }
-                       else {
-                               BLI_bpathIterator_getPath(bpi, filepath_expanded);
-                       }
-               }
-               st= PyUnicode_DecodeFSDefault(filepath_expanded);
-
-               PyList_Append(list, st);
-               Py_DECREF(st);
+       if (absolute) {
+               flag |= BPATH_TRAVERSE_ABS;
        }
 
-       BLI_bpathIterator_free(bpi);
+       list= PyList_New(0);
+
+       bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list);
 
        return list;
 }