54 # define _WIN32_IE 0x0501
60 # include "binreloc.h"
67 #define STR_OR_FALLBACK(a) ((a) ? (a) : _str_null)
86 .temp_dirname_session =
"",
97 # define ASSERT_IS_INIT() BLI_assert(is_appdir_init)
99 # define ASSERT_IS_INIT() ((void)0)
138 static char version_str[5];
140 BLI_snprintf(version_str,
sizeof(version_str),
"%d.%02d", version / 100, version % 100);
165 return documentfolder;
198 if (documents_path &&
BLI_is_dir(documents_path)) {
212 BLI_path_join(try_documents_path,
sizeof(try_documents_path), home_path,
N_(
"Documents"),
NULL);
229 bool success =
false;
232 success = SHGetSpecialFolderPathW(0, wpath, CSIDL_FONTS, 0);
234 wcscat(wpath,
L"\\");
265 size_t targetpath_len,
266 const bool check_is_dir,
267 const char *path_base,
268 const char *folder_name,
269 const char *subfolder_name)
275 BLI_path_join(targetpath, targetpath_len, path_base, folder_name, subfolder_name,
NULL);
276 if (check_is_dir ==
false) {
277 CLOG_INFO(&
LOG, 3,
"using without test: '%s'", targetpath);
290 targetpath[0] =
'\0';
302 static bool test_env_path(
char *path,
const char *envvar,
const bool check_is_dir)
313 if (check_is_dir ==
false) {
314 CLOG_INFO(&
LOG, 3,
"using env '%s' without test: '%s'", envvar, env_path);
319 CLOG_INFO(&
LOG, 3,
"env '%s' found: %s", envvar, env_path);
323 CLOG_INFO(&
LOG, 3,
"env '%s' missing: %s", envvar, env_path);
344 size_t targetpath_len,
345 const char *folder_name,
346 const char *subfolder_name,
348 const bool check_is_dir)
354 "folder='%s', subfolder='%s'",
367 const char *path_base =
g_app.program_dirname;
372 BLI_snprintf(osx_resourses,
sizeof(osx_resourses),
"%s../Resources",
g_app.program_dirname);
375 path_base = osx_resourses;
385 size_t targetpath_len,
386 const char *folder_name,
387 const char *subfolder_name)
390 const bool check_is_dir =
true;
392 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
416 size_t targetpath_len,
417 const char *subfolder_name,
419 const bool check_is_dir)
425 return test_path(targetpath, targetpath_len, check_is_dir, user_path, subfolder_name,
NULL);
430 size_t targetpath_len,
431 const char *subfolder_name,
434 const bool check_is_dir =
true;
449 size_t targetpath_len,
450 const char *folder_name,
451 const char *subfolder_name,
453 const bool check_is_dir)
456 const char *user_base_path;
461 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
466 if (user_base_path) {
476 "'%s', folder='%s', subfolder='%s'",
483 targetpath, targetpath_len, check_is_dir, user_path, folder_name, subfolder_name);
486 size_t targetpath_len,
487 const char *folder_name,
488 const char *subfolder_name)
491 const bool check_is_dir =
true;
493 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
507 size_t targetpath_len,
508 const char *folder_name,
509 const char *subfolder_name,
511 const bool check_is_dir)
514 const char *system_base_path;
524 system_path[0] =
'\0';
526 if (system_base_path) {
530 if (!system_path[0]) {
536 "'%s', folder='%s', subfolder='%s'",
543 targetpath, targetpath_len, check_is_dir, system_path, folder_name, subfolder_name);
547 size_t targetpath_len,
548 const char *folder_name,
549 const char *subfolder_name)
552 const bool check_is_dir =
true;
554 targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
571 const char *subfolder,
690 const bool check_is_dir =
false;
695 path,
sizeof(path), subfolder,
"BLENDER_USER_DATAFILES", check_is_dir)) {
698 get_path_user_ex(path,
sizeof(path),
"datafiles", subfolder, version, check_is_dir);
702 path,
sizeof(path), subfolder,
"BLENDER_USER_CONFIG", check_is_dir)) {
705 get_path_user_ex(path,
sizeof(path),
"config", subfolder, version, check_is_dir);
709 path,
sizeof(path), subfolder,
"BLENDER_USER_AUTOSAVE", check_is_dir)) {
712 get_path_user_ex(path,
sizeof(path),
"autosave", subfolder, version, check_is_dir);
716 path,
sizeof(path), subfolder,
"BLENDER_USER_SCRIPTS", check_is_dir)) {
719 get_path_user_ex(path,
sizeof(path),
"scripts", subfolder, version, check_is_dir);
726 if (
'\0' == path[0]) {
766 const bool check_is_dir)
786 return ok ? path :
NULL;
809 static void where_am_i(
char *fullname,
const size_t maxlen,
const char *name)
814 const char *path =
NULL;
815 path = br_find_exe(
NULL);
826 wchar_t *fullname_16 =
MEM_mallocN(maxlen *
sizeof(
wchar_t),
"ProgramPath");
827 if (GetModuleFileNameW(0, fullname_16, maxlen)) {
830 CLOG_ERROR(&
LOG,
"path can't be found: \"%.*s\"", (
int)maxlen, fullname);
832 NULL,
"path contains invalid characters or is too long (see console)",
"Error", MB_OK);
843 if (name && name[0]) {
846 if (name[0] ==
'.') {
849 BLI_path_program_extensions_add_win32(fullname, maxlen);
856 BLI_path_program_extensions_add_win32(fullname, maxlen);
866 if (!
STREQ(name, fullname)) {
867 CLOG_INFO(&
LOG, 2,
"guessing '%s' == '%s'", name, fullname);
885 return g_app.program_filename;
894 return g_app.program_dirname;
898 const size_t fullpath_len,
899 const int version_major,
900 const int version_minor)
904 #ifdef PYTHON_EXECUTABLE_NAME
906 const char *python_build_def =
STRINGIFY(PYTHON_EXECUTABLE_NAME);
909 #if defined(WIN32) && !defined(NDEBUG)
910 const char *basename_debug =
"python_d";
912 char python_version[16];
914 const char *python_names[] = {
915 #ifdef PYTHON_EXECUTABLE_NAME
918 #if defined(WIN32) && !defined(NDEBUG)
924 bool is_found =
false;
926 SNPRINTF(python_version,
"%s%d.%d",
basename, version_major, version_minor);
930 if (python_bin_dir) {
932 for (
int i = 0; i <
ARRAY_SIZE(python_names); i++) {
937 BLI_path_program_extensions_add_win32(fullpath, fullpath_len)
949 if (is_found ==
false) {
950 for (
int i = 0; i <
ARRAY_SIZE(python_names); i++) {
958 if (is_found ==
false) {
973 "startup" SEP_STR "bl_app_templates_user",
974 "startup" SEP_STR "bl_app_templates_system",
1023 app_template, app_template_path,
sizeof(app_template_path))) {
1048 for (
int f = 0; f < totfile; f++) {
1076 static void where_is_temp(
char *tempdir,
const size_t tempdir_len,
const char *userdir)
1085 if (tempdir[0] ==
'\0') {
1086 const char *env_vars[] = {
1096 for (
int i = 0; i <
ARRAY_SIZE(env_vars); i++) {
1098 if (tmp && (tmp[0] !=
'\0') &&
BLI_is_dir(tmp)) {
1105 if (tempdir[0] ==
'\0') {
1115 const size_t tempdir_session_len,
1116 const char *tempdir)
1118 tempdir_session[0] =
'\0';
1120 const int tempdir_len = strlen(tempdir);
1122 const char *session_name =
"blender_XXXXXX";
1123 const int session_name_len = strlen(session_name);
1127 const int tempdir_session_len_required = tempdir_len + session_name_len + 1;
1129 if (tempdir_session_len_required <= tempdir_session_len) {
1131 BLI_string_join(tempdir_session, tempdir_session_len, tempdir, session_name);
1133 const bool needs_create = (_mktemp_s(tempdir_session, tempdir_session_len_required) == 0);
1135 const bool needs_create = (mkdtemp(tempdir_session) ==
NULL);
1148 "Could not generate a temp file name for '%s', falling back to '%s'",
1151 BLI_strncpy(tempdir_session, tempdir, tempdir_session_len);
1168 g_app.temp_dirname_session,
sizeof(
g_app.temp_dirname_session),
g_app.temp_dirname_base);
1184 return g_app.temp_dirname_base;
@ BLENDER_SYSTEM_DATAFILES
#define BLENDER_USERPREF_FILE
@ BLENDER_RESOURCE_PATH_SYSTEM
@ BLENDER_RESOURCE_PATH_LOCAL
@ BLENDER_RESOURCE_PATH_USER
#define BLI_assert_unreachable()
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries)
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()
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, const size_t dirlen)
bool BLI_path_program_search(char *fullname, const size_t maxlen, const char *name)
void BLI_path_normalize(const char *relabase, char *path) ATTR_NONNULL(2)
bool BLI_path_abs_from_cwd(char *path, const size_t maxlen) ATTR_NONNULL()
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
#define FILENAME_IS_CURRPAR(_n)
size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
const char * BLI_getenv(const char *env) ATTR_NONNULL(1)
int BLI_path_slash_ensure(char *string) ATTR_NONNULL()
const char * BLI_path_slash_rfind(const char *string) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
#define SNPRINTF(dst, format,...)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxncpy) ATTR_NONNULL()
#define BLI_string_join(result, result_len,...)
Compatibility-like things for windows.
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
const GHOST_TUns8 * GHOST_getUserDir(int version, const char *versionstr)
const GHOST_TUns8 * GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type)
const GHOST_TUns8 * GHOST_getSystemDir(int version, const char *versionstr)
@ 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(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)
char program_filename[FILE_MAX]
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)
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)
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]
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)
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8)