patch [#34103] dir_contents.patch
from Lawrence D'Oliveiro (ldo) - storage.c: Simplify BLI_dir_contents and make it and its internal subsidiary routines reentrant - Moved common code for disposal of a struct direntry to new routine BLI_free_filelist in storage.c, and put calls to it in interface_icons.c and filelist.c - Took out inclusion of BLI_fileops_types.h from BLI_fileops.h and put it explicitly into .c files that need it (which turned out to be only 7 of the 35 files that were including the former)
This commit is contained in:
@@ -48,6 +48,7 @@ struct GPUMaterial;
|
|||||||
struct GPUNode;
|
struct GPUNode;
|
||||||
struct GPUNodeStack;
|
struct GPUNodeStack;
|
||||||
struct ID;
|
struct ID;
|
||||||
|
struct ImBuf;
|
||||||
struct ImageFormatData;
|
struct ImageFormatData;
|
||||||
struct ListBase;
|
struct ListBase;
|
||||||
struct Main;
|
struct Main;
|
||||||
|
@@ -34,14 +34,12 @@
|
|||||||
#define __BLI_FILEOPS_H__
|
#define __BLI_FILEOPS_H__
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "BLI_fileops_types.h"
|
|
||||||
|
|
||||||
/* for size_t (needed on windows) */
|
/* for size_t (needed on windows) */
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -68,6 +66,7 @@ double BLI_dir_free_space(const char *dir);
|
|||||||
char *BLI_current_working_dir(char *dir, const size_t maxlen);
|
char *BLI_current_working_dir(char *dir, const size_t maxlen);
|
||||||
|
|
||||||
unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist);
|
unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist);
|
||||||
|
void BLI_free_filelist(struct direntry * filelist, unsigned int nrentries);
|
||||||
|
|
||||||
/* Files */
|
/* Files */
|
||||||
|
|
||||||
|
@@ -91,9 +91,7 @@
|
|||||||
#include "BLI_fileops_types.h"
|
#include "BLI_fileops_types.h"
|
||||||
#include "BLI_path_util.h"
|
#include "BLI_path_util.h"
|
||||||
|
|
||||||
/* vars: */
|
#include "../imbuf/IMB_imbuf.h"
|
||||||
static int totnum, actnum;
|
|
||||||
static struct direntry *files; /* array[totnum] */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the current working directory into *dir (max size maxncpy), and
|
* Copies the current working directory into *dir (max size maxncpy), and
|
||||||
@@ -209,12 +207,18 @@ double BLI_dir_free_space(const char *dir)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BuildDirCtx {
|
||||||
|
struct direntry *files; /* array[nrfiles] */
|
||||||
|
int nrfiles;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans the directory named *dirname and appends entries for its contents to files.
|
* Scans the directory named *dirname and appends entries for its contents to files.
|
||||||
* Recorded pathnames will be prefixed by *relname if specified (FIXME: actually this
|
* Recorded pathnames will be prefixed by *relname if specified (FIXME: actually this
|
||||||
* option is not used anywhere, might as well get rid of it).
|
* option is not used anywhere, might as well get rid of it).
|
||||||
*/
|
*/
|
||||||
static void bli_builddir(const char *dirname, const char *relname)
|
static void bli_builddir(const char *dirname, const char *relname,
|
||||||
|
struct BuildDirCtx *dir_ctx)
|
||||||
{
|
{
|
||||||
struct ListBase dirbase = {NULL, NULL};
|
struct ListBase dirbase = {NULL, NULL};
|
||||||
int rellen, newnum = 0;
|
int rellen, newnum = 0;
|
||||||
@@ -260,48 +264,47 @@ static void bli_builddir(const char *dirname, const char *relname)
|
|||||||
|
|
||||||
if (newnum) {
|
if (newnum) {
|
||||||
|
|
||||||
if (files) {
|
if (dir_ctx->files) {
|
||||||
void * const tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry));
|
void * const tmp = realloc(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
files = (struct direntry *)tmp;
|
dir_ctx->files = (struct direntry *)tmp;
|
||||||
}
|
}
|
||||||
else { /* realloc fail */
|
else { /* realloc fail */
|
||||||
free(files);
|
free(dir_ctx->files);
|
||||||
files = NULL;
|
dir_ctx->files = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (files == NULL)
|
if (dir_ctx->files == NULL)
|
||||||
files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
|
dir_ctx->files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
|
||||||
|
|
||||||
if (files) {
|
if (dir_ctx->files) {
|
||||||
struct dirlink * dlink = (struct dirlink *) dirbase.first;
|
struct dirlink * dlink = (struct dirlink *) dirbase.first;
|
||||||
|
struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles];
|
||||||
while (dlink) {
|
while (dlink) {
|
||||||
memset(&files[actnum], 0, sizeof(struct direntry));
|
memset(file, 0, sizeof(struct direntry));
|
||||||
files[actnum].relname = dlink->name;
|
file->relname = dlink->name;
|
||||||
files[actnum].path = BLI_strdupcat(dirname, dlink->name);
|
file->path = BLI_strdupcat(dirname, dlink->name);
|
||||||
// use 64 bit file size, only needed for WIN32 and WIN64.
|
// use 64 bit file size, only needed for WIN32 and WIN64.
|
||||||
// Excluding other than current MSVC compiler until able to test
|
// Excluding other than current MSVC compiler until able to test
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
{
|
{
|
||||||
wchar_t *name_16 = alloc_utf16_from_8(dlink->name, 0);
|
wchar_t *name_16 = alloc_utf16_from_8(dlink->name, 0);
|
||||||
#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER >= 1500)
|
#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER >= 1500)
|
||||||
_wstat64(name_16, &files[actnum].s);
|
_wstat64(name_16, &entry->s);
|
||||||
#elif defined(__MINGW32__)
|
#elif defined(__MINGW32__)
|
||||||
_stati64(dlink->name, &files[actnum].s);
|
_stati64(dlink->name, &entry->s);
|
||||||
#endif
|
#endif
|
||||||
free(name_16);
|
free(name_16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
stat(dlink->name, &files[actnum].s);
|
stat(dlink->name, &file->s);
|
||||||
#endif
|
#endif
|
||||||
files[actnum].type = files[actnum].s.st_mode;
|
file->type = file->s.st_mode;
|
||||||
files[actnum].flags = 0;
|
file->flags = 0;
|
||||||
/* FIXME: this is the only place where totnum and actnum are incremented,
|
dir_ctx->nrfiles++;
|
||||||
* so they will always be equal, might as well get rid of one */
|
file++;
|
||||||
totnum++;
|
|
||||||
actnum++;
|
|
||||||
dlink = dlink->next;
|
dlink = dlink->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,7 +314,9 @@ static void bli_builddir(const char *dirname, const char *relname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BLI_freelist(&dirbase);
|
BLI_freelist(&dirbase);
|
||||||
if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
|
if (dir_ctx->files) {
|
||||||
|
qsort(dir_ctx->files, dir_ctx->nrfiles, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("%s empty directory\n", dirname);
|
printf("%s empty directory\n", dirname);
|
||||||
@@ -328,7 +333,7 @@ static void bli_builddir(const char *dirname, const char *relname)
|
|||||||
* Fills in the "mode[123]", "size" and "string" fields in the elements of the files
|
* Fills in the "mode[123]", "size" and "string" fields in the elements of the files
|
||||||
* array with descriptive details about each item. "string" will have a format similar to "ls -l".
|
* array with descriptive details about each item. "string" will have a format similar to "ls -l".
|
||||||
*/
|
*/
|
||||||
static void bli_adddirstrings(void)
|
static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
|
||||||
{
|
{
|
||||||
char datum[100];
|
char datum[100];
|
||||||
char buf[512];
|
char buf[512];
|
||||||
@@ -346,7 +351,7 @@ static void bli_adddirstrings(void)
|
|||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
time_t zero = 0;
|
time_t zero = 0;
|
||||||
|
|
||||||
for (num = 0, file = files; num < actnum; num++, file++) {
|
for (num = 0, file = dir_ctx->files; num < dir_ctx->nrfiles; num++, file++) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
mode = 0;
|
mode = 0;
|
||||||
BLI_strncpy(file->mode1, types[0], sizeof(file->mode1));
|
BLI_strncpy(file->mode1, types[0], sizeof(file->mode1));
|
||||||
@@ -453,26 +458,46 @@ static void bli_adddirstrings(void)
|
|||||||
*/
|
*/
|
||||||
unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
|
unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
|
||||||
{
|
{
|
||||||
/* reset global variables
|
struct BuildDirCtx dir_ctx;
|
||||||
* memory stored in files is free()'d in
|
|
||||||
* filesel.c:freefilelist() */
|
|
||||||
|
|
||||||
actnum = totnum = 0;
|
dir_ctx.nrfiles = 0;
|
||||||
files = NULL;
|
dir_ctx.files = NULL;
|
||||||
|
|
||||||
bli_builddir(dirname, "");
|
bli_builddir(dirname, "", &dir_ctx);
|
||||||
bli_adddirstrings();
|
bli_adddirstrings(&dir_ctx);
|
||||||
|
|
||||||
if (files) {
|
if (dir_ctx.files) {
|
||||||
*(filelist) = files;
|
*filelist = dir_ctx.files;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// keep blender happy. Blender stores this in a variable
|
// keep blender happy. Blender stores this in a variable
|
||||||
// where 0 has special meaning.....
|
// where 0 has special meaning.....
|
||||||
*(filelist) = files = malloc(sizeof(struct direntry));
|
*filelist = malloc(sizeof(struct direntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
return(actnum);
|
return dir_ctx.nrfiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* frees storage for an array of direntries, including the array itself. */
|
||||||
|
void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < nrentries; ++i)
|
||||||
|
{
|
||||||
|
struct direntry * const entry = filelist + i;
|
||||||
|
if (entry->image) {
|
||||||
|
IMB_freeImBuf(entry->image);
|
||||||
|
}
|
||||||
|
if (entry->relname)
|
||||||
|
MEM_freeN(entry->relname);
|
||||||
|
if (entry->path)
|
||||||
|
MEM_freeN(entry->path);
|
||||||
|
if (entry->string)
|
||||||
|
MEM_freeN(entry->string);
|
||||||
|
/* entry->poin assumed not to point to anything needing freeing here */
|
||||||
|
}
|
||||||
|
|
||||||
|
free(filelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
#include "BLI_fileops_types.h"
|
||||||
|
|
||||||
#include "DNA_brush_types.h"
|
#include "DNA_brush_types.h"
|
||||||
#include "DNA_dynamicpaint_types.h"
|
#include "DNA_dynamicpaint_types.h"
|
||||||
@@ -766,18 +767,8 @@ static void init_iconfile_list(struct ListBase *list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free temporary direntry structure that's been created by BLI_dir_contents() */
|
BLI_free_filelist(dir, totfile);
|
||||||
i = totfile - 1;
|
|
||||||
|
|
||||||
for (; i >= 0; i--) {
|
|
||||||
MEM_freeN(dir[i].relname);
|
|
||||||
MEM_freeN(dir[i].path);
|
|
||||||
if (dir[i].string) {
|
|
||||||
MEM_freeN(dir[i].string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(dir);
|
|
||||||
dir = NULL;
|
dir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
#include "BLI_dynstr.h"
|
#include "BLI_dynstr.h"
|
||||||
|
#include "BLI_fileops_types.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# include "BLI_winstuff.h"
|
# include "BLI_winstuff.h"
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
#include "BLI_fileops_types.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_screen.h"
|
#include "BKE_screen.h"
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
#include "BLI_linklist.h"
|
#include "BLI_linklist.h"
|
||||||
#include "BLI_threads.h"
|
#include "BLI_threads.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
#include "BLI_fileops_types.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# include "BLI_winstuff.h"
|
# include "BLI_winstuff.h"
|
||||||
@@ -545,8 +546,6 @@ FileList *filelist_new(short type)
|
|||||||
|
|
||||||
void filelist_free(struct FileList *filelist)
|
void filelist_free(struct FileList *filelist)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!filelist) {
|
if (!filelist) {
|
||||||
printf("Attempting to delete empty filelist.\n");
|
printf("Attempting to delete empty filelist.\n");
|
||||||
return;
|
return;
|
||||||
@@ -557,23 +556,8 @@ void filelist_free(struct FileList *filelist)
|
|||||||
filelist->fidx = NULL;
|
filelist->fidx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < filelist->numfiles; ++i) {
|
BLI_free_filelist(filelist->filelist, filelist->numfiles);
|
||||||
if (filelist->filelist[i].image) {
|
|
||||||
IMB_freeImBuf(filelist->filelist[i].image);
|
|
||||||
}
|
|
||||||
filelist->filelist[i].image = NULL;
|
|
||||||
if (filelist->filelist[i].relname)
|
|
||||||
MEM_freeN(filelist->filelist[i].relname);
|
|
||||||
if (filelist->filelist[i].path)
|
|
||||||
MEM_freeN(filelist->filelist[i].path);
|
|
||||||
filelist->filelist[i].relname = NULL;
|
|
||||||
if (filelist->filelist[i].string)
|
|
||||||
MEM_freeN(filelist->filelist[i].string);
|
|
||||||
filelist->filelist[i].string = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
filelist->numfiles = 0;
|
filelist->numfiles = 0;
|
||||||
free(filelist->filelist);
|
|
||||||
filelist->filelist = NULL;
|
filelist->filelist = NULL;
|
||||||
filelist->filter = 0;
|
filelist->filter = 0;
|
||||||
filelist->filter_glob[0] = '\0';
|
filelist->filter_glob[0] = '\0';
|
||||||
|
@@ -58,6 +58,7 @@
|
|||||||
#include "BLI_linklist.h"
|
#include "BLI_linklist.h"
|
||||||
#include "BLI_dynstr.h"
|
#include "BLI_dynstr.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
#include "BLI_fileops_types.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
|
@@ -45,6 +45,7 @@
|
|||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_rand.h"
|
#include "BLI_rand.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
#include "BLI_fileops_types.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_screen.h"
|
#include "BKE_screen.h"
|
||||||
|
Reference in New Issue
Block a user