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)
This commit is contained in:
Campbell Barton 2013-03-05 03:17:46 +00:00
parent 47c1570e68
commit f44b54d2a7
25 changed files with 388 additions and 157 deletions

@ -41,6 +41,7 @@
#include "DNA_vec_types.h" #include "DNA_vec_types.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_path_util.h" #include "BLI_path_util.h"

@ -78,15 +78,16 @@ static void free_locales(void)
static void fill_locales(void) static void fill_locales(void)
{ {
char *languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale"); const char * const languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale");
char languages[FILE_MAX];
LinkNode *lines = NULL, *line; LinkNode *lines = NULL, *line;
char *str; char *str;
int idx = 0; int idx = 0;
free_locales(); free_locales();
BLI_join_dirfile(languages_path, FILE_MAX, languages_path, "languages"); BLI_join_dirfile(languages, FILE_MAX, languages_path, "languages");
line = lines = BLI_file_read_as_lines(languages_path); line = lines = BLI_file_read_as_lines(languages);
/* This whole "parsing" code is a bit weak, in that it expects strictly formated input file... /* This whole "parsing" code is a bit weak, in that it expects strictly formated input file...
* Should not be a problem, though, as this file is script-generated! */ * Should not be a problem, though, as this file is script-generated! */
@ -185,7 +186,7 @@ EnumPropertyItem *BLF_RNA_lang_enum_properties(void)
void BLF_lang_init(void) void BLF_lang_init(void)
{ {
#ifdef WITH_INTERNATIONAL #ifdef WITH_INTERNATIONAL
char *messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale"); const char * const messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
if (messagepath) { if (messagepath) {
bl_locale_init(messagepath, TEXT_DOMAIN_NAME); bl_locale_init(messagepath, TEXT_DOMAIN_NAME);

@ -56,7 +56,7 @@ unsigned char *BLF_get_unifont(int *unifont_size_r)
{ {
#ifdef WITH_INTERNATIONAL #ifdef WITH_INTERNATIONAL
if (unifont_ttf == NULL) { if (unifont_ttf == NULL) {
char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); const char * const fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
if (fontpath) { if (fontpath) {
char unifont_path[1024]; char unifont_path[1024];

@ -29,9 +29,9 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_endian_switch.h" #include "BLI_endian_switch.h"
#include "BKE_customdata_file.h" #include "BKE_customdata_file.h"

@ -1773,6 +1773,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
(void) frame_height; (void) frame_height;
(void) search_ibuf; (void) search_ibuf;
(void) marker; (void) marker;
(void) from_anchor;
(void) track; (void) track;
(void) use_mask; (void) use_mask;

@ -61,8 +61,8 @@ int BLI_stat(const char *path, struct stat *buffer);
struct direntry; struct direntry;
int BLI_is_dir(const char *path); bool BLI_is_dir(const char *path);
int BLI_is_file(const char *path); bool BLI_is_file(const char *path);
void BLI_dir_create_recursive(const char *dir); void BLI_dir_create_recursive(const char *dir);
double BLI_dir_free_space(const char *dir); 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);
@ -85,7 +85,7 @@ size_t BLI_file_descriptor_size(int file);
size_t BLI_file_size(const char *file); size_t BLI_file_size(const char *file);
/* compare if one was last modified before the other */ /* compare if one was last modified before the other */
int BLI_file_older(const char *file1, const char *file2); bool BLI_file_older(const char *file1, const char *file2);
/* read ascii file as lines, empty list if reading fails */ /* read ascii file as lines, empty list if reading fails */
struct LinkNode *BLI_file_read_as_lines(const char *file); struct LinkNode *BLI_file_read_as_lines(const char *file);

@ -40,10 +40,10 @@ struct direntry;
const char *BLI_getDefaultDocumentFolder(void); const char *BLI_getDefaultDocumentFolder(void);
char *BLI_get_folder(int folder_id, const char *subfolder); const char *BLI_get_folder(int folder_id, const char *subfolder);
char *BLI_get_folder_create(int folder_id, const char *subfolder); const char *BLI_get_folder_create(int folder_id, const char *subfolder);
char *BLI_get_user_folder_notest(int folder_id, const char *subfolder); const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder);
char *BLI_get_folder_version(const int id, const int ver, const bool do_check); const char *BLI_get_folder_version(const int id, const int ver, const bool do_check);
/* folder_id */ /* folder_id */
@ -109,8 +109,8 @@ void BLI_getlastdir(const char *dir, char *last, size_t maxlen);
bool BLI_testextensie(const char *str, const char *ext); bool BLI_testextensie(const char *str, const char *ext);
bool BLI_testextensie_array(const char *str, const char **ext_array); bool BLI_testextensie_array(const char *str, const char **ext_array);
bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch); bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch);
int BLI_replace_extension(char *path, size_t maxlen, const char *ext); bool BLI_replace_extension(char *path, size_t maxlen, const char *ext);
int BLI_ensure_extension(char *path, size_t maxlen, const char *ext); bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext);
void BLI_uniquename(struct ListBase *list, void *vlink, const char * defname, char delim, short name_offs, short len); void BLI_uniquename(struct ListBase *list, void *vlink, const char * defname, char delim, short name_offs, short len);
bool BLI_uniquename_cb(bool (*unique_check)(void * arg, const char * name), bool BLI_uniquename_cb(bool (*unique_check)(void * arg, const char * name),
void *arg, const char * defname, char delim, char *name, short name_len); void *arg, const char * defname, char delim, char *name, short name_len);
@ -155,13 +155,14 @@ bool BLI_has_parent(char *path);
* \retval Returns true if the path was relative (started with "//"). * \retval Returns true if the path was relative (started with "//").
*/ */
bool BLI_path_abs(char *path, const char *basepath); bool BLI_path_abs(char *path, const char *basepath);
int BLI_path_frame(char *path, int frame, int digits); bool BLI_path_frame(char *path, int frame, int digits);
int BLI_path_frame_range(char *path, int sta, int end, int digits); bool BLI_path_frame_range(char *path, int sta, int end, int digits);
int BLI_path_cwd(char *path); bool BLI_path_cwd(char *path);
void BLI_path_rel(char *file, const char *relfile); void BLI_path_rel(char *file, const char *relfile);
bool BLI_path_is_rel(const char *path); bool BLI_path_is_rel(const char *path);
/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */
#ifdef WIN32 #ifdef WIN32
# define BLI_path_cmp BLI_strcasecmp # define BLI_path_cmp BLI_strcasecmp
# define BLI_path_ncmp BLI_strncasecmp # define BLI_path_ncmp BLI_strncasecmp

@ -167,7 +167,7 @@ typedef bool _BLI_Bool;
(b) = (tval); \ (b) = (tval); \
} (void)0 } (void)0
/* ELEM#(a, ...): is the first arg equal any of the others */
#define ELEM(a, b, c) ((a) == (b) || (a) == (c)) #define ELEM(a, b, c) ((a) == (b) || (a) == (c))
#define ELEM3(a, b, c, d) (ELEM(a, b, c) || (a) == (d) ) #define ELEM3(a, b, c, d) (ELEM(a, b, c) || (a) == (d) )
#define ELEM4(a, b, c, d, e) (ELEM(a, b, c) || ELEM(a, d, e) ) #define ELEM4(a, b, c, d, e) (ELEM(a, b, c) || ELEM(a, d, e) )

@ -79,8 +79,8 @@
/* local */ /* local */
#define UNIQUE_NAME_MAX 128 #define UNIQUE_NAME_MAX 128
static char bprogname[FILE_MAX]; /* path to program executable */ static char bprogname[FILE_MAX]; /* full path to program executable */
static char bprogdir[FILE_MAX]; /* path in which executable is located */ static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */
static char btempdir[FILE_MAX]; /* temporary directory */ static char btempdir[FILE_MAX]; /* temporary directory */
static int add_win32_extension(char *name); static int add_win32_extension(char *name);
@ -229,7 +229,7 @@ void BLI_newname(char *name, int add)
* Ensures name is unique (according to criteria specified by caller in unique_check callback), * Ensures name is unique (according to criteria specified by caller in unique_check callback),
* incrementing its numeric suffix as necessary. Returns true if name had to be adjusted. * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted.
* *
* \param unique_check Return true iff name is not unique * \param unique_check Return true if name is not unique
* \param arg Additional arg to unique_check--meaning is up to caller * \param arg Additional arg to unique_check--meaning is up to caller
* \param defname To initialize name if latter is empty * \param defname To initialize name if latter is empty
* \param delim Delimits numeric suffix in name * \param delim Delimits numeric suffix in name
@ -470,6 +470,10 @@ bool BLI_path_is_rel(const char *path)
return path[0] == '/' && path[1] == '/'; return path[0] == '/' && path[1] == '/';
} }
/**
* Replaces *file with a relative version (prefixed by "//") such that BLI_path_abs, given
* the same *relfile, will convert it back to its original value.
*/
void BLI_path_rel(char *file, const char *relfile) void BLI_path_rel(char *file, const char *relfile)
{ {
const char *lslash; const char *lslash;
@ -575,8 +579,8 @@ void BLI_path_rel(char *file, const char *relfile)
} }
/** /**
* Cleans path and makes sure it ends with a slash, and returns true iff * Cleans path and makes sure it ends with a slash.
* it has more than one other path separator in it. * \return true if \a path has more than one other path separator in it.
*/ */
bool BLI_has_parent(char *path) bool BLI_has_parent(char *path)
{ {
@ -594,7 +598,7 @@ bool BLI_has_parent(char *path)
} }
/** /**
* Replaces path with the path of its parent directory, returning true iff * Replaces path with the path of its parent directory, returning true if
* it was able to find a parent directory within the pathname. * it was able to find a parent directory within the pathname.
*/ */
bool BLI_parent_dir(char *path) bool BLI_parent_dir(char *path)
@ -618,7 +622,7 @@ bool BLI_parent_dir(char *path)
/** /**
* Looks for a sequence of "#" characters in the last slash-separated component of *path, * Looks for a sequence of "#" characters in the last slash-separated component of *path,
* returning the indexes of the first and one past the last character in the sequence in * returning the indexes of the first and one past the last character in the sequence in
* *char_start and *char_end respectively. Returns true iff such a sequence was found. * *char_start and *char_end respectively. Returns true if such a sequence was found.
*/ */
static bool stringframe_chars(const char *path, int *char_start, int *char_end) static bool stringframe_chars(const char *path, int *char_start, int *char_end)
{ {
@ -674,7 +678,11 @@ static void ensure_digits(char *path, int digits)
} }
} }
int BLI_path_frame(char *path, int frame, int digits) /**
* Replaces "#" character sequence in last slash-separated component of *path
* with frame as decimal integer, with leading zeroes as necessary, to make digits digits.
*/
bool BLI_path_frame(char *path, int frame, int digits)
{ {
int ch_sta, ch_end; int ch_sta, ch_end;
@ -685,12 +693,17 @@ int BLI_path_frame(char *path, int frame, int digits)
char tmp[FILE_MAX]; char tmp[FILE_MAX];
sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end); sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
strcpy(path, tmp); strcpy(path, tmp);
return 1; return true;
} }
return 0; return false;
} }
int BLI_path_frame_range(char *path, int sta, int end, int digits) /**
* Replaces "#" character sequence in last slash-separated component of *path
* with sta and end as decimal integers, with leading zeroes as necessary, to make digits
* digits each, with a hyphen in-between.
*/
bool BLI_path_frame_range(char *path, int sta, int end, int digits)
{ {
int ch_sta, ch_end; int ch_sta, ch_end;
@ -703,15 +716,15 @@ int BLI_path_frame_range(char *path, int sta, int end, int digits)
"%.*s%.*d-%.*d%s", "%.*s%.*d-%.*d%s",
ch_sta, path, ch_end - ch_sta, sta, ch_end - ch_sta, end, path + ch_end); ch_sta, path, ch_end - ch_sta, sta, ch_end - ch_sta, end, path + ch_end);
BLI_strncpy(path, tmp, FILE_MAX); BLI_strncpy(path, tmp, FILE_MAX);
return 1; return true;
} }
return 0; return false;
} }
/** /**
* If path begins with "//", strips that and replaces it with basepath directory. Also converts * If path begins with "//", strips that and replaces it with basepath directory. Also converts
* a drive-letter prefix to something more sensible if this is a non-drive-letter-based system. * a drive-letter prefix to something more sensible if this is a non-drive-letter-based system.
* Returns true iff "//" prefix expansion was done. * Returns true if "//" prefix expansion was done.
*/ */
bool BLI_path_abs(char *path, const char *basepath) bool BLI_path_abs(char *path, const char *basepath)
{ {
@ -809,24 +822,27 @@ bool BLI_path_abs(char *path, const char *basepath)
} }
/* /**
* Should only be done with command line paths. * Expands path relative to the current working directory, if it was relative.
* this is NOT something blenders internal paths support like the // prefix * Returns true if such expansion was done.
*
* \note Should only be done with command line paths.
* this is _not_ something blenders internal paths support like the "//" prefix
*/ */
int BLI_path_cwd(char *path) bool BLI_path_cwd(char *path)
{ {
int wasrelative = 1; bool wasrelative = true;
int filelen = strlen(path); const int filelen = strlen(path);
#ifdef WIN32 #ifdef WIN32
if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/'))
wasrelative = 0; wasrelative = false;
#else #else
if (filelen >= 2 && path[0] == '/') if (filelen >= 2 && path[0] == '/')
wasrelative = 0; wasrelative = false;
#endif #endif
if (wasrelative == 1) { if (wasrelative) {
char cwd[FILE_MAX] = ""; char cwd[FILE_MAX] = "";
BLI_current_working_dir(cwd, sizeof(cwd)); /* in case the full path to the blend isn't used */ BLI_current_working_dir(cwd, sizeof(cwd)); /* in case the full path to the blend isn't used */
@ -853,6 +869,7 @@ int BLI_path_cwd(char *path)
/* 'di's filename component is moved into 'fi', di is made a dir path */ /* 'di's filename component is moved into 'fi', di is made a dir path */
/* FIXME: duplicates functionality of BLI_split_dirfile. */
void BLI_splitdirstring(char *di, char *fi) void BLI_splitdirstring(char *di, char *fi)
{ {
char *lslash = (char *)BLI_last_slash(di); char *lslash = (char *)BLI_last_slash(di);
@ -867,6 +884,9 @@ void BLI_splitdirstring(char *di, char *fi)
} }
} }
/**
* Copies into *last the part of *dir following the second-last slash.
*/
void BLI_getlastdir(const char *dir, char *last, const size_t maxlen) void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
{ {
const char *s = dir; const char *s = dir;
@ -893,7 +913,7 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
const char *BLI_getDefaultDocumentFolder(void) const char *BLI_getDefaultDocumentFolder(void)
{ {
#ifndef WIN32 #ifndef WIN32
const char *xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR"); const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
if (xdg_documents_dir) if (xdg_documents_dir)
return xdg_documents_dir; return xdg_documents_dir;
@ -929,6 +949,7 @@ const char *BLI_getDefaultDocumentFolder(void)
// #define PATH_DEBUG // #define PATH_DEBUG
/* returns a formatted representation of the specified version number. Non-reentrant! */
static char *blender_version_decimal(const int ver) static char *blender_version_decimal(const int ver)
{ {
static char version_str[5]; static char version_str[5];
@ -936,7 +957,11 @@ static char *blender_version_decimal(const int ver)
return version_str; return version_str;
} }
static int test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name) /**
* Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
* returning true if result points to a directory.
*/
static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
{ {
char tmppath[FILE_MAX]; char tmppath[FILE_MAX];
@ -948,44 +973,60 @@ static int test_path(char *targetpath, const char *path_base, const char *path_s
BLI_make_file_string("/", targetpath, tmppath, folder_name); BLI_make_file_string("/", targetpath, tmppath, folder_name);
else else
BLI_strncpy(targetpath, tmppath, sizeof(tmppath)); BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
/* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
* if folder_name is specified but not otherwise? */
if (BLI_is_dir(targetpath)) { if (BLI_is_dir(targetpath)) {
#ifdef PATH_DEBUG #ifdef PATH_DEBUG
printf("\t%s found: %s\n", __func__, targetpath); printf("\t%s found: %s\n", __func__, targetpath);
#endif #endif
return 1; return true;
} }
else { else {
#ifdef PATH_DEBUG #ifdef PATH_DEBUG
printf("\t%s missing: %s\n", __func__, targetpath); printf("\t%s missing: %s\n", __func__, targetpath);
#endif #endif
//targetpath[0] = '\0'; //targetpath[0] = '\0';
return 0; return false;
} }
} }
static int test_env_path(char *path, const char *envvar) /**
* Puts the value of the specified environment variable into *path if it exists
* and points at a directory. Returns true if this was done.
*/
static bool test_env_path(char *path, const char *envvar)
{ {
const char *env = envvar ? getenv(envvar) : NULL; const char *env = envvar ? getenv(envvar) : NULL;
if (!env) return 0; if (!env) return false;
if (BLI_is_dir(env)) { if (BLI_is_dir(env)) {
BLI_strncpy(path, env, FILE_MAX); BLI_strncpy(path, env, FILE_MAX);
#ifdef PATH_DEBUG #ifdef PATH_DEBUG
printf("\t%s env %s found: %s\n", __func__, envvar, env); printf("\t%s env %s found: %s\n", __func__, envvar, env);
#endif #endif
return 1; return true;
} }
else { else {
path[0] = '\0'; path[0] = '\0';
#ifdef PATH_DEBUG #ifdef PATH_DEBUG
printf("\t%s env %s missing: %s\n", __func__, envvar, env); printf("\t%s env %s missing: %s\n", __func__, envvar, env);
#endif #endif
return 0; return false;
} }
} }
static int get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver) /**
* Constructs in \a targetpath the name of a directory relative to a version-specific
* subdirectory in the parent directory of the Blender executable.
*
* \param targetpath String to return path
* \param folder_name Optional folder name within version-specific directory
* \param subfolder_name Optional subfolder name within folder_name
* \param ver To construct name of version-specific directory within bprogdir
* \return true if such a directory exists.
*/
static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
{ {
char relfolder[FILE_MAX]; char relfolder[FILE_MAX];
@ -1006,22 +1047,34 @@ static int get_path_local(char *targetpath, const char *folder_name, const char
} }
/* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
if (test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder)) return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder);
return 1;
return 0;
} }
static int is_portable_install(void) /**
* Is this an install with user files kept together with the Blender executable and its
* installation files.
*/
static bool is_portable_install(void)
{ {
/* detect portable install by the existance of config folder */ /* detect portable install by the existence of config folder */
const int ver = BLENDER_VERSION; const int ver = BLENDER_VERSION;
char path[FILE_MAX]; char path[FILE_MAX];
return get_path_local(path, "config", NULL, ver); return get_path_local(path, "config", NULL, ver);
} }
static int get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) /**
* Returns the path of a folder within the user-files area.
*
*
* \param targetpath String to return path
* \param folder_name default name of folder within user area
* \param subfolder_name optional name of subfolder within folder
* \param envvar name of environment variable which, if defined, overrides folder_name
* \param ver Blender version, used to construct a subdirectory name
* \return true if it was able to construct such a path.
*/
static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
{ {
char user_path[FILE_MAX]; char user_path[FILE_MAX];
const char *user_base_path; const char *user_base_path;
@ -1038,7 +1091,7 @@ static int get_path_user(char *targetpath, const char *folder_name, const char *
} }
else { else {
BLI_strncpy(targetpath, user_path, FILE_MAX); BLI_strncpy(targetpath, user_path, FILE_MAX);
return 1; return true;
} }
} }
@ -1047,30 +1100,34 @@ static int get_path_user(char *targetpath, const char *folder_name, const char *
BLI_strncpy(user_path, user_base_path, FILE_MAX); BLI_strncpy(user_path, user_base_path, FILE_MAX);
if (!user_path[0]) if (!user_path[0])
return 0; return false;
#ifdef PATH_DEBUG #ifdef PATH_DEBUG
printf("%s: %s\n", __func__, user_path); printf("%s: %s\n", __func__, user_path);
#endif #endif
if (subfolder_name) { if (subfolder_name) {
/* try $HOME/folder_name/subfolder_name */
return test_path(targetpath, user_path, folder_name, subfolder_name); return test_path(targetpath, user_path, folder_name, subfolder_name);
} }
else { else {
/* try $HOME/folder_name */
return test_path(targetpath, user_path, NULL, folder_name); return test_path(targetpath, user_path, NULL, folder_name);
} }
} }
static int get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) /**
* Returns the path of a folder within the Blender installation directory.
*
* \param targetpath String to return path
* \param folder_name default name of folder within installation area
* \param subfolder_name optional name of subfolder within folder
* \param envvar name of environment variable which, if defined, overrides folder_name
* \param ver Blender version, used to construct a subdirectory name
* \return true if it was able to construct such a path.
*/
static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
{ {
char system_path[FILE_MAX]; char system_path[FILE_MAX];
const char *system_base_path; const char *system_base_path;
/* first allow developer only overrides to the system path
* these are only used when running blender from source */
char cwd[FILE_MAX]; char cwd[FILE_MAX];
char relfolder[FILE_MAX]; char relfolder[FILE_MAX];
@ -1086,16 +1143,20 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
relfolder[0] = '\0'; relfolder[0] = '\0';
} }
/* first allow developer only overrides to the system path
* these are only used when running blender from source */
/* try CWD/release/folder_name */ /* try CWD/release/folder_name */
if (BLI_current_working_dir(cwd, sizeof(cwd))) { if (BLI_current_working_dir(cwd, sizeof(cwd))) {
if (test_path(targetpath, cwd, "release", relfolder)) { if (test_path(targetpath, cwd, "release", relfolder)) {
return 1; return true;
} }
} }
/* try EXECUTABLE_DIR/release/folder_name */ /* try EXECUTABLE_DIR/release/folder_name */
if (test_path(targetpath, bprogdir, "release", relfolder)) if (test_path(targetpath, bprogdir, "release", relfolder))
return 1; return true;
/* end developer overrides */ /* end developer overrides */
@ -1108,7 +1169,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
} }
else { else {
BLI_strncpy(targetpath, system_path, FILE_MAX); BLI_strncpy(targetpath, system_path, FILE_MAX);
return 1; return true;
} }
} }
@ -1117,7 +1178,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
BLI_strncpy(system_path, system_base_path, FILE_MAX); BLI_strncpy(system_path, system_base_path, FILE_MAX);
if (!system_path[0]) if (!system_path[0])
return 0; return false;
#ifdef PATH_DEBUG #ifdef PATH_DEBUG
printf("%s: %s\n", __func__, system_path); printf("%s: %s\n", __func__, system_path);
@ -1135,7 +1196,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
/* get a folder out of the 'folder_id' presets for paths */ /* get a folder out of the 'folder_id' presets for paths */
/* returns the path if found, NULL string if not */ /* returns the path if found, NULL string if not */
char *BLI_get_folder(int folder_id, const char *subfolder) const char *BLI_get_folder(int folder_id, const char *subfolder)
{ {
const int ver = BLENDER_VERSION; const int ver = BLENDER_VERSION;
static char path[FILE_MAX] = ""; static char path[FILE_MAX] = "";
@ -1182,7 +1243,10 @@ char *BLI_get_folder(int folder_id, const char *subfolder)
return path; return path;
} }
char *BLI_get_user_folder_notest(int folder_id, const char *subfolder) /**
* Returns the path to a folder in the user area without checking that it actually exists first.
*/
const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
{ {
const int ver = BLENDER_VERSION; const int ver = BLENDER_VERSION;
static char path[FILE_MAX] = ""; static char path[FILE_MAX] = "";
@ -1207,9 +1271,12 @@ char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
return path; return path;
} }
char *BLI_get_folder_create(int folder_id, const char *subfolder) /**
* Returns the path to a folder in the user area, creating it if it doesn't exist.
*/
const char *BLI_get_folder_create(int folder_id, const char *subfolder)
{ {
char *path; const char *path;
/* only for user folders */ /* only for user folders */
if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
@ -1225,10 +1292,14 @@ char *BLI_get_folder_create(int folder_id, const char *subfolder)
return path; return path;
} }
char *BLI_get_folder_version(const int id, const int ver, const bool do_check) /**
* Returns the path of the top-level version-specific local, user or system directory.
* If do_check, then the result will be NULL if the directory doesn't exist.
*/
const char *BLI_get_folder_version(const int id, const int ver, const bool do_check)
{ {
static char path[FILE_MAX] = ""; static char path[FILE_MAX] = "";
int ok; bool ok;
switch (id) { switch (id) {
case BLENDER_RESOURCE_PATH_USER: case BLENDER_RESOURCE_PATH_USER:
ok = get_path_user(path, NULL, NULL, NULL, ver); ok = get_path_user(path, NULL, NULL, NULL, ver);
@ -1241,11 +1312,11 @@ char *BLI_get_folder_version(const int id, const int ver, const bool do_check)
break; break;
default: default:
path[0] = '\0'; /* in case do_check is false */ path[0] = '\0'; /* in case do_check is false */
ok = FALSE; ok = false;
BLI_assert(!"incorrect ID"); BLI_assert(!"incorrect ID");
} }
if ((ok == FALSE) && do_check) { if (!ok && do_check) {
return NULL; return NULL;
} }
@ -1262,6 +1333,9 @@ char *BLI_get_folder_version(const int id, const int ver, const bool do_check)
# undef PATH_DEBUG # undef PATH_DEBUG
#endif #endif
/**
* Sets the specified environment variable to the specified value.
*/
void BLI_setenv(const char *env, const char *val) void BLI_setenv(const char *env, const char *val)
{ {
/* free windows */ /* free windows */
@ -1287,6 +1361,8 @@ void BLI_setenv(const char *env, const char *val)
/** /**
* Only set an env var if already not there. * Only set an env var if already not there.
* Like Unix setenv(env, val, 0); * Like Unix setenv(env, val, 0);
*
* (not used anywhere).
*/ */
void BLI_setenv_if_new(const char *env, const char *val) void BLI_setenv_if_new(const char *env, const char *val)
{ {
@ -1295,6 +1371,9 @@ void BLI_setenv_if_new(const char *env, const char *val)
} }
/**
* Changes to the path separators to the native ones for this OS.
*/
void BLI_clean(char *path) void BLI_clean(char *path)
{ {
#ifdef WIN32 #ifdef WIN32
@ -1306,6 +1385,9 @@ void BLI_clean(char *path)
#endif #endif
} }
/**
* Replaces occurrences of from with to in *string.
*/
void BLI_char_switch(char *string, char from, char to) void BLI_char_switch(char *string, char from, char to)
{ {
while (*string != 0) { while (*string != 0) {
@ -1314,6 +1396,10 @@ void BLI_char_switch(char *string, char from, char to)
} }
} }
/**
* Strips off nonexistent subdirectories from the end of *dir, leaving the path of
* the lowest-level directory that does exist.
*/
void BLI_make_exist(char *dir) void BLI_make_exist(char *dir)
{ {
int a; int a;
@ -1322,7 +1408,7 @@ void BLI_make_exist(char *dir)
a = strlen(dir); a = strlen(dir);
while (BLI_is_dir(dir) == 0) { while (!BLI_is_dir(dir)) {
a--; a--;
while (dir[a] != SEP) { while (dir[a] != SEP) {
a--; a--;
@ -1342,11 +1428,14 @@ void BLI_make_exist(char *dir)
} }
} }
/**
* Ensures that the parent directory of *name exists.
*/
void BLI_make_existing_file(const char *name) void BLI_make_existing_file(const char *name)
{ {
char di[FILE_MAX], fi[FILE_MAXFILE]; char di[FILE_MAX], fi[FILE_MAXFILE];
BLI_strncpy(di, name, sizeof(di)); BLI_strncpy(di, name, sizeof(di));
/* FIXME: use BLI_split_dir_part instead and get rid of fi. */
BLI_splitdirstring(di, fi); BLI_splitdirstring(di, fi);
/* test exist */ /* test exist */
@ -1355,7 +1444,15 @@ void BLI_make_existing_file(const char *name)
} }
} }
/**
* Returns in *string the concatenation of *dir and *file (also with *relabase on the
* front if specified and *dir begins with "//"). Normalizes all occurrences of path
* separators, including ensuring there is exactly one between the copies of *dir and *file,
* and between the copies of *relabase and *dir.
*
* \param relabase Optional prefix to substitute for "//" on front of *dir
* \param string Area to return result
*/
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file) void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
{ {
int sl; int sl;
@ -1460,8 +1557,11 @@ bool BLI_testextensie_array(const char *str, const char **ext_array)
return false; return false;
} }
/* semicolon separated wildcards, eg: /**
* '*.zip;*.py;*.exe' */ * Semicolon separated wildcards, eg:
* '*.zip;*.py;*.exe'
* does str match any of the semicolon-separated glob patterns in fnmatch.
*/
bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch) bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
{ {
const char *ext_step = ext_fnmatch; const char *ext_step = ext_fnmatch;
@ -1490,10 +1590,14 @@ bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
} }
int BLI_replace_extension(char *path, size_t maxlen, const char *ext) /**
* Removes any existing extension on the end of \a path and appends \a ext.
* \return false if there was no room.
*/
bool BLI_replace_extension(char *path, size_t maxlen, const char *ext)
{ {
size_t path_len = strlen(path); const size_t path_len = strlen(path);
size_t ext_len = strlen(ext); const size_t ext_len = strlen(ext);
ssize_t a; ssize_t a;
for (a = path_len - 1; a >= 0; a--) { for (a = path_len - 1; a >= 0; a--) {
@ -1507,24 +1611,26 @@ int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
} }
if (a + ext_len >= maxlen) if (a + ext_len >= maxlen)
return 0; return false;
memcpy(path + a, ext, ext_len + 1); memcpy(path + a, ext, ext_len + 1);
return 1; return true;
} }
/* strip's trailing '.'s and adds the extension only when needed */ /**
int BLI_ensure_extension(char *path, size_t maxlen, const char *ext) * Strip's trailing '.'s and adds the extension only when needed
*/
bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
{ {
size_t path_len = strlen(path); const size_t path_len = strlen(path);
size_t ext_len = strlen(ext); const size_t ext_len = strlen(ext);
ssize_t a; ssize_t a;
/* first check the extension is alread there */ /* first check the extension is already there */
if ( (ext_len <= path_len) && if ( (ext_len <= path_len) &&
(strcmp(path + (path_len - ext_len), ext) == 0)) (strcmp(path + (path_len - ext_len), ext) == 0))
{ {
return 1; return true;
} }
for (a = path_len - 1; a >= 0; a--) { for (a = path_len - 1; a >= 0; a--) {
@ -1538,10 +1644,10 @@ int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
a++; a++;
if (a + ext_len >= maxlen) if (a + ext_len >= maxlen)
return 0; return false;
memcpy(path + a, ext, ext_len + 1); memcpy(path + a, ext, ext_len + 1);
return 1; return true;
} }
/* Converts "/foo/bar.txt" to "/foo/" and "bar.txt" /* Converts "/foo/bar.txt" to "/foo/" and "bar.txt"
@ -1553,7 +1659,7 @@ int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen) void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
{ {
const char *lslash_str = BLI_last_slash(string); const char *lslash_str = BLI_last_slash(string);
size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0; const size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
if (dir) { if (dir) {
if (lslash) { if (lslash) {
@ -1569,17 +1675,26 @@ void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t d
} }
} }
/**
* Copies the parent directory part of string into *dir, max length dirlen.
*/
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen) void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
{ {
BLI_split_dirfile(string, dir, NULL, dirlen, 0); BLI_split_dirfile(string, dir, NULL, dirlen, 0);
} }
/**
* Copies the leaf filename part of string into *file, max length filelen.
*/
void BLI_split_file_part(const char *string, char *file, const size_t filelen) void BLI_split_file_part(const char *string, char *file, const size_t filelen)
{ {
BLI_split_dirfile(string, NULL, file, 0, filelen); BLI_split_dirfile(string, NULL, file, 0, filelen);
} }
/* simple appending of filename to dir, does not check for valid path! */ /**
* Simple appending of filename to dir, does not check for valid path!
* Puts result into *dst, which may be same area as *dir.
*/
void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const char *file) void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const char *file)
{ {
size_t dirlen = BLI_strnlen(dir, maxlen); size_t dirlen = BLI_strnlen(dir, maxlen);
@ -1616,7 +1731,12 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha
BLI_strncpy(dst + dirlen, file, maxlen - dirlen); BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
} }
/* like pythons os.path.basename( ) */ /**
* like pythons os.path.basename()
*
* \return The pointer into \a path string immediately after last slash,
* or start of \a path if none found.
*/
const char *BLI_path_basename(const char *path) const char *BLI_path_basename(const char *path)
{ {
const char * const filename = BLI_last_slash(path); const char * const filename = BLI_last_slash(path);
@ -1658,11 +1778,29 @@ const char *BLI_path_basename(const char *path)
* this function returns wrong results! * this function returns wrong results!
* XXX: test on empty base_dir and return an error ? * XXX: test on empty base_dir and return an error ?
*/ */
int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const char *base_dir, const char *src_dir, const char *dest_dir)
/**
*
* \param abs Optional string to return new full path
* \param abs_len Size of *abs string
* \param rel Optional area to return new path relative to parent directory of .blend file
* (only meaningful if item is in a subdirectory thereof)
* \param rel_len Size of *rel area
* \param base_dir Path of .blend file
* \param src_dir Original path of item (any initial "//" will be expanded to
* parent directory of .blend file)
* \param dest_dir New directory into which item will be moved
* \return bli_rebase_state
*
* \note Not actually used anywhere!
*/
int BLI_rebase_path(char *abs, size_t abs_len,
char *rel, size_t rel_len,
const char *base_dir, const char *src_dir, const char *dest_dir)
{ {
char path[FILE_MAX]; char path[FILE_MAX]; /* original full path of item */
char dir[FILE_MAX]; char dir[FILE_MAX]; /* directory part of src_dir */
char base[FILE_MAX]; char base[FILE_MAX]; /* basename part of src_dir */
char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */ char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
char dest_path[FILE_MAX]; char dest_path[FILE_MAX];
char rel_dir[FILE_MAX]; char rel_dir[FILE_MAX];
@ -1694,21 +1832,23 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
/* if image is "below" current .blend file directory */ /* if image is "below" current .blend file directory */
if (!BLI_path_ncmp(path, blend_dir, len)) { if (!BLI_path_ncmp(path, blend_dir, len)) {
/* if image is _in_ current .blend file directory */
if (BLI_path_cmp(dir, blend_dir) == 0) { if (BLI_path_cmp(dir, blend_dir) == 0) {
/* image is directly in .blend file parent directory => put directly in dest_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base); BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
} }
/* "below" */
else { else {
/* "below" (in subdirectory of .blend file parent directory) => put in same relative directory structure in dest_dir */
/* rel = image_path_dir - blend_dir */ /* rel = image_path_dir - blend_dir */
BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir)); BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
/* subdirectories relative to blend_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir); BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir);
/* same subdirectories relative to dest_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base); BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base);
/* keeping original item basename */
} }
} }
/* image is out of current directory */ /* image is out of current directory -- just put straight in dest_dir */
else { else {
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base); BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
} }
@ -1718,7 +1858,7 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
if (rel) { if (rel) {
strncat(rel, rel_dir, rel_len); strncat(rel, rel_dir, rel_len);
strncat(rel, base, rel_len); strncat(rel, base, rel_len); /* FIXME: could overflow rel area! */
} }
/* return 2 if (src == dest) */ /* return 2 if (src == dest) */
@ -1792,6 +1932,11 @@ void BLI_del_slash(char *string)
} }
} }
/**
* Tries appending each of the semicolon-separated extensions in the PATHEXT
* environment variable (Windows-only) onto *name in turn until such a file is found.
* Returns success/failure.
*/
static int add_win32_extension(char *name) static int add_win32_extension(char *name)
{ {
int retval = 0; int retval = 0;
@ -2008,16 +2153,26 @@ static void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir
} }
} }
/**
* Sets btempdir to userdir if specified and is a valid directory, otherwise
* chooses a suitable OS-specific temporary directory.
*/
void BLI_init_temporary_dir(char *userdir) void BLI_init_temporary_dir(char *userdir)
{ {
BLI_where_is_temp(btempdir, FILE_MAX, userdir); BLI_where_is_temp(btempdir, FILE_MAX, userdir);
} }
/**
* Returns the path to the temporary directory.
*/
const char *BLI_temporary_dir(void) const char *BLI_temporary_dir(void)
{ {
return btempdir; return btempdir;
} }
/**
* Puts in *dir path to OS-specific temporary directory.
*/
void BLI_system_temporary_dir(char *dir) void BLI_system_temporary_dir(char *dir)
{ {
BLI_where_is_temp(dir, FILE_MAX, NULL); BLI_where_is_temp(dir, FILE_MAX, NULL);
@ -2025,6 +2180,10 @@ void BLI_system_temporary_dir(char *dir)
#ifdef WITH_ICONV #ifdef WITH_ICONV
/**
* Converts a string encoded in the charset named by *code to UTF-8.
* Opens a new iconv context each time it is run, which is probably not the
* most efficient. */
void BLI_string_to_utf8(char *original, char *utf_8, const char *code) void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
{ {
size_t inbytesleft = strlen(original); size_t inbytesleft = strlen(original);
@ -2045,6 +2204,7 @@ void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
rv = iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft); rv = iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
if (rv == (size_t) -1) { if (rv == (size_t) -1) {
printf("iconv Error\n"); printf("iconv Error\n");
iconv_close(cd);
return; return;
} }
*utf_8 = '\0'; *utf_8 = '\0';

@ -93,12 +93,14 @@
/* vars: */ /* vars: */
static int totnum, actnum; 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_; * Copies the current working directory into *dir (max size maxncpy), and
* returns a pointer to same.
/* can return NULL when the size is not big enough */ *
* \note can return NULL when the size is not big enough
*/
char *BLI_current_working_dir(char *dir, const size_t maxncpy) char *BLI_current_working_dir(char *dir, const size_t maxncpy)
{ {
const char *pwd = getenv("PWD"); const char *pwd = getenv("PWD");
@ -110,26 +112,33 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy)
return getcwd(dir, 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) static int bli_compare(struct direntry *entry1, struct direntry *entry2)
{ {
/* type is equal to stat.st_mode */ /* type is equal to stat.st_mode */
/* directories come before non-directories */
if (S_ISDIR(entry1->type)) { if (S_ISDIR(entry1->type)) {
if (S_ISDIR(entry2->type) == 0) return (-1); if (S_ISDIR(entry2->type) == 0) return (-1);
} }
else { else {
if (S_ISDIR(entry2->type)) return (1); if (S_ISDIR(entry2->type)) return (1);
} }
/* non-regular files come after regular files */
if (S_ISREG(entry1->type)) { if (S_ISREG(entry1->type)) {
if (S_ISREG(entry2->type) == 0) return (-1); if (S_ISREG(entry2->type) == 0) return (-1);
} }
else { else {
if (S_ISREG(entry2->type)) return (1); 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);
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 */ /* make sure "." and ".." are always first */
if (strcmp(entry1->relname, ".") == 0) return (-1); if (strcmp(entry1->relname, ".") == 0) return (-1);
if (strcmp(entry2->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)); 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) double BLI_dir_free_space(const char *dir)
{ {
#ifdef WIN32 #ifdef WIN32
@ -197,10 +209,14 @@ double BLI_dir_free_space(const char *dir)
#endif #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) static void bli_builddir(const char *dirname, const char *relname)
{ {
struct dirent *fname; struct ListBase dirbase = {NULL, NULL};
struct dirlink *dlink;
int rellen, newnum = 0; int rellen, newnum = 0;
char buf[256]; char buf[256];
DIR *dir; DIR *dir;
@ -212,6 +228,9 @@ static void bli_builddir(const char *dirname, const char *relname)
buf[rellen] = '/'; buf[rellen] = '/';
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 #ifndef WIN32
if (chdir(dirname) == -1) { if (chdir(dirname) == -1) {
perror(dirname); perror(dirname);
@ -227,13 +246,14 @@ static void bli_builddir(const char *dirname, const char *relname)
UTF16_UN_ENCODE(dirname); UTF16_UN_ENCODE(dirname);
#endif #endif
if ((dir = (DIR *)opendir("."))) { if ((dir = opendir(".")) != NULL) {
while ((fname = (struct dirent *) readdir(dir)) != NULL) { const struct dirent *fname;
dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); while ((fname = readdir(dir)) != NULL) {
if (dlink) { struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
if (dlink != NULL) {
BLI_strncpy(buf + rellen, fname->d_name, sizeof(buf) - rellen); BLI_strncpy(buf + rellen, fname->d_name, sizeof(buf) - rellen);
dlink->name = BLI_strdup(buf); dlink->name = BLI_strdup(buf);
BLI_addhead(dirbase, dlink); BLI_addhead(&dirbase, dlink);
newnum++; newnum++;
} }
} }
@ -241,7 +261,7 @@ static void bli_builddir(const char *dirname, const char *relname)
if (newnum) { if (newnum) {
if (files) { if (files) {
void *tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry)); void * const tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry));
if (tmp) { if (tmp) {
files = (struct direntry *)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)); files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
if (files) { if (files) {
dlink = (struct dirlink *) dirbase->first; struct dirlink * dlink = (struct dirlink *) dirbase.first;
while (dlink) { while (dlink) {
memset(&files[actnum], 0, sizeof(struct direntry)); memset(&files[actnum], 0, sizeof(struct direntry));
files[actnum].relname = dlink->name; files[actnum].relname = dlink->name;
@ -278,6 +298,8 @@ static void bli_builddir(const char *dirname, const char *relname)
#endif #endif
files[actnum].type = files[actnum].s.st_mode; files[actnum].type = files[actnum].s.st_mode;
files[actnum].flags = 0; 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++; totnum++;
actnum++; actnum++;
dlink = dlink->next; dlink = dlink->next;
@ -288,7 +310,7 @@ static void bli_builddir(const char *dirname, const char *relname)
exit(1); exit(1);
} }
BLI_freelist(dirbase); BLI_freelist(&dirbase);
if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare); if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
} }
else { 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) static void bli_adddirstrings(void)
{ {
char datum[100]; char datum[100];
char buf[512]; char buf[512];
char size[250]; char size[250];
static const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"}; static const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
/* symbolic display, indexed by mode field value */
int num, mode; int num, mode;
#ifdef WIN32 #ifdef WIN32
__int64 st_size; __int64 st_size;
@ -375,6 +402,9 @@ static void bli_adddirstrings(void)
*/ */
st_size = file->s.st_size; 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) { if (st_size > 1024 * 1024 * 1024) {
BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)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->date, file->time, size, file->relname);
file->string = BLI_strdup(buf); 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) unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
{ {
/* reset global variables /* 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) size_t BLI_file_descriptor_size(int file)
{ {
struct stat buf; struct stat buf;
if (file <= 0) return (-1); if (file < 0) return (-1);
fstat(file, &buf); /* CHANGE */ fstat(file, &buf); /* CHANGE */
return (buf.st_size); return (buf.st_size);
} }
/**
* Returns the size of a file.
*/
size_t BLI_file_size(const char *path) 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); int size, file = BLI_open(path, O_BINARY | O_RDONLY, 0);
if (file == -1) if (file == -1)
@ -462,7 +504,10 @@ size_t BLI_file_size(const char *path)
return size; 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) int BLI_exists(const char *name)
{ {
#if defined(WIN32) #if defined(WIN32)
@ -509,18 +554,27 @@ int BLI_stat(const char *path, struct stat *buffer)
} }
#endif #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)); 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)); 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) LinkNode *BLI_file_read_as_lines(const char *name)
{ {
FILE *fp = BLI_fopen(name, "r"); 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); char *line = BLI_strdupn(&buf[last], i - last);
BLI_linklist_prepend(&lines, line); 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; last = i + 1;
} }
} }
@ -558,17 +615,21 @@ LinkNode *BLI_file_read_as_lines(const char *name)
fclose(fp); fclose(fp);
/* get them the right way round */
BLI_linklist_reverse(&lines); BLI_linklist_reverse(&lines);
return lines; return lines;
} }
/*
* Frees memory from a previous call to BLI_file_read_as_lines.
*/
void BLI_file_free_lines(LinkNode *lines) void BLI_file_free_lines(LinkNode *lines)
{ {
BLI_linklist_free(lines, (void (*)(void *))MEM_freeN); BLI_linklist_free(lines, (void (*)(void *))MEM_freeN);
} }
/** is file1 older then file2 */ /** 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 #ifdef WIN32
struct _stat st1, st2; struct _stat st1, st2;
@ -576,16 +637,16 @@ int BLI_file_older(const char *file1, const char *file2)
UTF16_ENCODE(file1); UTF16_ENCODE(file1);
UTF16_ENCODE(file2); UTF16_ENCODE(file2);
if (_wstat(file1_16, &st1)) return 0; if (_wstat(file1_16, &st1)) return false;
if (_wstat(file2_16, &st2)) return 0; if (_wstat(file2_16, &st2)) return false;
UTF16_UN_ENCODE(file2); UTF16_UN_ENCODE(file2);
UTF16_UN_ENCODE(file1); UTF16_UN_ENCODE(file1);
#else #else
struct stat st1, st2; struct stat st1, st2;
if (stat(file1, &st1)) return 0; if (stat(file1, &st1)) return false;
if (stat(file2, &st2)) return 0; if (stat(file2, &st2)) return false;
#endif #endif
return (st1.st_mtime < st2.st_mtime); return (st1.st_mtime < st2.st_mtime);
} }

@ -110,7 +110,7 @@ ImBuf *get_brush_icon(Brush *brush)
static const int flags = IB_rect | IB_multilayer | IB_metadata; static const int flags = IB_rect | IB_multilayer | IB_metadata;
char path[FILE_MAX]; char path[FILE_MAX];
char *folder; const char *folder;
if (!(brush->icon_imbuf)) { if (!(brush->icon_imbuf)) {
if (brush->flag & BRUSH_CUSTOM_ICON) { if (brush->flag & BRUSH_CUSTOM_ICON) {

@ -583,7 +583,7 @@ void file_change_dir(bContext *C, int checkdir)
ED_fileselect_clear(C, sfile); ED_fileselect_clear(C, sfile);
if (checkdir && BLI_is_dir(sfile->params->dir) == 0) { if (checkdir && !BLI_is_dir(sfile->params->dir)) {
BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir)); BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir));
/* could return but just refresh the current dir */ /* could return but just refresh the current dir */
} }

@ -629,7 +629,7 @@ void ED_spacetype_file(void)
void ED_file_init(void) void ED_file_init(void)
{ {
char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
fsmenu_read_system(fsmenu_get(), TRUE); fsmenu_read_system(fsmenu_get(), TRUE);

@ -29,6 +29,7 @@
* \ingroup imbuf * \ingroup imbuf
*/ */
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "imbuf.h" #include "imbuf.h"

@ -32,6 +32,7 @@
#include <string.h> #include <string.h>
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"

@ -37,6 +37,7 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"

@ -33,6 +33,7 @@
#include "png.h" #include "png.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "BLI_math.h" #include "BLI_math.h"

@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "imbuf.h" #include "imbuf.h"

@ -34,6 +34,7 @@
# include <io.h> # include <io.h>
#endif #endif
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"

@ -74,7 +74,7 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self))
{ {
PyObject *ret = PyTuple_New(2); PyObject *ret = PyTuple_New(2);
PyObject *item; PyObject *item;
char *path; const char *path;
path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL); path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL);
item = PyUnicode_DecodeFSDefault(path ? path : ""); item = PyUnicode_DecodeFSDefault(path ? path : "");
@ -147,7 +147,7 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
int folder_id; int folder_id;
static const char *kwlist[] = {"type", "subdir", NULL}; static const char *kwlist[] = {"type", "subdir", NULL};
char *path; const char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir)) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir))
return NULL; return NULL;
@ -191,7 +191,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100; int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
static const char *kwlist[] = {"type", "major", "minor", NULL}; static const char *kwlist[] = {"type", "major", "minor", NULL};
int folder_id; int folder_id;
char *path; const char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor)) if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor))
return NULL; return NULL;
@ -245,7 +245,7 @@ void BPy_init_modules(void)
PyObject *mod; PyObject *mod;
/* Needs to be first since this dir is needed for future modules */ /* Needs to be first since this dir is needed for future modules */
char *modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules"); const char * const modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
if (modpath) { if (modpath) {
// printf("bpy: found module path '%s'.\n", modpath); // printf("bpy: found module path '%s'.\n", modpath);
PyObject *sys_path = PySys_GetObject("path"); /* borrow */ PyObject *sys_path = PySys_GetObject("path"); /* borrow */

@ -35,13 +35,13 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_path_util.h" #include "BLI_path_util.h"
#include "BLI_rect.h" #include "BLI_rect.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_threads.h" #include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BKE_image.h" #include "BKE_image.h"
#include "BKE_global.h" #include "BKE_global.h"

@ -502,7 +502,7 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
G.relbase_valid = 0; G.relbase_valid = 0;
if (!from_memory) { if (!from_memory) {
char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (cfgdir) { if (cfgdir) {
BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE);
BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE);
@ -614,7 +614,7 @@ void wm_read_history(void)
struct RecentFile *recent; struct RecentFile *recent;
char *line; char *line;
int num; int num;
char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (!cfgdir) return; if (!cfgdir) return;
@ -643,7 +643,7 @@ static void write_history(void)
{ {
struct RecentFile *recent, *next_recent; struct RecentFile *recent, *next_recent;
char name[FILE_MAX]; char name[FILE_MAX];
char *user_config_dir; const char *user_config_dir;
FILE *fp; FILE *fp;
int i; int i;

@ -1598,14 +1598,14 @@ static void wm_block_splash_refreshmenu(bContext *UNUSED(C), void *UNUSED(arg_bl
static int wm_resource_check_prev(void) static int wm_resource_check_prev(void)
{ {
char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, TRUE); const char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true);
// if (res) printf("USER: %s\n", res); // if (res) printf("USER: %s\n", res);
#if 0 /* ignore the local folder */ #if 0 /* ignore the local folder */
if (res == NULL) { if (res == NULL) {
/* with a local dir, copying old files isn't useful since local dir get priority for config */ /* with a local dir, copying old files isn't useful since local dir get priority for config */
res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, TRUE); res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true);
} }
#endif #endif
@ -1614,7 +1614,7 @@ static int wm_resource_check_prev(void)
return FALSE; return FALSE;
} }
else { else {
return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, TRUE) != NULL); return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL);
} }
} }
@ -2409,7 +2409,7 @@ static int blend_save_check(bContext *UNUSED(C), wmOperator *op)
RNA_string_get(op->ptr, "filepath", filepath); RNA_string_get(op->ptr, "filepath", filepath);
if (!BLO_has_bfile_extension(filepath)) { if (!BLO_has_bfile_extension(filepath)) {
/* some users would prefer BLI_replace_extension(), /* some users would prefer BLI_replace_extension(),
* we keep getting knit-picking bug reports about this - campbell */ * we keep getting nitpicking bug reports about this - campbell */
BLI_ensure_extension(filepath, FILE_MAX, ".blend"); BLI_ensure_extension(filepath, FILE_MAX, ".blend");
RNA_string_set(op->ptr, "filepath", filepath); RNA_string_set(op->ptr, "filepath", filepath);
return TRUE; return TRUE;

@ -49,12 +49,12 @@
#include "PIL_time.h" #include "PIL_time.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_path_util.h" #include "BLI_path_util.h"
#include "BLI_rect.h" #include "BLI_rect.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_utildefines.h"
#include "IMB_imbuf_types.h" #include "IMB_imbuf_types.h"
#include "IMB_imbuf.h" #include "IMB_imbuf.h"

@ -1888,7 +1888,7 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
* somehow it remembers the sys.path - Campbell * somehow it remembers the sys.path - Campbell
*/ */
static bool first_time = true; static bool first_time = true;
char *py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL); const char * const py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL);
#if 0 // TODO - py3 #if 0 // TODO - py3
STR_String pname = progname; STR_String pname = progname;