diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-11-23 16:37:13 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-11-23 20:42:18 +0300 |
commit | 6308c16675fa7d5d6a3b91eb8591402c65b767d6 (patch) | |
tree | 12cb63e8e4d8d26f1c44094c7b4618011d586a07 /source | |
parent | 57c9d69e6bcfba01090282161c04252c4780b0fa (diff) |
Refactor: BLI_path_util (split out app directory access)
This module is intended for path manipulation functions
but had utility functions added to access various directories.
Diffstat (limited to 'source')
35 files changed, 932 insertions, 810 deletions
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 12d71827136..308e0819efe 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -42,6 +42,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" +#include "BKE_appdir.h" #include "DNA_userdef_types.h" diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c index 150ff1b2107..276c68130c2 100644 --- a/source/blender/blenfont/intern/blf_translation.c +++ b/source/blender/blenfont/intern/blf_translation.c @@ -42,6 +42,8 @@ #include "BLI_path_util.h" #include "BLI_string.h" +#include "BKE_appdir.h" + #include "DNA_userdef_types.h" /* For user settings. */ #include "BPY_extern.h" diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h new file mode 100644 index 00000000000..3b2e70ba3e0 --- /dev/null +++ b/source/blender/blenkernel/BKE_appdir.h @@ -0,0 +1,85 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __BKE_APPDIR_H__ +#define __BKE_APPDIR_H__ + +/** \file BKE_appdir.h + * \ingroup bli + */ + +#ifdef __cplusplus +extern "C" { +#endif + +const char *BLI_getDefaultDocumentFolder(void); + +const char *BLI_get_folder(int folder_id, const char *subfolder); +const char *BLI_get_folder_create(int folder_id, const char *subfolder); +const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder); +const char *BLI_get_folder_version(const int id, const int ver, const bool do_check); + + +/* Initialize path to program executable */ +void BLI_init_program_path(const char *argv0); +/* Initialize path to temporary directory. + * NOTE: On Window userdir will be set to the temporary directory! */ +void BLI_temp_dir_init(char *userdir); + +const char *BLI_program_path(void); +const char *BLI_program_dir(void); +const char *BLI_temp_dir_session(void); +const char *BLI_temp_dir_base(void); +void BLI_system_temporary_dir(char *dir); +void BLI_temp_dir_session_purge(void); + + +/* folder_id */ + +/* general, will find based on user/local/system priority */ +#define BLENDER_DATAFILES 2 + +/* user-specific */ +#define BLENDER_USER_CONFIG 31 +#define BLENDER_USER_DATAFILES 32 +#define BLENDER_USER_SCRIPTS 33 +#define BLENDER_USER_AUTOSAVE 34 + +/* system */ +#define BLENDER_SYSTEM_DATAFILES 52 +#define BLENDER_SYSTEM_SCRIPTS 53 +#define BLENDER_SYSTEM_PYTHON 54 + +/* for BLI_get_folder_version only */ +#define BLENDER_RESOURCE_PATH_USER 0 +#define BLENDER_RESOURCE_PATH_LOCAL 1 +#define BLENDER_RESOURCE_PATH_SYSTEM 2 + +#define BLENDER_STARTUP_FILE "startup.blend" +#define BLENDER_USERPREF_FILE "userpref.blend" +#define BLENDER_QUIT_FILE "quit.blend" +#define BLENDER_BOOKMARK_FILE "bookmarks.txt" +#define BLENDER_HISTORY_FILE "recent-files.txt" + + +#ifdef __cplusplus +} +#endif + +#endif /* __BKE_APPDIR_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 6550882c2f7..fb717b1745b 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -37,6 +37,7 @@ set(INC ../modifiers ../nodes ../render/extern/include + ../../../intern/ghost ../../../intern/guardedalloc ../../../intern/glew-mx ../../../intern/iksolver/extern @@ -63,6 +64,7 @@ set(SRC intern/addon.c intern/anim.c intern/anim_sys.c + intern/appdir.c intern/armature.c intern/autoexec.c intern/blender.c @@ -176,6 +178,7 @@ set(SRC BKE_addon.h BKE_anim.h BKE_animsys.h + BKE_appdir.h BKE_armature.h BKE_autoexec.h BKE_blender.h @@ -276,6 +279,12 @@ set(SRC add_definitions(${GL_DEFINITIONS}) +if(WIN32) + list(APPEND INC + ../../../intern/utfconv + ) +endif() + if(WITH_AUDASPACE) list(APPEND INC ../../../intern/audaspace/intern diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c new file mode 100644 index 00000000000..66dc4c113a2 --- /dev/null +++ b/source/blender/blenkernel/intern/appdir.c @@ -0,0 +1,806 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/** \file blender/blenlib/intern/appdir.c + * \ingroup bke + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "BLI_utildefines.h" +#include "BLI_string.h" +#include "BLI_fileops.h" +#include "BLI_path_util.h" + +#include "BKE_appdir.h" /* own include */ + +#include "GHOST_Path-api.h" + +#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */ + +#include "MEM_guardedalloc.h" + +#ifdef WIN32 +# include "utf_winfunc.h" +# include "utfconv.h" +# include <io.h> +# ifdef _WIN32_IE +# undef _WIN32_IE +# endif +# define _WIN32_IE 0x0501 +# include <windows.h> +# include <shlobj.h> +# include "BLI_winstuff.h" +#else /* non windows */ +# ifdef WITH_BINRELOC +# include "binreloc.h" +# endif +# include <unistd.h> /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */ +#endif /* WIN32 */ + +/* local */ +static char bprogname[FILE_MAX]; /* full path to program executable */ +static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */ +static char btempdir_base[FILE_MAX]; /* persistent temporary directory */ +static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */ + +/* This is now only used to really get the user's default document folder */ +/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used + * as default location to save documents */ +const char *BLI_getDefaultDocumentFolder(void) +{ +#ifndef WIN32 + const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR"); + + if (xdg_documents_dir) + return xdg_documents_dir; + + return getenv("HOME"); +#else /* Windows */ + static char documentfolder[MAXPATHLEN]; + HRESULT hResult; + + /* Check for %HOME% env var */ + if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) { + if (BLI_is_dir(documentfolder)) return documentfolder; + } + + /* add user profile support for WIN 2K / NT. + * This is %APPDATA%, which translates to either + * %USERPROFILE%\Application Data or since Vista + * to %USERPROFILE%\AppData\Roaming + */ + hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder); + + if (hResult == S_OK) { + if (BLI_is_dir(documentfolder)) return documentfolder; + } + + return NULL; +#endif /* WIN32 */ +} + + +// #define PATH_DEBUG + +/* returns a formatted representation of the specified version number. Non-reentrant! */ +static char *blender_version_decimal(const int ver) +{ + static char version_str[5]; + sprintf(version_str, "%d.%02d", ver / 100, ver % 100); + return version_str; +} + +/** + * 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]; + + if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep); + else BLI_strncpy(tmppath, path_base, sizeof(tmppath)); + + /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */ + if (folder_name) + BLI_make_file_string("/", targetpath, tmppath, folder_name); + else + 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)) { +#ifdef PATH_DEBUG + printf("\t%s found: %s\n", __func__, targetpath); +#endif + return true; + } + else { +#ifdef PATH_DEBUG + printf("\t%s missing: %s\n", __func__, targetpath); +#endif + //targetpath[0] = '\0'; + return false; + } +} + +/** + * 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; + if (!env) return false; + + if (BLI_is_dir(env)) { + BLI_strncpy(path, env, FILE_MAX); +#ifdef PATH_DEBUG + printf("\t%s env %s found: %s\n", __func__, envvar, env); +#endif + return true; + } + else { + path[0] = '\0'; +#ifdef PATH_DEBUG + printf("\t%s env %s missing: %s\n", __func__, envvar, env); +#endif + return false; + } +} + +/** + * 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]; + +#ifdef PATH_DEBUG + printf("%s...\n", __func__); +#endif + + if (folder_name) { + if (subfolder_name) { + BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); + } + else { + BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); + } + } + else { + relfolder[0] = '\0'; + } + + /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ +#ifdef __APPLE__ + static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */ + sprintf(osx_resourses, "%s../Resources", bprogdir); + return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder); +#else + return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder); +#endif +} + +/** + * 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 existence of config folder */ + const int ver = BLENDER_VERSION; + char path[FILE_MAX]; + + return get_path_local(path, "config", NULL, 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]; + const char *user_base_path; + + /* for portable install, user path is always local */ + if (is_portable_install()) + return get_path_local(targetpath, folder_name, subfolder_name, ver); + + user_path[0] = '\0'; + + if (test_env_path(user_path, envvar)) { + if (subfolder_name) { + return test_path(targetpath, user_path, NULL, subfolder_name); + } + else { + BLI_strncpy(targetpath, user_path, FILE_MAX); + return true; + } + } + + user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver)); + if (user_base_path) + BLI_strncpy(user_path, user_base_path, FILE_MAX); + + if (!user_path[0]) + return false; + +#ifdef PATH_DEBUG + printf("%s: %s\n", __func__, user_path); +#endif + + if (subfolder_name) { + return test_path(targetpath, user_path, folder_name, subfolder_name); + } + else { + return test_path(targetpath, user_path, NULL, folder_name); + } +} + +/** + * 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]; + const char *system_base_path; + char cwd[FILE_MAX]; + char relfolder[FILE_MAX]; + + if (folder_name) { + if (subfolder_name) { + BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); + } + else { + BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); + } + } + else { + 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 */ + if (BLI_current_working_dir(cwd, sizeof(cwd))) { + if (test_path(targetpath, cwd, "release", relfolder)) { + return true; + } + } + + /* try EXECUTABLE_DIR/release/folder_name */ + if (test_path(targetpath, bprogdir, "release", relfolder)) + return true; + + /* end developer overrides */ + + + + system_path[0] = '\0'; + + if (test_env_path(system_path, envvar)) { + if (subfolder_name) { + return test_path(targetpath, system_path, NULL, subfolder_name); + } + else { + BLI_strncpy(targetpath, system_path, FILE_MAX); + return true; + } + } + + system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver)); + if (system_base_path) + BLI_strncpy(system_path, system_base_path, FILE_MAX); + + if (!system_path[0]) + return false; + +#ifdef PATH_DEBUG + printf("%s: %s\n", __func__, system_path); +#endif + + if (subfolder_name) { + /* try $BLENDERPATH/folder_name/subfolder_name */ + return test_path(targetpath, system_path, folder_name, subfolder_name); + } + else { + /* try $BLENDERPATH/folder_name */ + return test_path(targetpath, system_path, NULL, folder_name); + } +} + +/* get a folder out of the 'folder_id' presets for paths */ +/* returns the path if found, NULL string if not */ +const char *BLI_get_folder(int folder_id, const char *subfolder) +{ + const int ver = BLENDER_VERSION; + static char path[FILE_MAX] = ""; + + switch (folder_id) { + case BLENDER_DATAFILES: /* general case */ + if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; + if (get_path_local(path, "datafiles", subfolder, ver)) break; + if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; + return NULL; + + case BLENDER_USER_DATAFILES: + if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; + return NULL; + + case BLENDER_SYSTEM_DATAFILES: + if (get_path_local(path, "datafiles", subfolder, ver)) break; + if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; + return NULL; + + case BLENDER_USER_AUTOSAVE: + if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break; + return NULL; + + case BLENDER_USER_CONFIG: + if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break; + return NULL; + + case BLENDER_USER_SCRIPTS: + if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break; + return NULL; + + case BLENDER_SYSTEM_SCRIPTS: + if (get_path_local(path, "scripts", subfolder, ver)) break; + if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break; + return NULL; + + case BLENDER_SYSTEM_PYTHON: + if (get_path_local(path, "python", subfolder, ver)) break; + if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break; + return NULL; + + default: + BLI_assert(0); + break; + } + + return path; +} + +/** + * 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; + static char path[FILE_MAX] = ""; + + switch (folder_id) { + case BLENDER_USER_DATAFILES: + get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver); + break; + case BLENDER_USER_CONFIG: + get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver); + break; + case BLENDER_USER_AUTOSAVE: + get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver); + break; + case BLENDER_USER_SCRIPTS: + get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver); + break; + default: + BLI_assert(0); + break; + } + + if ('\0' == path[0]) { + return NULL; + } + return path; +} + +/** + * 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) +{ + const char *path; + + /* only for user folders */ + if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) + return NULL; + + path = BLI_get_folder(folder_id, subfolder); + + if (!path) { + path = BLI_get_user_folder_notest(folder_id, subfolder); + if (path) BLI_dir_create_recursive(path); + } + + return path; +} + +/** + * 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] = ""; + bool ok; + switch (id) { + case BLENDER_RESOURCE_PATH_USER: + ok = get_path_user(path, NULL, NULL, NULL, ver); + break; + case BLENDER_RESOURCE_PATH_LOCAL: + ok = get_path_local(path, NULL, NULL, ver); + break; + case BLENDER_RESOURCE_PATH_SYSTEM: + ok = get_path_system(path, NULL, NULL, NULL, ver); + break; + default: + path[0] = '\0'; /* in case do_check is false */ + ok = false; + BLI_assert(!"incorrect ID"); + break; + } + + if (!ok && do_check) { + return NULL; + } + + return path; +} + +#ifdef PATH_DEBUG +# undef PATH_DEBUG +#endif + + + + +/* -------------------------------------------------------------------- */ +/* Preset paths */ + +/** + * 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) +{ + int retval = 0; + int type; + + type = BLI_exists(name); + if ((type == 0) || S_ISDIR(type)) { +#ifdef _WIN32 + char filename[FILE_MAX]; + char ext[FILE_MAX]; + const char *extensions = getenv("PATHEXT"); + if (extensions) { + char *temp; + do { + strcpy(filename, name); + temp = strstr(extensions, ";"); + if (temp) { + strncpy(ext, extensions, temp - extensions); + ext[temp - extensions] = 0; + extensions = temp + 1; + strcat(filename, ext); + } + else { + strcat(filename, extensions); + } + + type = BLI_exists(filename); + if (type && (!S_ISDIR(type))) { + retval = 1; + strcpy(name, filename); + break; + } + } while (temp); + } +#endif + } + else { + retval = 1; + } + + return (retval); +} + +/** + * Checks if name is a fully qualified filename to an executable. + * If not it searches $PATH for the file. On Windows it also + * adds the correct extension (.com .exe etc) from + * $PATHEXT if necessary. Also on Windows it translates + * the name to its 8.3 version to prevent problems with + * spaces and stuff. Final result is returned in fullname. + * + * \param fullname The full path and full name of the executable + * (must be FILE_MAX minimum) + * \param name The name of the executable (usually argv[0]) to be checked + */ +static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name) +{ + char filename[FILE_MAX]; + const char *path = NULL, *temp; + +#ifdef _WIN32 + const char *separator = ";"; +#else + const char *separator = ":"; +#endif + + +#ifdef WITH_BINRELOC + /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */ + path = br_find_exe(NULL); + if (path) { + BLI_strncpy(fullname, path, maxlen); + free((void *)path); + return; + } +#endif + +#ifdef _WIN32 + wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath"); + if (GetModuleFileNameW(0, fullname_16, maxlen)) { + conv_utf_16_to_8(fullname_16, fullname, maxlen); + if (!BLI_exists(fullname)) { + printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname); + MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); + } + MEM_freeN(fullname_16); + return; + } + + MEM_freeN(fullname_16); +#endif + + /* unix and non linux */ + if (name && name[0]) { + + BLI_strncpy(fullname, name, maxlen); + if (name[0] == '.') { + char wdir[FILE_MAX] = ""; + BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */ + + // not needed but avoids annoying /./ in name + if (name[1] == SEP) + BLI_join_dirfile(fullname, maxlen, wdir, name + 2); + else + BLI_join_dirfile(fullname, maxlen, wdir, name); + + add_win32_extension(fullname); /* XXX, doesnt respect length */ + } + else if (BLI_last_slash(name)) { + // full path + BLI_strncpy(fullname, name, maxlen); + add_win32_extension(fullname); + } + else { + // search for binary in $PATH + path = getenv("PATH"); + if (path) { + do { + temp = strstr(path, separator); + if (temp) { + strncpy(filename, path, temp - path); + filename[temp - path] = 0; + path = temp + 1; + } + else { + strncpy(filename, path, sizeof(filename)); + } + BLI_path_append(fullname, maxlen, name); + if (add_win32_extension(filename)) { + BLI_strncpy(fullname, filename, maxlen); + break; + } + } while (temp); + } + } +#if defined(DEBUG) + if (strcmp(name, fullname)) { + printf("guessing '%s' == '%s'\n", name, fullname); + } +#endif + } +} + +void BLI_init_program_path(const char *argv0) +{ + bli_where_am_i(bprogname, sizeof(bprogname), argv0); + BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir)); +} + +/** + * Path to executable + */ +const char *BLI_program_path(void) +{ + return bprogname; +} + +/** + * Path to directory of executable + */ +const char *BLI_program_dir(void) +{ + return bprogdir; +} + +/** + * Gets the temp directory when blender first runs. + * If the default path is not found, use try $TEMP + * + * Also make sure the temp dir has a trailing slash + * + * \param fullname The full path to the temporary temp directory + * \param basename The full path to the persistent temp directory (may be NULL) + * \param maxlen The size of the fullname buffer + * \param userdir Directory specified in user preferences + */ +static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) +{ + /* Clear existing temp dir, if needed. */ + BLI_temp_dir_session_purge(); + + fullname[0] = '\0'; + if (basename) { + basename[0] = '\0'; + } + + if (userdir && BLI_is_dir(userdir)) { + BLI_strncpy(fullname, userdir, maxlen); + } + + +#ifdef WIN32 + if (fullname[0] == '\0') { + const char *tmp = getenv("TEMP"); /* Windows */ + if (tmp && BLI_is_dir(tmp)) { + BLI_strncpy(fullname, tmp, maxlen); + } + } +#else + /* Other OS's - Try TMP and TMPDIR */ + if (fullname[0] == '\0') { + const char *tmp = getenv("TMP"); + if (tmp && BLI_is_dir(tmp)) { + BLI_strncpy(fullname, tmp, maxlen); + } + } + + if (fullname[0] == '\0') { + const char *tmp = getenv("TMPDIR"); + if (tmp && BLI_is_dir(tmp)) { + BLI_strncpy(fullname, tmp, maxlen); + } + } +#endif + + if (fullname[0] == '\0') { + BLI_strncpy(fullname, "/tmp/", maxlen); + } + else { + /* add a trailing slash if needed */ + BLI_add_slash(fullname); +#ifdef WIN32 + if (userdir && userdir != fullname) { + BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */ + } +#endif + } + + /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ + if (basename) { + /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ + char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); + const size_t ln = strlen(tmp_name) + 1; + if (ln <= maxlen) { +#ifdef WIN32 + if (_mktemp_s(tmp_name, ln) == 0) { + BLI_dir_create_recursive(tmp_name); + } +#else + mkdtemp(tmp_name); +#endif + } + if (BLI_is_dir(tmp_name)) { + BLI_strncpy(basename, fullname, maxlen); + BLI_strncpy(fullname, tmp_name, maxlen); + BLI_add_slash(fullname); + } + else { + printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname); + } + + MEM_freeN(tmp_name); + } +} + +/** + * Sets btempdir_base to userdir if specified and is a valid directory, otherwise + * chooses a suitable OS-specific temporary directory. + * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base. + */ +void BLI_temp_dir_init(char *userdir) +{ + BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir); +; +} + +/** + * Path to temporary directory (with trailing slash) + */ +const char *BLI_temp_dir_session(void) +{ + return btempdir_session[0] ? btempdir_session : BLI_temp_dir_base(); +} + +/** + * Path to persistent temporary directory (with trailing slash) + */ +const char *BLI_temp_dir_base(void) +{ + return btempdir_base; +} + +/** + * Path to the system temporary directory (with trailing slash) + */ +void BLI_system_temporary_dir(char *dir) +{ + BLI_where_is_temp(dir, NULL, FILE_MAX, NULL); +} + +/** + * Delete content of this instance's temp dir. + */ +void BLI_temp_dir_session_purge(void) +{ + if (btempdir_session[0] && BLI_is_dir(btempdir_session)) { + BLI_delete(btempdir_session, true, true); + } +} diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index adfe43cb2a3..17dc2574bf7 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -61,6 +61,7 @@ #include "IMB_imbuf.h" #include "IMB_moviecache.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_bpath.h" #include "BKE_brush.h" diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index a9e853c873e..295243a361e 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -57,6 +57,7 @@ #include "BLF_translation.h" +#include "BKE_appdir.h" #include "BKE_key.h" #include "BKE_multires.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index fba16a17e8b..46b68448550 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -58,6 +58,7 @@ #include "WM_api.h" +#include "BKE_appdir.h" #include "BKE_anim.h" #include "BKE_blender.h" #include "BKE_cloth.h" diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 1a13fcf99d9..37d0bd1798c 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -60,6 +60,7 @@ #include "DNA_scene_types.h" #include "DNA_smoke_types.h" +#include "BKE_appdir.h" #include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_bvhutils.h" diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 3d82480d050..bade390d056 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -40,40 +40,6 @@ extern "C" { struct ListBase; struct direntry; -const char *BLI_getDefaultDocumentFolder(void); - -const char *BLI_get_folder(int folder_id, const char *subfolder); -const char *BLI_get_folder_create(int folder_id, const char *subfolder); -const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder); -const char *BLI_get_folder_version(const int id, const int ver, const bool do_check); - -/* folder_id */ - -/* general, will find based on user/local/system priority */ -#define BLENDER_DATAFILES 2 - -/* user-specific */ -#define BLENDER_USER_CONFIG 31 -#define BLENDER_USER_DATAFILES 32 -#define BLENDER_USER_SCRIPTS 33 -#define BLENDER_USER_AUTOSAVE 34 - -/* system */ -#define BLENDER_SYSTEM_DATAFILES 52 -#define BLENDER_SYSTEM_SCRIPTS 53 -#define BLENDER_SYSTEM_PYTHON 54 - -/* for BLI_get_folder_version only */ -#define BLENDER_RESOURCE_PATH_USER 0 -#define BLENDER_RESOURCE_PATH_LOCAL 1 -#define BLENDER_RESOURCE_PATH_SYSTEM 2 - -#define BLENDER_STARTUP_FILE "startup.blend" -#define BLENDER_USERPREF_FILE "userpref.blend" -#define BLENDER_QUIT_FILE "quit.blend" -#define BLENDER_BOOKMARK_FILE "bookmarks.txt" -#define BLENDER_HISTORY_FILE "recent-files.txt" - #ifdef WIN32 #define SEP '\\' #define ALTSEP '/' @@ -185,19 +151,6 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char void BLI_char_switch(char *string, char from, char to) ATTR_NONNULL(); -/* Initialize path to program executable */ -void BLI_init_program_path(const char *argv0); -/* Initialize path to temporary directory. - * NOTE: On Window userdir will be set to the temporary directory! */ -void BLI_temp_dir_init(char *userdir); - -const char *BLI_program_path(void); -const char *BLI_program_dir(void); -const char *BLI_temp_dir_session(void); -const char *BLI_temp_dir_base(void); -void BLI_system_temporary_dir(char *dir); -void BLI_temp_dir_session_purge(void); - #ifdef WITH_ICONV void BLI_string_to_utf8(char *original, char *utf_8, const char *code); #endif diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index ba166b11960..cb84c0d2e52 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -29,7 +29,6 @@ set(INC . # ../blenkernel # dont add this back! ../makesdna - ../../../intern/ghost ../../../intern/guardedalloc ../../../extern/wcwidth ) diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index e3e13b0bcac..9a9385e0687 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -45,12 +45,6 @@ #include "BLI_string_utf8.h" #include "BLI_fnmatch.h" -#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */ - -#include "GHOST_Path-api.h" - -#include "MEM_guardedalloc.h" - #ifdef WIN32 # include "utf_winfunc.h" # include "utfconv.h" @@ -62,21 +56,12 @@ # include <windows.h> # include <shlobj.h> # include "BLI_winstuff.h" -#else /* non windows */ -# ifdef WITH_BINRELOC -# include "binreloc.h" -# endif -# include <unistd.h> /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */ +# include "MEM_guardedalloc.h" #endif /* WIN32 */ /* local */ #define UNIQUE_NAME_MAX 128 -static char bprogname[FILE_MAX]; /* full path to program executable */ -static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */ -static char btempdir_base[FILE_MAX]; /* persistent temporary directory */ -static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */ - /* implementation */ /** @@ -1038,446 +1023,8 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen) } } -/* This is now only used to really get the user's default document folder */ -/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used - * as default location to save documents */ -const char *BLI_getDefaultDocumentFolder(void) -{ -#ifndef WIN32 - const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR"); - - if (xdg_documents_dir) - return xdg_documents_dir; - - return getenv("HOME"); -#else /* Windows */ - static char documentfolder[MAXPATHLEN]; - HRESULT hResult; - - /* Check for %HOME% env var */ - if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) { - if (BLI_is_dir(documentfolder)) return documentfolder; - } - - /* add user profile support for WIN 2K / NT. - * This is %APPDATA%, which translates to either - * %USERPROFILE%\Application Data or since Vista - * to %USERPROFILE%\AppData\Roaming - */ - hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder); - - if (hResult == S_OK) { - if (BLI_is_dir(documentfolder)) return documentfolder; - } - - return NULL; -#endif /* WIN32 */ -} - -/* NEW stuff, to be cleaned up when fully migrated */ -/* ************************************************************* */ -/* ************************************************************* */ - -// #define PATH_DEBUG - -/* returns a formatted representation of the specified version number. Non-reentrant! */ -static char *blender_version_decimal(const int ver) -{ - static char version_str[5]; - sprintf(version_str, "%d.%02d", ver / 100, ver % 100); - return version_str; -} - -/** - * 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]; - - if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep); - else BLI_strncpy(tmppath, path_base, sizeof(tmppath)); - - /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */ - if (folder_name) - BLI_make_file_string("/", targetpath, tmppath, folder_name); - else - 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)) { -#ifdef PATH_DEBUG - printf("\t%s found: %s\n", __func__, targetpath); -#endif - return true; - } - else { -#ifdef PATH_DEBUG - printf("\t%s missing: %s\n", __func__, targetpath); -#endif - //targetpath[0] = '\0'; - return false; - } -} - -/** - * 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; - if (!env) return false; - - if (BLI_is_dir(env)) { - BLI_strncpy(path, env, FILE_MAX); -#ifdef PATH_DEBUG - printf("\t%s env %s found: %s\n", __func__, envvar, env); -#endif - return true; - } - else { - path[0] = '\0'; -#ifdef PATH_DEBUG - printf("\t%s env %s missing: %s\n", __func__, envvar, env); -#endif - return false; - } -} - -/** - * 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]; - -#ifdef PATH_DEBUG - printf("%s...\n", __func__); -#endif - if (folder_name) { - if (subfolder_name) { - BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); - } - else { - BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); - } - } - else { - relfolder[0] = '\0'; - } - /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ -#ifdef __APPLE__ - static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */ - sprintf(osx_resourses, "%s../Resources", bprogdir); - return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder); -#else - return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder); -#endif -} - -/** - * 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 existence of config folder */ - const int ver = BLENDER_VERSION; - char path[FILE_MAX]; - - return get_path_local(path, "config", NULL, 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]; - const char *user_base_path; - - /* for portable install, user path is always local */ - if (is_portable_install()) - return get_path_local(targetpath, folder_name, subfolder_name, ver); - - user_path[0] = '\0'; - - if (test_env_path(user_path, envvar)) { - if (subfolder_name) { - return test_path(targetpath, user_path, NULL, subfolder_name); - } - else { - BLI_strncpy(targetpath, user_path, FILE_MAX); - return true; - } - } - - user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver)); - if (user_base_path) - BLI_strncpy(user_path, user_base_path, FILE_MAX); - - if (!user_path[0]) - return false; - -#ifdef PATH_DEBUG - printf("%s: %s\n", __func__, user_path); -#endif - - if (subfolder_name) { - return test_path(targetpath, user_path, folder_name, subfolder_name); - } - else { - return test_path(targetpath, user_path, NULL, folder_name); - } -} - -/** - * 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]; - const char *system_base_path; - char cwd[FILE_MAX]; - char relfolder[FILE_MAX]; - - if (folder_name) { - if (subfolder_name) { - BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); - } - else { - BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); - } - } - else { - 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 */ - if (BLI_current_working_dir(cwd, sizeof(cwd))) { - if (test_path(targetpath, cwd, "release", relfolder)) { - return true; - } - } - - /* try EXECUTABLE_DIR/release/folder_name */ - if (test_path(targetpath, bprogdir, "release", relfolder)) - return true; - - /* end developer overrides */ - - - - system_path[0] = '\0'; - - if (test_env_path(system_path, envvar)) { - if (subfolder_name) { - return test_path(targetpath, system_path, NULL, subfolder_name); - } - else { - BLI_strncpy(targetpath, system_path, FILE_MAX); - return true; - } - } - - system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver)); - if (system_base_path) - BLI_strncpy(system_path, system_base_path, FILE_MAX); - - if (!system_path[0]) - return false; - -#ifdef PATH_DEBUG - printf("%s: %s\n", __func__, system_path); -#endif - - if (subfolder_name) { - /* try $BLENDERPATH/folder_name/subfolder_name */ - return test_path(targetpath, system_path, folder_name, subfolder_name); - } - else { - /* try $BLENDERPATH/folder_name */ - return test_path(targetpath, system_path, NULL, folder_name); - } -} - -/* get a folder out of the 'folder_id' presets for paths */ -/* returns the path if found, NULL string if not */ -const char *BLI_get_folder(int folder_id, const char *subfolder) -{ - const int ver = BLENDER_VERSION; - static char path[FILE_MAX] = ""; - - switch (folder_id) { - case BLENDER_DATAFILES: /* general case */ - if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - if (get_path_local(path, "datafiles", subfolder, ver)) break; - if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_DATAFILES: - if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - return NULL; - - case BLENDER_SYSTEM_DATAFILES: - if (get_path_local(path, "datafiles", subfolder, ver)) break; - if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_AUTOSAVE: - if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_CONFIG: - if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break; - return NULL; - - case BLENDER_USER_SCRIPTS: - if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break; - return NULL; - - case BLENDER_SYSTEM_SCRIPTS: - if (get_path_local(path, "scripts", subfolder, ver)) break; - if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break; - return NULL; - - case BLENDER_SYSTEM_PYTHON: - if (get_path_local(path, "python", subfolder, ver)) break; - if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break; - return NULL; - - default: - BLI_assert(0); - break; - } - - return path; -} - -/** - * 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; - static char path[FILE_MAX] = ""; - - switch (folder_id) { - case BLENDER_USER_DATAFILES: - get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver); - break; - case BLENDER_USER_CONFIG: - get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver); - break; - case BLENDER_USER_AUTOSAVE: - get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver); - break; - case BLENDER_USER_SCRIPTS: - get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver); - break; - default: - BLI_assert(0); - break; - } - - if ('\0' == path[0]) { - return NULL; - } - return path; -} - -/** - * 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) -{ - const char *path; - - /* only for user folders */ - if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) - return NULL; - - path = BLI_get_folder(folder_id, subfolder); - - if (!path) { - path = BLI_get_user_folder_notest(folder_id, subfolder); - if (path) BLI_dir_create_recursive(path); - } - - return path; -} - -/** - * 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] = ""; - bool ok; - switch (id) { - case BLENDER_RESOURCE_PATH_USER: - ok = get_path_user(path, NULL, NULL, NULL, ver); - break; - case BLENDER_RESOURCE_PATH_LOCAL: - ok = get_path_local(path, NULL, NULL, ver); - break; - case BLENDER_RESOURCE_PATH_SYSTEM: - ok = get_path_system(path, NULL, NULL, NULL, ver); - break; - default: - path[0] = '\0'; /* in case do_check is false */ - ok = false; - BLI_assert(!"incorrect ID"); - break; - } - - if (!ok && do_check) { - return NULL; - } - - return path; -} - -/* End new stuff */ -/* ************************************************************* */ -/* ************************************************************* */ - - - -#ifdef PATH_DEBUG -# undef PATH_DEBUG -#endif /** * Sets the specified environment variable to the specified value, @@ -2153,310 +1700,6 @@ void BLI_path_native_slash(char *path) #endif } -/** - * 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) -{ - int retval = 0; - int type; - - type = BLI_exists(name); - if ((type == 0) || S_ISDIR(type)) { -#ifdef _WIN32 - char filename[FILE_MAX]; - char ext[FILE_MAX]; - const char *extensions = getenv("PATHEXT"); - if (extensions) { - char *temp; - do { - strcpy(filename, name); - temp = strstr(extensions, ";"); - if (temp) { - strncpy(ext, extensions, temp - extensions); - ext[temp - extensions] = 0; - extensions = temp + 1; - strcat(filename, ext); - } - else { - strcat(filename, extensions); - } - - type = BLI_exists(filename); - if (type && (!S_ISDIR(type))) { - retval = 1; - strcpy(name, filename); - break; - } - } while (temp); - } -#endif - } - else { - retval = 1; - } - - return (retval); -} - -/** - * Checks if name is a fully qualified filename to an executable. - * If not it searches $PATH for the file. On Windows it also - * adds the correct extension (.com .exe etc) from - * $PATHEXT if necessary. Also on Windows it translates - * the name to its 8.3 version to prevent problems with - * spaces and stuff. Final result is returned in fullname. - * - * \param fullname The full path and full name of the executable - * (must be FILE_MAX minimum) - * \param name The name of the executable (usually argv[0]) to be checked - */ -static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name) -{ - char filename[FILE_MAX]; - const char *path = NULL, *temp; - -#ifdef _WIN32 - const char *separator = ";"; -#else - const char *separator = ":"; -#endif - - -#ifdef WITH_BINRELOC - /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */ - path = br_find_exe(NULL); - if (path) { - BLI_strncpy(fullname, path, maxlen); - free((void *)path); - return; - } -#endif - -#ifdef _WIN32 - wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath"); - if (GetModuleFileNameW(0, fullname_16, maxlen)) { - conv_utf_16_to_8(fullname_16, fullname, maxlen); - if (!BLI_exists(fullname)) { - printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname); - MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); - } - MEM_freeN(fullname_16); - return; - } - - MEM_freeN(fullname_16); -#endif - - /* unix and non linux */ - if (name && name[0]) { - - BLI_strncpy(fullname, name, maxlen); - if (name[0] == '.') { - char wdir[FILE_MAX] = ""; - BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */ - - // not needed but avoids annoying /./ in name - if (name[1] == SEP) - BLI_join_dirfile(fullname, maxlen, wdir, name + 2); - else - BLI_join_dirfile(fullname, maxlen, wdir, name); - - add_win32_extension(fullname); /* XXX, doesnt respect length */ - } - else if (BLI_last_slash(name)) { - // full path - BLI_strncpy(fullname, name, maxlen); - add_win32_extension(fullname); - } - else { - // search for binary in $PATH - path = getenv("PATH"); - if (path) { - do { - temp = strstr(path, separator); - if (temp) { - strncpy(filename, path, temp - path); - filename[temp - path] = 0; - path = temp + 1; - } - else { - strncpy(filename, path, sizeof(filename)); - } - BLI_path_append(fullname, maxlen, name); - if (add_win32_extension(filename)) { - BLI_strncpy(fullname, filename, maxlen); - break; - } - } while (temp); - } - } -#if defined(DEBUG) - if (strcmp(name, fullname)) { - printf("guessing '%s' == '%s'\n", name, fullname); - } -#endif - } -} - -void BLI_init_program_path(const char *argv0) -{ - bli_where_am_i(bprogname, sizeof(bprogname), argv0); - BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir)); -} - -/** - * Path to executable - */ -const char *BLI_program_path(void) -{ - return bprogname; -} - -/** - * Path to directory of executable - */ -const char *BLI_program_dir(void) -{ - return bprogdir; -} - -/** - * Gets the temp directory when blender first runs. - * If the default path is not found, use try $TEMP - * - * Also make sure the temp dir has a trailing slash - * - * \param fullname The full path to the temporary temp directory - * \param basename The full path to the persistent temp directory (may be NULL) - * \param maxlen The size of the fullname buffer - * \param userdir Directory specified in user preferences - */ -static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) -{ - /* Clear existing temp dir, if needed. */ - BLI_temp_dir_session_purge(); - - fullname[0] = '\0'; - if (basename) { - basename[0] = '\0'; - } - - if (userdir && BLI_is_dir(userdir)) { - BLI_strncpy(fullname, userdir, maxlen); - } - - -#ifdef WIN32 - if (fullname[0] == '\0') { - const char *tmp = getenv("TEMP"); /* Windows */ - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } -#else - /* Other OS's - Try TMP and TMPDIR */ - if (fullname[0] == '\0') { - const char *tmp = getenv("TMP"); - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } - - if (fullname[0] == '\0') { - const char *tmp = getenv("TMPDIR"); - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } -#endif - - if (fullname[0] == '\0') { - BLI_strncpy(fullname, "/tmp/", maxlen); - } - else { - /* add a trailing slash if needed */ - BLI_add_slash(fullname); -#ifdef WIN32 - if (userdir && userdir != fullname) { - BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */ - } -#endif - } - - /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ - if (basename) { - /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ - char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); - const size_t ln = strlen(tmp_name) + 1; - if (ln <= maxlen) { -#ifdef WIN32 - if (_mktemp_s(tmp_name, ln) == 0) { - BLI_dir_create_recursive(tmp_name); - } -#else - mkdtemp(tmp_name); -#endif - } - if (BLI_is_dir(tmp_name)) { - BLI_strncpy(basename, fullname, maxlen); - BLI_strncpy(fullname, tmp_name, maxlen); - BLI_add_slash(fullname); - } - else { - printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname); - } - - MEM_freeN(tmp_name); - } -} - -/** - * Sets btempdir_base to userdir if specified and is a valid directory, otherwise - * chooses a suitable OS-specific temporary directory. - * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base. - */ -void BLI_temp_dir_init(char *userdir) -{ - BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir); -; -} - -/** - * Path to temporary directory (with trailing slash) - */ -const char *BLI_temp_dir_session(void) -{ - return btempdir_session[0] ? btempdir_session : BLI_temp_dir_base(); -} - -/** - * Path to persistent temporary directory (with trailing slash) - */ -const char *BLI_temp_dir_base(void) -{ - return btempdir_base; -} - -/** - * Path to the system temporary directory (with trailing slash) - */ -void BLI_system_temporary_dir(char *dir) -{ - BLI_where_is_temp(dir, NULL, FILE_MAX, NULL); -} - -/** - * Delete content of this instance's temp dir. - */ -void BLI_temp_dir_session_purge(void) -{ - if (btempdir_session[0] && BLI_is_dir(btempdir_session)) { - BLI_delete(btempdir_session, true, true); - } -} #ifdef WITH_ICONV diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 51dd9166e46..3bb037901c3 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -51,6 +51,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_icons.h" +#include "BKE_appdir.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 5573515391d..3af978db19a 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -45,6 +45,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BKE_appdir.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_main.h" diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 47f7b6fe543..7398ed6d759 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -60,6 +60,7 @@ #include "DNA_brush_types.h" #include "DNA_screen_types.h" +#include "BKE_appdir.h" #include "BKE_brush.h" #include "BKE_context.h" #include "BKE_colortools.h" diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 13beba3fff8..9d6068047af 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -34,6 +34,7 @@ #include "BLO_readfile.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 8b90cf6cc29..04d270f5ed1 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -58,6 +58,7 @@ #include "BLI_fileops_types.h" #include "BLI_fnmatch.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index d5be04cff20..bda5aa865cd 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -41,6 +41,7 @@ #include "BLO_readfile.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 6a505959820..5aceeed20d7 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -42,6 +42,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_main.h" diff --git a/source/blender/freestyle/intern/application/AppConfig.cpp b/source/blender/freestyle/intern/application/AppConfig.cpp index cf7959ffaef..6da7dbea3e6 100644 --- a/source/blender/freestyle/intern/application/AppConfig.cpp +++ b/source/blender/freestyle/intern/application/AppConfig.cpp @@ -31,7 +31,7 @@ using namespace std; extern "C" { -#include "BLI_path_util.h" +#include "BKE_appdir.h" } namespace Freestyle { diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index 7ecb4164caf..86322bcd350 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -67,6 +67,7 @@ extern "C" { #include "BKE_global.h" #include "BLI_utildefines.h" +#include "BLI_path_util.h" #include "DNA_freestyle_types.h" diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp index 5b8d50eb5eb..c7be8b1dd17 100644 --- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -60,6 +60,7 @@ extern "C" { #include "FRS_freestyle.h" #include "RNA_access.h" +#include "BKE_appdir.h" #include "DNA_scene_types.h" #include "bpy_rna.h" /* pyrna_struct_CreatePyObject() */ diff --git a/source/blender/freestyle/intern/system/StringUtils.h b/source/blender/freestyle/intern/system/StringUtils.h index 77b543c7886..e11798762e4 100644 --- a/source/blender/freestyle/intern/system/StringUtils.h +++ b/source/blender/freestyle/intern/system/StringUtils.h @@ -36,7 +36,8 @@ extern "C" { #include "BKE_utildefines.h" -#include "BLI_blenlib.h" +#include "BLI_string.h" +#include "BLI_path_util.h" } using namespace std; diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 5dd6b366a93..69c5b24bda0 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -56,11 +56,11 @@ #include "BLI_fileops.h" #include "BLI_math.h" #include "BLI_math_color.h" -#include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_threads.h" #include "BLI_rect.h" +#include "BKE_appdir.h" #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_image.h" diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index ab5039df627..a77f4dbe3fe 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -35,6 +35,7 @@ #include "BLI_utildefines.h" +#include "BKE_appdir.h" #include "BKE_sound.h" #include "BKE_addon.h" diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 134e718bce5..7ffca8c06ea 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -31,9 +31,9 @@ #include <Python.h> #include "BLI_utildefines.h" -#include "BLI_path_util.h" #include "BLI_string.h" +#include "BKE_appdir.h" #include "BKE_main.h" #include "BKE_global.h" /* XXX, G.main only */ #include "BKE_blender.h" diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 16cdd44ce38..ae1443cd949 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -46,6 +46,7 @@ #include "BLI_utildefines.h" #include "BLI_path_util.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_global.h" #include "structseq.h" diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index d46c95a25b8..fed72625966 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -63,6 +63,7 @@ #include "DNA_text_types.h" +#include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_text.h" #include "BKE_main.h" diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 08a82d026a0..7b25cbae6ad 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" +#include "BKE_appdir.h" #include "BLI_utildefines.h" #include "BLI_listbase.h" #include "BLI_hash_md5.h" diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 8a6b5046b73..baf2d322db0 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -69,6 +69,7 @@ #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" +#include "BKE_appdir.h" #include "BKE_utildefines.h" #include "BKE_autoexec.h" #include "BKE_blender.h" diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index f762e19c969..aa93f103991 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -68,6 +68,7 @@ #include "BKE_report.h" #include "BKE_addon.h" +#include "BKE_appdir.h" #include "BKE_sequencer.h" /* free seq clipboard */ #include "BKE_material.h" /* clear_matcopybuf */ #include "BKE_tracking.h" /* free tracking clipboard */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 4052b560239..3c2850ee282 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -64,6 +64,7 @@ #include "BLO_readfile.h" +#include "BKE_appdir.h" #include "BKE_autoexec.h" #include "BKE_blender.h" #include "BKE_brush.h" diff --git a/source/creator/creator.c b/source/creator/creator.c index f872398300a..223c299d3bb 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -75,6 +75,7 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_brush.h" #include "BKE_context.h" diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 1a6501fae6e..685895a7301 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -64,6 +64,7 @@ extern "C" #include "BLO_readfile.h" #include "BLO_runtime.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_depsgraph.h" #include "BKE_global.h" diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index fefc64b4bad..1479b5d584a 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -133,6 +133,7 @@ extern "C" { #include "BKE_main.h" #include "BKE_global.h" #include "BKE_library.h" +#include "BKE_appdir.h" #include "BLI_blenlib.h" #include "GPU_material.h" #include "MEM_guardedalloc.h" |