diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-03-05 07:44:47 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-03-05 07:44:47 +0400 |
commit | 1a9cde8b998fc79c58caefae83dad8493c213aee (patch) | |
tree | 6fd81a4570f37b764f87ce3c9f8e121b5013a083 /source/blender/blenlib | |
parent | f44b54d2a7866033025bd4e99992a72e3a27c428 (diff) |
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)
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_fileops.h | 5 | ||||
-rw-r--r-- | source/blender/blenlib/intern/storage.c | 101 |
2 files changed, 65 insertions, 41 deletions
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index f0d4bb111a0..d88ef398fd6 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -34,14 +34,12 @@ #define __BLI_FILEOPS_H__ #include <stdio.h> - +#include <sys/stat.h> #ifdef __cplusplus extern "C" { #endif -#include "BLI_fileops_types.h" - /* for size_t (needed on windows) */ #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); unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist); +void BLI_free_filelist(struct direntry * filelist, unsigned int nrentries); /* Files */ diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index bf621ae8004..0b45ff7fb6c 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -91,9 +91,7 @@ #include "BLI_fileops_types.h" #include "BLI_path_util.h" -/* vars: */ -static int totnum, actnum; -static struct direntry *files; /* array[totnum] */ +#include "../imbuf/IMB_imbuf.h" /** * Copies the current working directory into *dir (max size maxncpy), and @@ -209,12 +207,18 @@ double BLI_dir_free_space(const char *dir) #endif } +struct BuildDirCtx { + struct direntry *files; /* array[nrfiles] */ + int nrfiles; +}; + /** * 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 * 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}; int rellen, newnum = 0; @@ -260,48 +264,47 @@ static void bli_builddir(const char *dirname, const char *relname) if (newnum) { - if (files) { - void * const tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry)); + if (dir_ctx->files) { + void * const tmp = realloc(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry)); if (tmp) { - files = (struct direntry *)tmp; + dir_ctx->files = (struct direntry *)tmp; } else { /* realloc fail */ - free(files); - files = NULL; + free(dir_ctx->files); + dir_ctx->files = NULL; } } - if (files == NULL) - files = (struct direntry *)malloc(newnum * sizeof(struct direntry)); + if (dir_ctx->files == NULL) + dir_ctx->files = (struct direntry *)malloc(newnum * sizeof(struct direntry)); - if (files) { + if (dir_ctx->files) { struct dirlink * dlink = (struct dirlink *) dirbase.first; + struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles]; while (dlink) { - memset(&files[actnum], 0, sizeof(struct direntry)); - files[actnum].relname = dlink->name; - files[actnum].path = BLI_strdupcat(dirname, dlink->name); + memset(file, 0, sizeof(struct direntry)); + file->relname = dlink->name; + file->path = BLI_strdupcat(dirname, dlink->name); // use 64 bit file size, only needed for WIN32 and WIN64. // Excluding other than current MSVC compiler until able to test #ifdef WIN32 { wchar_t *name_16 = alloc_utf16_from_8(dlink->name, 0); #if (defined(WIN32) || defined(WIN64)) && (_MSC_VER >= 1500) - _wstat64(name_16, &files[actnum].s); + _wstat64(name_16, &entry->s); #elif defined(__MINGW32__) - _stati64(dlink->name, &files[actnum].s); + _stati64(dlink->name, &entry->s); #endif free(name_16); } #else - stat(dlink->name, &files[actnum].s); + stat(dlink->name, &file->s); #endif - files[actnum].type = files[actnum].s.st_mode; - files[actnum].flags = 0; - /* FIXME: this is the only place where totnum and actnum are incremented, - * so they will always be equal, might as well get rid of one */ - totnum++; - actnum++; + file->type = file->s.st_mode; + file->flags = 0; + dir_ctx->nrfiles++; + file++; dlink = dlink->next; } } @@ -311,7 +314,9 @@ static void bli_builddir(const char *dirname, const char *relname) } 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 { 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 * 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 buf[512]; @@ -346,7 +351,7 @@ static void bli_adddirstrings(void) struct tm *tm; 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 mode = 0; 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) { - /* reset global variables - * memory stored in files is free()'d in - * filesel.c:freefilelist() */ + struct BuildDirCtx dir_ctx; - actnum = totnum = 0; - files = NULL; + dir_ctx.nrfiles = 0; + dir_ctx.files = NULL; - bli_builddir(dirname, ""); - bli_adddirstrings(); + bli_builddir(dirname, "", &dir_ctx); + bli_adddirstrings(&dir_ctx); - if (files) { - *(filelist) = files; + if (dir_ctx.files) { + *filelist = dir_ctx.files; } else { // keep blender happy. Blender stores this in a variable // where 0 has special meaning..... - *(filelist) = files = malloc(sizeof(struct direntry)); + *filelist = malloc(sizeof(struct direntry)); + } + + 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 */ } - return(actnum); + free(filelist); } |