diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-03-05 07:17:46 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-03-05 07:17:46 +0400 |
commit | f44b54d2a7866033025bd4e99992a72e3a27c428 (patch) | |
tree | e8c15aac4a82b206adf2d551fcc626592f23cd64 /source/blender/blenlib/intern/storage.c | |
parent | 47c1570e6839e3684bfe4b0c78a3404e5bb72184 (diff) |
patch [#34103]
from Lawrence D'Oliveiro (ldo)
More use of bool type, necessitating adding inclusion of BLI_utildefines.h, or moving it up in the inclusion order if it was already included, in various places
- storage.c: make some variables only used in bli_builddir local to that
- storage.c: BLI_file_descriptor_size should allow 0 as a valid file descriptor
- path_util.c: make pointers to non-reentrant storage returned from folder routines const, necessitating making variables holding these returned pointers const elsewhere as well
- path_util.c: BLI_string_to_utf8 closes iconv context in case of conversion error
- blf_lang.c: fill_locales routine now has its own "languages" local variable to construct paths (was stealing internal storage belonging to BLI_get_folder before)
Diffstat (limited to 'source/blender/blenlib/intern/storage.c')
-rw-r--r-- | source/blender/blenlib/intern/storage.c | 121 |
1 files changed, 91 insertions, 30 deletions
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 1358fdd2a62..bf621ae8004 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -93,12 +93,14 @@ /* vars: */ static int totnum, actnum; -static struct direntry *files; +static struct direntry *files; /* array[totnum] */ -static struct ListBase dirbase_ = {NULL, NULL}; -static struct ListBase *dirbase = &dirbase_; - -/* can return NULL when the size is not big enough */ +/** + * Copies the current working directory into *dir (max size maxncpy), and + * returns a pointer to same. + * + * \note can return NULL when the size is not big enough + */ char *BLI_current_working_dir(char *dir, const size_t maxncpy) { const char *pwd = getenv("PWD"); @@ -110,26 +112,33 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy) return getcwd(dir, maxncpy); } - +/* + * Ordering function for sorting lists of files/directories. Returns -1 if + * entry1 belongs before entry2, 0 if they are equal, 1 if they should be swapped. + */ static int bli_compare(struct direntry *entry1, struct direntry *entry2) { /* type is equal to stat.st_mode */ + /* directories come before non-directories */ if (S_ISDIR(entry1->type)) { if (S_ISDIR(entry2->type) == 0) return (-1); } else { if (S_ISDIR(entry2->type)) return (1); } + /* non-regular files come after regular files */ if (S_ISREG(entry1->type)) { if (S_ISREG(entry2->type) == 0) return (-1); } else { if (S_ISREG(entry2->type)) return (1); } + /* arbitrary, but consistent, ordering of different types of non-regular files */ if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); - + + /* OK, now we know their S_IFMT fields are the same, go on to a name comparison */ /* make sure "." and ".." are always first */ if (strcmp(entry1->relname, ".") == 0) return (-1); if (strcmp(entry2->relname, ".") == 0) return (1); @@ -139,7 +148,10 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2) return (BLI_natstrcmp(entry1->relname, entry2->relname)); } - +/** + * Returns the number of free bytes on the volume containing the specified pathname. */ +/* Not actually used anywhere. + */ double BLI_dir_free_space(const char *dir) { #ifdef WIN32 @@ -197,10 +209,14 @@ double BLI_dir_free_space(const char *dir) #endif } +/** + * 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) { - struct dirent *fname; - struct dirlink *dlink; + struct ListBase dirbase = {NULL, NULL}; int rellen, newnum = 0; char buf[256]; DIR *dir; @@ -212,6 +228,9 @@ static void bli_builddir(const char *dirname, const char *relname) buf[rellen] = '/'; rellen++; } + /* FIXME: any reason why we can't opendir dirname directly, instead of making it + * the current directory first? That would simplify calls to this routine (currently + * having to save/restore the current directory) a lot. */ #ifndef WIN32 if (chdir(dirname) == -1) { perror(dirname); @@ -227,13 +246,14 @@ static void bli_builddir(const char *dirname, const char *relname) UTF16_UN_ENCODE(dirname); #endif - if ((dir = (DIR *)opendir("."))) { - while ((fname = (struct dirent *) readdir(dir)) != NULL) { - dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); - if (dlink) { + if ((dir = opendir(".")) != NULL) { + const struct dirent *fname; + while ((fname = readdir(dir)) != NULL) { + struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); + if (dlink != NULL) { BLI_strncpy(buf + rellen, fname->d_name, sizeof(buf) - rellen); dlink->name = BLI_strdup(buf); - BLI_addhead(dirbase, dlink); + BLI_addhead(&dirbase, dlink); newnum++; } } @@ -241,7 +261,7 @@ static void bli_builddir(const char *dirname, const char *relname) if (newnum) { if (files) { - void *tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry)); + void * const tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry)); if (tmp) { files = (struct direntry *)tmp; } @@ -255,7 +275,7 @@ static void bli_builddir(const char *dirname, const char *relname) files = (struct direntry *)malloc(newnum * sizeof(struct direntry)); if (files) { - dlink = (struct dirlink *) dirbase->first; + struct dirlink * dlink = (struct dirlink *) dirbase.first; while (dlink) { memset(&files[actnum], 0, sizeof(struct direntry)); files[actnum].relname = dlink->name; @@ -278,6 +298,8 @@ static void bli_builddir(const char *dirname, const char *relname) #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++; dlink = dlink->next; @@ -288,7 +310,7 @@ static void bli_builddir(const char *dirname, const char *relname) exit(1); } - BLI_freelist(dirbase); + BLI_freelist(&dirbase); if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare); } else { @@ -302,12 +324,17 @@ 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) { char datum[100]; char buf[512]; char size[250]; static const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"}; + /* symbolic display, indexed by mode field value */ int num, mode; #ifdef WIN32 __int64 st_size; @@ -375,6 +402,9 @@ static void bli_adddirstrings(void) */ st_size = file->s.st_size; + /* FIXME: Either change decimal prefixes to binary ones + * <http://en.wikipedia.org/wiki/Binary_prefix>, or change + * divisor factors from 1024 to 1000. */ if (st_size > 1024 * 1024 * 1024) { BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size) / (1024 * 1024 * 1024)); } @@ -413,9 +443,14 @@ static void bli_adddirstrings(void) file->date, file->time, size, file->relname); file->string = BLI_strdup(buf); + /* FIXME: not actually used anywhere, why bother to set it up? */ } } +/** + * Scans the contents of the directory named *dirname, and allocates and fills in an + * array of entries describing them in *filelist. The length of the array is the function result. + */ unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist) { /* reset global variables @@ -441,17 +476,24 @@ unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist) } +/** + * Returns the file size of an opened file descriptor. + */ size_t BLI_file_descriptor_size(int file) { struct stat buf; - if (file <= 0) return (-1); + if (file < 0) return (-1); fstat(file, &buf); /* CHANGE */ return (buf.st_size); } +/** + * Returns the size of a file. + */ size_t BLI_file_size(const char *path) { + /* FIXME: opening and closing the file is inefficient. Why not use stat(2) instead? */ int size, file = BLI_open(path, O_BINARY | O_RDONLY, 0); if (file == -1) @@ -462,7 +504,10 @@ size_t BLI_file_size(const char *path) return size; } - +/** + * Returns the st_mode from statting the specified path name, or 0 if it couldn't be statted + * (most likely doesn't exist or no access). + */ int BLI_exists(const char *name) { #if defined(WIN32) @@ -509,18 +554,27 @@ int BLI_stat(const char *path, struct stat *buffer) } #endif -/* would be better in fileops.c except that it needs stat.h so add here */ -int BLI_is_dir(const char *file) +/** + * Does the specified path point to a directory? + * \note Would be better in fileops.c except that it needs stat.h so add here + */ +bool BLI_is_dir(const char *file) { return S_ISDIR(BLI_exists(file)); } -int BLI_is_file(const char *path) +/** + * Does the specified path point to a non-directory? + */ +bool BLI_is_file(const char *path) { - int mode = BLI_exists(path); + const int mode = BLI_exists(path); return (mode && !S_ISDIR(mode)); } +/** + * Reads the contents of a text file and returns the lines in a linked list. + */ LinkNode *BLI_file_read_as_lines(const char *name) { FILE *fp = BLI_fopen(name, "r"); @@ -549,6 +603,9 @@ LinkNode *BLI_file_read_as_lines(const char *name) char *line = BLI_strdupn(&buf[last], i - last); BLI_linklist_prepend(&lines, line); + /* faster to build singly-linked list in reverse order */ + /* alternatively, could process buffer in reverse order so + * list ends up right way round to start with */ last = i + 1; } } @@ -557,18 +614,22 @@ LinkNode *BLI_file_read_as_lines(const char *name) } fclose(fp); - + + /* get them the right way round */ BLI_linklist_reverse(&lines); return lines; } +/* + * Frees memory from a previous call to BLI_file_read_as_lines. + */ void BLI_file_free_lines(LinkNode *lines) { BLI_linklist_free(lines, (void (*)(void *))MEM_freeN); } /** is file1 older then file2 */ -int BLI_file_older(const char *file1, const char *file2) +bool BLI_file_older(const char *file1, const char *file2) { #ifdef WIN32 struct _stat st1, st2; @@ -576,16 +637,16 @@ int BLI_file_older(const char *file1, const char *file2) UTF16_ENCODE(file1); UTF16_ENCODE(file2); - if (_wstat(file1_16, &st1)) return 0; - if (_wstat(file2_16, &st2)) return 0; + if (_wstat(file1_16, &st1)) return false; + if (_wstat(file2_16, &st2)) return false; UTF16_UN_ENCODE(file2); UTF16_UN_ENCODE(file1); #else struct stat st1, st2; - if (stat(file1, &st1)) return 0; - if (stat(file2, &st2)) return 0; + if (stat(file1, &st1)) return false; + if (stat(file2, &st2)) return false; #endif return (st1.st_mtime < st2.st_mtime); } |