40 # define _WIN32_IE 0x0501
46 # include "binreloc.h"
53 #define STR_OR_FALLBACK(a) ((a) ? (a) : _str_null)
72 .temp_dirname_session =
"",
83 # define ASSERT_IS_INIT() BLI_assert(is_appdir_init)
85 # define ASSERT_IS_INIT() ((void)0)
115 static char version_str[5];
117 BLI_snprintf(version_str,
sizeof(version_str),
"%d.%d", version / 100, version % 100);
135 return documentfolder;
166 #elif defined(__APPLE__)
180 if (documents_path &&
BLI_is_dir(documents_path)) {
194 BLI_path_join(try_documents_path,
sizeof(try_documents_path), home_path,
N_(
"Documents"),
NULL);
217 r_path, path_len, caches_root_path,
"Blender Foundation",
"Blender",
"Cache",
SEP_STR,
NULL);
218 #elif defined(__APPLE__)
234 if (SHGetSpecialFolderPathW(0, wpath, CSIDL_FONTS, 0)) {
235 wcscat(wpath,
L"\\");
238 #elif defined(__APPLE__)
242 STRNCPY(test_dir,
"/usr/share/fonts");
274 size_t targetpath_len,
275 const bool check_is_dir,
276 const char *path_base,
277 const char *folder_name,
278 const char *subfolder_name)
284 BLI_path_join(targetpath, targetpath_len, path_base, folder_name, subfolder_name,
NULL);
285 if (check_is_dir ==
false) {
286 CLOG_INFO(&
LOG, 3,
"using without test: '%s'", targetpath);
299 targetpath[0] =
'\0';
311 static bool test_env_path(
char *path,
const char *envvar,
const bool check_is_dir)
322 if (check_is_dir ==
false) {
323 CLOG_INFO(&
LOG, 3,
"using env '%s' without test: '%s'", envvar, env_path);
328 CLOG_INFO(&
LOG, 3,
"env '%s' found: %s", envvar, env_path);
332 CLOG_INFO(&
LOG, 3,
"env '%s' missing: %s", envvar, env_path);
353 size_t targetpath_len,
354 const char *folder_name,
355 const char *subfolder_name,
357 const bool check_is_dir)
363 "folder='%s', subfolder='%s'",
376 const char *path_base =
g_app.program_dirname;
381 BLI_snprintf(osx_resourses,
sizeof(osx_resourses),
"%s../Resources",
g_app.program_dirname);
384 path_base = osx_resourses;
394 size_t targetpath_len,
395 const char *folder_name,
396 const char *subfolder_name)
399 const bool check_is_dir =
true;
401 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
421 size_t targetpath_len,
422 const char *subfolder_name,
424 const bool check_is_dir)
430 return test_path(targetpath, targetpath_len, check_is_dir, user_path, subfolder_name,
NULL);
435 size_t targetpath_len,
436 const char *subfolder_name,
439 const bool check_is_dir =
true;
454 size_t targetpath_len,
455 const char *folder_name,
456 const char *subfolder_name,
458 const bool check_is_dir)
461 const char *user_base_path;
466 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
471 if (user_base_path) {
481 "'%s', folder='%s', subfolder='%s'",
488 targetpath, targetpath_len, check_is_dir, user_path, folder_name, subfolder_name);
491 size_t targetpath_len,
492 const char *folder_name,
493 const char *subfolder_name)
496 const bool check_is_dir =
true;
498 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
512 size_t targetpath_len,
513 const char *folder_name,
514 const char *subfolder_name,
516 const bool check_is_dir)
519 const char *system_base_path;
529 system_path[0] =
'\0';
531 if (system_base_path) {
535 if (!system_path[0]) {
541 "'%s', folder='%s', subfolder='%s'",
548 targetpath, targetpath_len, check_is_dir, system_path, folder_name, subfolder_name);
552 size_t targetpath_len,
553 const char *folder_name,
554 const char *subfolder_name)
557 const bool check_is_dir =
true;
559 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
569 const char *subfolder,
685 const bool check_is_dir =
false;
690 path,
sizeof(path), subfolder,
"BLENDER_USER_DATAFILES", check_is_dir)) {
693 get_path_user_ex(path,
sizeof(path),
"datafiles", subfolder, version, check_is_dir);
697 path,
sizeof(path), subfolder,
"BLENDER_USER_CONFIG", check_is_dir)) {
700 get_path_user_ex(path,
sizeof(path),
"config", subfolder, version, check_is_dir);
704 path,
sizeof(path), subfolder,
"BLENDER_USER_AUTOSAVE", check_is_dir)) {
707 get_path_user_ex(path,
sizeof(path),
"autosave", subfolder, version, check_is_dir);
711 path,
sizeof(path), subfolder,
"BLENDER_USER_SCRIPTS", check_is_dir)) {
714 get_path_user_ex(path,
sizeof(path),
"scripts", subfolder, version, check_is_dir);
721 if (
'\0' == path[0]) {
754 const bool check_is_dir)
774 return ok ? path :
NULL;
797 static void where_am_i(
char *fullname,
const size_t maxlen,
const char *name)
802 const char *path =
NULL;
803 path = br_find_exe(
NULL);
814 wchar_t *fullname_16 =
MEM_mallocN(maxlen *
sizeof(
wchar_t),
"ProgramPath");
815 if (GetModuleFileNameW(0, fullname_16, maxlen)) {
818 CLOG_ERROR(&
LOG,
"path can't be found: \"%.*s\"", (
int)maxlen, fullname);
820 NULL,
"path contains invalid characters or is too long (see console)",
"Error", MB_OK);
831 if (name && name[0]) {
834 if (name[0] ==
'.') {
837 BLI_path_program_extensions_add_win32(fullname, maxlen);
844 BLI_path_program_extensions_add_win32(fullname, maxlen);
854 if (!
STREQ(name, fullname)) {
855 CLOG_INFO(&
LOG, 2,
"guessing '%s' == '%s'", name, fullname);
870 return g_app.program_filepath;
876 return g_app.program_dirname;
880 const size_t fullpath_len,
881 const int version_major,
882 const int version_minor)
886 #ifdef PYTHON_EXECUTABLE_NAME
888 const char *python_build_def =
STRINGIFY(PYTHON_EXECUTABLE_NAME);
891 #if defined(WIN32) && !defined(NDEBUG)
892 const char *basename_debug =
"python_d";
894 char python_version[16];
896 const char *python_names[] = {
897 #ifdef PYTHON_EXECUTABLE_NAME
900 #if defined(WIN32) && !defined(NDEBUG)
906 bool is_found =
false;
908 SNPRINTF(python_version,
"%s%d.%d",
basename, version_major, version_minor);
912 if (python_bin_dir) {
914 for (
int i = 0; i <
ARRAY_SIZE(python_names); i++) {
919 BLI_path_program_extensions_add_win32(fullpath, fullpath_len)
931 if (is_found ==
false) {
932 for (
int i = 0; i <
ARRAY_SIZE(python_names); i++) {
940 if (is_found ==
false) {
955 "startup" SEP_STR "bl_app_templates_user",
956 "startup" SEP_STR "bl_app_templates_system",
1002 app_template, app_template_path,
sizeof(app_template_path))) {
1027 for (
int f = 0; f < dir_num; f++) {
1055 static void where_is_temp(
char *tempdir,
const size_t tempdir_len,
const char *userdir)
1064 if (tempdir[0] ==
'\0') {
1065 const char *env_vars[] = {
1075 for (
int i = 0; i <
ARRAY_SIZE(env_vars); i++) {
1077 if (tmp && (tmp[0] !=
'\0') &&
BLI_is_dir(tmp)) {
1084 if (tempdir[0] ==
'\0') {
1094 const size_t tempdir_session_len,
1095 const char *tempdir)
1097 tempdir_session[0] =
'\0';
1099 const int tempdir_len = strlen(tempdir);
1101 const char *session_name =
"blender_XXXXXX";
1102 const int session_name_len = strlen(session_name);
1106 const int tempdir_session_len_required = tempdir_len + session_name_len + 1;
1108 if (tempdir_session_len_required <= tempdir_session_len) {
1110 BLI_string_join(tempdir_session, tempdir_session_len, tempdir, session_name);
1112 const bool needs_create = (_mktemp_s(tempdir_session, tempdir_session_len_required) == 0);
1114 const bool needs_create = (mkdtemp(tempdir_session) ==
NULL);
1127 "Could not generate a temp file name for '%s', falling back to '%s'",
1130 BLI_strncpy(tempdir_session, tempdir, tempdir_session_len);
1146 g_app.temp_dirname_session,
sizeof(
g_app.temp_dirname_session),
g_app.temp_dirname_base);
1156 return g_app.temp_dirname_base;
#define BLENDER_USERPREF_FILE
@ BLENDER_RESOURCE_PATH_SYSTEM
@ BLENDER_RESOURCE_PATH_LOCAL
@ BLENDER_RESOURCE_PATH_USER
@ BLENDER_SYSTEM_DATAFILES
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_delete(const char *file, bool dir, bool recursive) ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **r_filelist)
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
bool BLI_dir_create_recursive(const char *dir) ATTR_NONNULL()
Some types for dealing with directories.
void BLI_kdtree_nd_() free(KDTree *tree)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
struct LinkData * BLI_genericNodeN(void *data)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_split_dir_part(const char *string, char *dir, size_t dirlen)
void BLI_path_normalize(const char *relabase, char *path) ATTR_NONNULL(2)
bool BLI_path_program_search(char *fullname, size_t maxlen, const char *name)
#define FILENAME_IS_CURRPAR(_n)
const char * BLI_getenv(const char *env) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
bool BLI_path_abs_from_cwd(char *path, size_t maxlen) ATTR_NONNULL()
int BLI_path_slash_ensure(char *string) ATTR_NONNULL()
const char * BLI_path_slash_rfind(const char *string) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
#define STRNCPY(dst, src)
#define SNPRINTF(dst, format,...)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, size_t maxncpy) ATTR_NONNULL(1
#define BLI_string_join(result, result_len,...)
Compatibility-like things for windows.
void BLI_windows_get_default_root_dir(char root_dir[4])
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
const char * GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type)
const char * GHOST_getUserDir(int version, const char *versionstr)
const char * GHOST_getSystemDir(int version, const char *versionstr)
@ GHOST_kUserSpecialDirCaches
@ GHOST_kUserSpecialDirDocuments
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
bool BKE_appdir_app_template_any(void)
static const char _str_null[]
const char * BKE_appdir_folder_id_version(const int folder_id, const int version, const bool check_is_dir)
const char * BKE_appdir_folder_id_create(const int folder_id, const char *subfolder)
static const int app_template_directory_id[2]
void BKE_tempdir_init(const char *userdir)
static bool is_appdir_init
static bool get_path_user(char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name)
char program_dirname[FILE_MAX]
bool BKE_appdir_font_folder_default(char *dir)
static void where_am_i(char *fullname, const size_t maxlen, const char *name)
const char * BKE_appdir_folder_default_or_root(void)
const char * BKE_appdir_folder_default(void)
static bool get_path_system_ex(char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name, const int version, const bool check_is_dir)
static char * blender_version_decimal(const int version)
bool BKE_appdir_app_is_portable_install(void)
char temp_dirname_session[FILE_MAX]
bool BKE_appdir_program_python_search(char *fullpath, const size_t fullpath_len, const int version_major, const int version_minor)
bool BKE_appdir_folder_documents(char *dir)
static bool test_env_path(char *path, const char *envvar, const bool check_is_dir)
void BKE_appdir_init(void)
bool BKE_appdir_app_template_has_userpref(const char *app_template)
void BKE_appdir_exit(void)
static bool get_path_user_ex(char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name, const int version, const bool check_is_dir)
void BKE_tempdir_session_purge(void)
static bool get_path_local(char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name)
const char * BKE_appdir_folder_id(const int folder_id, const char *subfolder)
static const char * app_template_directory_search[2]
bool BKE_appdir_folder_id_ex(const int folder_id, const char *subfolder, char *path, size_t path_len)
void BKE_appdir_program_path_init(const char *argv0)
static void tempdir_session_create(char *tempdir_session, const size_t tempdir_session_len, const char *tempdir)
const char * BKE_appdir_folder_home(void)
static bool get_path_local_ex(char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name, const int version, const bool check_is_dir)
const char * BKE_tempdir_session(void)
#define STR_OR_FALLBACK(a)
bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_len)
bool BKE_appdir_folder_caches(char *r_path, const size_t path_len)
static bool get_path_environment_ex(char *targetpath, size_t targetpath_len, const char *subfolder_name, const char *envvar, const bool check_is_dir)
const char * BKE_tempdir_base(void)
const char * BKE_appdir_folder_root(void)
static void where_is_temp(char *tempdir, const size_t tempdir_len, const char *userdir)
static bool get_path_system(char *targetpath, size_t targetpath_len, const char *folder_name, const char *subfolder_name)
void BKE_appdir_app_templates(ListBase *templates)
const char * BKE_appdir_program_path(void)
static bool test_path(char *targetpath, size_t targetpath_len, const bool check_is_dir, const char *path_base, const char *folder_name, const char *subfolder_name)
const char * BKE_appdir_program_dir(void)
const char * BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder)
char temp_dirname_base[FILE_MAX]
char program_filepath[FILE_MAX]
static bool get_path_environment(char *targetpath, size_t targetpath_len, const char *subfolder_name, const char *envvar)
static char * basename(char *string)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)
const char * BLI_expand_tilde(const char *path_with_tilde)
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8)