BLI_path: remove trailing NULL argument to BLI_path_join

Using varargs had the disadvantages, replace with a macro which has
some advantages.

- Arguments are type checked.
- Less verbose.
- Unintended NULL arguments would silently terminate joining paths.
- Passing in a NULL argument warns with GCC.
This commit is contained in:
Campbell Barton 2022-10-17 11:16:41 +11:00
parent 2f3f208901
commit 1d1cade9a9
23 changed files with 184 additions and 111 deletions

View File

@ -1507,13 +1507,9 @@ bool MANTA::bakeData(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
BLI_path_join(cacheDirData, sizeof(cacheDirData), fds->cache_directory, FLUID_DOMAIN_DIR_DATA);
BLI_path_join(
cacheDirData, sizeof(cacheDirData), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
BLI_path_join(cacheDirGuiding,
sizeof(cacheDirGuiding),
fds->cache_directory,
FLUID_DOMAIN_DIR_GUIDE,
nullptr);
cacheDirGuiding, sizeof(cacheDirGuiding), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_make_safe(cacheDirData);
BLI_path_make_safe(cacheDirGuiding);
@ -1540,7 +1536,7 @@ bool MANTA::bakeNoise(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
BLI_path_join(
cacheDirNoise, sizeof(cacheDirNoise), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, nullptr);
cacheDirNoise, sizeof(cacheDirNoise), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE);
BLI_path_make_safe(cacheDirNoise);
ss.str("");
@ -1566,8 +1562,7 @@ bool MANTA::bakeMesh(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
string mesh_format = getCacheFileEnding(fds->cache_mesh_format);
BLI_path_join(
cacheDirMesh, sizeof(cacheDirMesh), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, nullptr);
BLI_path_join(cacheDirMesh, sizeof(cacheDirMesh), fds->cache_directory, FLUID_DOMAIN_DIR_MESH);
BLI_path_make_safe(cacheDirMesh);
ss.str("");
@ -1596,8 +1591,7 @@ bool MANTA::bakeParticles(FluidModifierData *fmd, int framenr)
BLI_path_join(cacheDirParticles,
sizeof(cacheDirParticles),
fds->cache_directory,
FLUID_DOMAIN_DIR_PARTICLES,
nullptr);
FLUID_DOMAIN_DIR_PARTICLES);
BLI_path_make_safe(cacheDirParticles);
ss.str("");
@ -1623,11 +1617,8 @@ bool MANTA::bakeGuiding(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
string resumable_cache = !(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
BLI_path_join(cacheDirGuiding,
sizeof(cacheDirGuiding),
fds->cache_directory,
FLUID_DOMAIN_DIR_GUIDE,
nullptr);
BLI_path_join(
cacheDirGuiding, sizeof(cacheDirGuiding), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_make_safe(cacheDirGuiding);
ss.str("");
@ -1678,13 +1669,11 @@ bool MANTA::exportSmokeScript(FluidModifierData *fmd)
FluidDomainSettings *fds = fmd->domain;
BLI_path_join(
cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
BLI_path_join(cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_make_safe(cacheDir);
/* Create 'script' subdir if it does not exist already */
BLI_dir_create_recursive(cacheDir);
BLI_path_join(
cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_SMOKE_SCRIPT, nullptr);
BLI_path_join(cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_SMOKE_SCRIPT);
BLI_path_make_safe(cacheDir);
bool noise = fds->flags & FLUID_DOMAIN_USE_NOISE;
@ -1791,13 +1780,11 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
FluidDomainSettings *fds = fmd->domain;
BLI_path_join(
cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
BLI_path_join(cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_make_safe(cacheDir);
/* Create 'script' subdir if it does not exist already */
BLI_dir_create_recursive(cacheDir);
BLI_path_join(
cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_LIQUID_SCRIPT, nullptr);
BLI_path_join(cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_LIQUID_SCRIPT);
BLI_path_make_safe(cacheDirScript);
bool mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
@ -2323,8 +2310,7 @@ bool MANTA::hasGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
string MANTA::getDirectory(FluidModifierData *fmd, string subdirectory)
{
char directory[FILE_MAX];
BLI_path_join(
directory, sizeof(directory), fmd->domain->cache_directory, subdirectory.c_str(), nullptr);
BLI_path_join(directory, sizeof(directory), fmd->domain->cache_directory, subdirectory.c_str());
BLI_path_make_safe(directory);
return directory;
}

View File

@ -191,7 +191,7 @@ bool BKE_appdir_folder_documents(char *dir)
char try_documents_path[FILE_MAXDIR];
/* Own attempt at getting a valid Documents path. */
BLI_path_join(try_documents_path, sizeof(try_documents_path), home_path, N_("Documents"), NULL);
BLI_path_join(try_documents_path, sizeof(try_documents_path), home_path, N_("Documents"));
if (!BLI_is_dir(try_documents_path)) {
return false;
}
@ -214,11 +214,11 @@ bool BKE_appdir_folder_caches(char *r_path, const size_t path_len)
#ifdef WIN32
BLI_path_join(
r_path, path_len, caches_root_path, "Blender Foundation", "Blender", "Cache", SEP_STR, NULL);
r_path, path_len, caches_root_path, "Blender Foundation", "Blender", "Cache", SEP_STR);
#elif defined(__APPLE__)
BLI_path_join(r_path, path_len, caches_root_path, "Blender", SEP_STR, NULL);
BLI_path_join(r_path, path_len, caches_root_path, "Blender", SEP_STR);
#else /* __linux__ */
BLI_path_join(r_path, path_len, caches_root_path, "blender", SEP_STR, NULL);
BLI_path_join(r_path, path_len, caches_root_path, "blender", SEP_STR);
#endif
return true;
@ -281,7 +281,9 @@ static bool test_path(char *targetpath,
/* Only the last argument should be NULL. */
BLI_assert(!(folder_name == NULL && (subfolder_name != NULL)));
BLI_path_join(targetpath, targetpath_len, path_base, folder_name, subfolder_name, NULL);
const char *path_array[] = {path_base, folder_name, subfolder_name};
const int path_array_num = (folder_name ? (subfolder_name ? 3 : 2) : 1);
BLI_path_join_array(targetpath, targetpath_len, path_array, path_array_num);
if (check_is_dir == false) {
CLOG_INFO(&LOG, 3, "using without test: '%s'", targetpath);
return true;
@ -365,7 +367,9 @@ static bool get_path_local_ex(char *targetpath,
STR_OR_FALLBACK(subfolder_name));
if (folder_name) { /* `subfolder_name` may be NULL. */
BLI_path_join(relfolder, sizeof(relfolder), folder_name, subfolder_name, NULL);
const char *path_array[] = {folder_name, subfolder_name};
const int path_array_num = subfolder_name ? 2 : 1;
BLI_path_join_array(relfolder, sizeof(relfolder), path_array, path_array_num);
}
else {
relfolder[0] = '\0';
@ -379,8 +383,7 @@ static bool get_path_local_ex(char *targetpath,
* we must move the blender_version dir with contents to Resources.
* Add 4 + 9 for the temporary `/../` path & `Resources`. */
char osx_resourses[FILE_MAX + 4 + 9];
BLI_path_join(
osx_resourses, sizeof(osx_resourses), g_app.program_dirname, "..", "Resources", NULL);
BLI_path_join(osx_resourses, sizeof(osx_resourses), g_app.program_dirname, "..", "Resources");
/* Remove the '/../' added above. */
BLI_path_normalize(NULL, osx_resourses);
path_base = osx_resourses;
@ -525,7 +528,9 @@ static bool get_path_system_ex(char *targetpath,
char relfolder[FILE_MAX];
if (folder_name) { /* `subfolder_name` may be NULL. */
BLI_path_join(relfolder, sizeof(relfolder), folder_name, subfolder_name, NULL);
const char *path_array[] = {folder_name, subfolder_name};
const int path_array_num = subfolder_name ? 2 : 1;
BLI_path_join_array(relfolder, sizeof(relfolder), path_array, path_array_num);
}
else {
relfolder[0] = '\0';
@ -1041,8 +1046,7 @@ bool BKE_appdir_app_template_has_userpref(const char *app_template)
}
char userpref_path[FILE_MAX];
BLI_path_join(
userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE, NULL);
BLI_path_join(userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE);
return BLI_exists(userpref_path);
}

View File

@ -515,8 +515,7 @@ CatalogFilePath AssetCatalogService::find_suitable_cdf_path_for_writing(
BLI_path_join(asset_lib_cdf_path,
sizeof(asset_lib_cdf_path),
suitable_root_path,
DEFAULT_CATALOG_FILENAME.c_str(),
nullptr);
DEFAULT_CATALOG_FILENAME.c_str());
return asset_lib_cdf_path;
}

View File

@ -737,7 +737,7 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) {
bool ok_write;
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE);
printf("Writing userprefs: '%s' ", filepath);
if (use_template_userpref) {
@ -764,7 +764,7 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
if (use_template_userpref) {
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, U.app_template))) {
/* Also save app-template prefs */
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE);
printf("Writing userprefs app-template: '%s' ", filepath);
if (BKE_blendfile_userdef_write(filepath, reports) != 0) {

View File

@ -327,17 +327,17 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
if (cache_map & FLUID_DOMAIN_OUTDATED_DATA) {
flags &= ~(FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
}
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
}
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@ -346,7 +346,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
}
if (cache_map & FLUID_DOMAIN_OUTDATED_NOISE) {
flags &= ~(FLUID_DOMAIN_BAKING_NOISE | FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@ -355,7 +355,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
}
if (cache_map & FLUID_DOMAIN_OUTDATED_MESH) {
flags &= ~(FLUID_DOMAIN_BAKING_MESH | FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@ -365,8 +365,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
if (cache_map & FLUID_DOMAIN_OUTDATED_PARTICLES) {
flags &= ~(FLUID_DOMAIN_BAKING_PARTICLES | FLUID_DOMAIN_BAKED_PARTICLES |
FLUID_DOMAIN_OUTDATED_PARTICLES);
BLI_path_join(
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@ -375,7 +374,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
}
if (cache_map & FLUID_DOMAIN_OUTDATED_GUIDE) {
flags &= ~(FLUID_DOMAIN_BAKING_GUIDE | FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);

View File

@ -175,12 +175,12 @@ bool BKE_image_save_options_init(ImageSaveOptions *opts,
BLI_strncpy(opts->filepath, G.ima, sizeof(opts->filepath));
}
else {
BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", DATA_("untitled"), nullptr);
BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", DATA_("untitled"));
BLI_path_abs(opts->filepath, BKE_main_blendfile_path(bmain));
}
}
else {
BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", ima->id.name + 2, nullptr);
BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", ima->id.name + 2);
BLI_path_make_safe(opts->filepath);
BLI_path_abs(opts->filepath, is_prev_save ? G.ima : BKE_main_blendfile_path(bmain));
}

View File

@ -545,7 +545,7 @@ static void unpack_generate_paths(const char *name,
break;
}
if (dir_name) {
BLI_path_join(r_relpath, relpathlen, "//", dir_name, tempname, NULL);
BLI_path_join(r_relpath, relpathlen, "//", dir_name, tempname);
}
}

View File

@ -115,8 +115,7 @@ void BKE_preferences_asset_library_default_add(UserDef *userdef)
userdef, DATA_(BKE_PREFS_ASSET_LIBRARY_DEFAULT_NAME), NULL);
/* Add new "Default" library under '[doc_path]/Blender/Assets'. */
BLI_path_join(
library->path, sizeof(library->path), documents_path, N_("Blender"), N_("Assets"), NULL);
BLI_path_join(library->path, sizeof(library->path), documents_path, N_("Blender"), N_("Assets"));
}
/** \} */

View File

@ -7,7 +7,9 @@
*/
#include "BLI_compiler_attrs.h"
#include "BLI_compiler_compat.h"
#include "BLI_utildefines.h"
#include "BLI_utildefines_variadic.h"
#ifdef __cplusplus
extern "C" {
@ -80,6 +82,14 @@ void BLI_join_dirfile(char *__restrict dst,
size_t maxlen,
const char *__restrict dir,
const char *__restrict file) ATTR_NONNULL();
/**
* See #BLI_path_join doc-string.
*/
size_t BLI_path_join_array(char *__restrict dst,
const size_t dst_len,
const char *path_array[],
const int path_array_num);
/**
* Join multiple strings into a path, ensuring only a single path separator between each,
* and trailing slash is kept.
@ -95,8 +105,94 @@ void BLI_join_dirfile(char *__restrict dst,
* \note If you want a trailing slash, add `SEP_STR` as the last path argument,
* duplicate slashes will be cleaned up.
*/
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path, ...)
ATTR_NONNULL(1, 3) ATTR_SENTINEL(0);
#define BLI_path_join(...) VA_NARGS_CALL_OVERLOAD(_BLI_path_join_, __VA_ARGS__)
#define _BLI_PATH_JOIN_ARGS_1 char *__restrict dst, size_t dst_len, const char *a
#define _BLI_PATH_JOIN_ARGS_2 _BLI_PATH_JOIN_ARGS_1, const char *b
#define _BLI_PATH_JOIN_ARGS_3 _BLI_PATH_JOIN_ARGS_2, const char *c
#define _BLI_PATH_JOIN_ARGS_4 _BLI_PATH_JOIN_ARGS_3, const char *d
#define _BLI_PATH_JOIN_ARGS_5 _BLI_PATH_JOIN_ARGS_4, const char *e
#define _BLI_PATH_JOIN_ARGS_6 _BLI_PATH_JOIN_ARGS_5, const char *f
#define _BLI_PATH_JOIN_ARGS_7 _BLI_PATH_JOIN_ARGS_6, const char *g
#define _BLI_PATH_JOIN_ARGS_8 _BLI_PATH_JOIN_ARGS_7, const char *h
#define _BLI_PATH_JOIN_ARGS_9 _BLI_PATH_JOIN_ARGS_8, const char *i
#define _BLI_PATH_JOIN_ARGS_10 _BLI_PATH_JOIN_ARGS_9, const char *j
#define _BLI_PATH_JOIN_ARGS_11 _BLI_PATH_JOIN_ARGS_10, const char *k
BLI_INLINE size_t _BLI_path_join_3(_BLI_PATH_JOIN_ARGS_1) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_4(_BLI_PATH_JOIN_ARGS_2) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_5(_BLI_PATH_JOIN_ARGS_3) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_6(_BLI_PATH_JOIN_ARGS_4) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_7(_BLI_PATH_JOIN_ARGS_5) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_8(_BLI_PATH_JOIN_ARGS_6) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_9(_BLI_PATH_JOIN_ARGS_7) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_10(_BLI_PATH_JOIN_ARGS_8) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_11(_BLI_PATH_JOIN_ARGS_9) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_12(_BLI_PATH_JOIN_ARGS_10) ATTR_NONNULL();
BLI_INLINE size_t _BLI_path_join_3(_BLI_PATH_JOIN_ARGS_1)
{
const char *path_array[] = {a};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_4(_BLI_PATH_JOIN_ARGS_2)
{
const char *path_array[] = {a, b};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_5(_BLI_PATH_JOIN_ARGS_3)
{
const char *path_array[] = {a, b, c};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_6(_BLI_PATH_JOIN_ARGS_4)
{
const char *path_array[] = {a, b, c, d};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_7(_BLI_PATH_JOIN_ARGS_5)
{
const char *path_array[] = {a, b, c, d, e};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_8(_BLI_PATH_JOIN_ARGS_6)
{
const char *path_array[] = {a, b, c, d, e, f};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_9(_BLI_PATH_JOIN_ARGS_7)
{
const char *path_array[] = {a, b, c, d, e, f, g};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_10(_BLI_PATH_JOIN_ARGS_8)
{
const char *path_array[] = {a, b, c, d, e, f, g, h};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_11(_BLI_PATH_JOIN_ARGS_9)
{
const char *path_array[] = {a, b, c, d, e, f, g, h, i};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
BLI_INLINE size_t _BLI_path_join_12(_BLI_PATH_JOIN_ARGS_10)
{
const char *path_array[] = {a, b, c, d, e, f, g, h, i, j};
return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
}
#undef _BLI_PATH_JOIN_ARGS_1
#undef _BLI_PATH_JOIN_ARGS_2
#undef _BLI_PATH_JOIN_ARGS_3
#undef _BLI_PATH_JOIN_ARGS_4
#undef _BLI_PATH_JOIN_ARGS_5
#undef _BLI_PATH_JOIN_ARGS_6
#undef _BLI_PATH_JOIN_ARGS_7
#undef _BLI_PATH_JOIN_ARGS_8
#undef _BLI_PATH_JOIN_ARGS_9
#undef _BLI_PATH_JOIN_ARGS_10
#undef _BLI_PATH_JOIN_ARGS_11
/**
* Like Python's `os.path.basename()`
*

View File

@ -1490,14 +1490,20 @@ void BLI_join_dirfile(char *__restrict dst,
BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path, ...)
size_t BLI_path_join_array(char *__restrict dst,
const size_t dst_len,
const char *path_array[],
const int path_array_num)
{
BLI_assert(path_array_num > 0);
#ifdef DEBUG_STRSIZE
memset(dst, 0xff, sizeof(*dst) * dst_len);
#endif
if (UNLIKELY(dst_len == 0)) {
return 0;
}
const char *path = path_array[0];
const size_t dst_last = dst_len - 1;
size_t ofs = BLI_strncpy_rlen(dst, path, dst_len);
@ -1519,9 +1525,8 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
has_trailing_slash = (path[len] != '\0');
}
va_list args;
va_start(args, path);
while ((path = (const char *)va_arg(args, const char *))) {
for (int path_index = 1; path_index < path_array_num; path_index++) {
path = path_array[path_index];
has_trailing_slash = false;
const char *path_init = path;
while (ELEM(path[0], SEP, ALTSEP)) {
@ -1556,7 +1561,6 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
has_trailing_slash = (path_init != path);
}
}
va_end(args);
if (has_trailing_slash) {
if ((ofs != dst_last) && (ofs != 0) && (ELEM(dst[ofs - 1], SEP, ALTSEP) == 0)) {

View File

@ -207,7 +207,7 @@ TEST(path_util, NameAtIndex_NoneComplexNeg)
char result[(out_size) + 1024]; \
/* check we don't write past the last byte */ \
result[out_size] = '\0'; \
BLI_path_join(result, out_size, __VA_ARGS__, NULL); \
BLI_path_join(result, out_size, __VA_ARGS__); \
/* simplify expected string */ \
BLI_str_replace_char(result, '\\', '/'); \
EXPECT_STREQ(result, expect); \

View File

@ -117,7 +117,7 @@ bool BlendfileLoadingBaseTest::blendfile_load(const char *filepath)
}
char abspath[FILENAME_MAX];
BLI_path_join(abspath, sizeof(abspath), test_assets_dir.c_str(), filepath, nullptr);
BLI_path_join(abspath, sizeof(abspath), test_assets_dir.c_str(), filepath);
BlendFileReadReport bf_reports = {nullptr};
bfile = BLO_read_from_file(abspath, BLO_READ_SKIP_NONE, &bf_reports);

View File

@ -368,7 +368,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
BKE_spacedata_draw_locks(true);
if (fluid_is_bake_noise(job) || fluid_is_bake_all(job)) {
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'noise' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
@ -376,7 +376,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_noise;
}
if (fluid_is_bake_mesh(job) || fluid_is_bake_all(job)) {
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'mesh' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
@ -384,8 +384,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_mesh;
}
if (fluid_is_bake_particle(job) || fluid_is_bake_all(job)) {
BLI_path_join(
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES);
BLI_path_abs(temp_dir, relbase);
/* Create 'particles' subdir if it does not exist already */
@ -396,7 +395,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_particles;
}
if (fluid_is_bake_guiding(job) || fluid_is_bake_all(job)) {
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'guiding' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
@ -404,11 +403,11 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_guide;
}
if (fluid_is_bake_data(job) || fluid_is_bake_all(job)) {
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'config' subdir if it does not exist already */
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'data' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
@ -416,8 +415,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_data;
if (fds->flags & FLUID_DOMAIN_EXPORT_MANTA_SCRIPT) {
BLI_path_join(
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'script' subdir if it does not exist already */
}

View File

@ -2457,8 +2457,7 @@ static void file_expand_directory(bContext *C)
else if (params->dir[0] == '~') {
char tmpstr[sizeof(params->dir) - 1];
BLI_strncpy(tmpstr, params->dir + 1, sizeof(tmpstr));
BLI_path_join(
params->dir, sizeof(params->dir), BKE_appdir_folder_default_or_root(), tmpstr, NULL);
BLI_path_join(params->dir, sizeof(params->dir), BKE_appdir_folder_default_or_root(), tmpstr);
}
else if (params->dir[0] == '\0')

View File

@ -113,10 +113,10 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
char filepath[FILE_MAX];
const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home != NULL) {
BLI_path_join(filepath, sizeof(filepath), xdg_config_home, "user-dirs.dirs", NULL);
BLI_path_join(filepath, sizeof(filepath), xdg_config_home, "user-dirs.dirs");
}
else {
BLI_path_join(filepath, sizeof(filepath), home, ".config", "user-dirs.dirs", NULL);
BLI_path_join(filepath, sizeof(filepath), home, ".config", "user-dirs.dirs");
}
fp = BLI_fopen(filepath, "r");
if (!fp) {
@ -147,7 +147,7 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
* Based on the 'user-dirs.dirs' man page,
* there is no need to resolve arbitrary environment variables. */
if (STRPREFIX(l_value, "$HOME" SEP_STR)) {
BLI_path_join(l_value_expanded, sizeof(l_value_expanded), home, l_value + 6, NULL);
BLI_path_join(l_value_expanded, sizeof(l_value_expanded), home, l_value + 6);
l_value_final = l_value_expanded;
}
@ -186,7 +186,7 @@ static void fsmenu_xdg_insert_entry(GHash *xdg_map,
char xdg_path_buf[FILE_MAXDIR];
const char *xdg_path = xdg_map ? BLI_ghash_lookup(xdg_map, key) : NULL;
if (xdg_path == NULL) {
BLI_path_join(xdg_path_buf, sizeof(xdg_path_buf), home, default_path, NULL);
BLI_path_join(xdg_path_buf, sizeof(xdg_path_buf), home, default_path);
xdg_path = xdg_path_buf;
}
fsmenu_insert_entry(

View File

@ -374,7 +374,7 @@ void unpack_menu(bContext *C,
char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
BLI_split_file_part(abs_name, fi, sizeof(fi));
BLI_path_join(local_name, sizeof(local_name), "//", folder, fi, NULL);
BLI_path_join(local_name, sizeof(local_name), "//", folder, fi);
if (!STREQ(abs_name, local_name)) {
switch (BKE_packedfile_compare_to_file(blendfile_path, local_name, pf)) {
case PF_CMP_NOFILE:

View File

@ -28,8 +28,7 @@ std::string path_reference(StringRefNull filepath,
}
else if (mode == PATH_REFERENCE_COPY) {
char filepath_cpy[PATH_MAX];
BLI_path_join(
filepath_cpy, PATH_MAX, base_dst.c_str(), BLI_path_basename(filepath_abs), nullptr);
BLI_path_join(filepath_cpy, PATH_MAX, base_dst.c_str(), BLI_path_basename(filepath_abs));
copy_set->add(std::make_pair(filepath_abs, filepath_cpy));
BLI_strncpy(filepath_abs, filepath_cpy, PATH_MAX);
mode = PATH_REFERENCE_RELATIVE;

View File

@ -380,7 +380,7 @@ static void export_in_memory_texture(Image *ima,
BKE_image_path_ensure_ext_from_imformat(file_name, &imageFormat);
char export_path[FILE_MAX];
BLI_path_join(export_path, FILE_MAX, export_dir.c_str(), file_name, nullptr);
BLI_path_join(export_path, FILE_MAX, export_dir.c_str(), file_name);
if (!allow_overwrite && BLI_exists(export_path)) {
return;
@ -576,7 +576,7 @@ static std::string get_tex_image_asset_path(bNode *node,
BLI_split_file_part(path.c_str(), file_path, FILE_MAX);
if (export_params.relative_paths) {
BLI_path_join(exp_path, FILE_MAX, ".", "textures", file_path, nullptr);
BLI_path_join(exp_path, FILE_MAX, ".", "textures", file_path);
}
else {
/* Create absolute path in the textures directory. */
@ -588,7 +588,7 @@ static std::string get_tex_image_asset_path(bNode *node,
char dir_path[FILE_MAX];
BLI_split_dir_part(stage_path.c_str(), dir_path, FILE_MAX);
BLI_path_join(exp_path, FILE_MAX, dir_path, "textures", file_path, nullptr);
BLI_path_join(exp_path, FILE_MAX, dir_path, "textures", file_path);
}
BLI_str_replace_char(exp_path, '\\', '/');
return exp_path;
@ -645,7 +645,7 @@ static void copy_tiled_textures(Image *ima,
BLI_split_file_part(src_tile_path, dest_filename, sizeof(dest_filename));
char dest_tile_path[FILE_MAX];
BLI_path_join(dest_tile_path, FILE_MAX, dest_dir.c_str(), dest_filename, nullptr);
BLI_path_join(dest_tile_path, FILE_MAX, dest_dir.c_str(), dest_filename);
if (!allow_overwrite && BLI_exists(dest_tile_path)) {
continue;
@ -680,7 +680,7 @@ static void copy_single_file(Image *ima, const std::string &dest_dir, const bool
BLI_split_file_part(source_path, file_name, FILE_MAX);
char dest_path[FILE_MAX];
BLI_path_join(dest_path, FILE_MAX, dest_dir.c_str(), file_name, nullptr);
BLI_path_join(dest_path, FILE_MAX, dest_dir.c_str(), file_name);
if (!allow_overwrite && BLI_exists(dest_path)) {
return;
@ -726,7 +726,7 @@ static void export_texture(bNode *node,
BLI_split_dir_part(stage_path.c_str(), usd_dir_path, FILE_MAX);
char tex_dir_path[FILE_MAX];
BLI_path_join(tex_dir_path, FILE_MAX, usd_dir_path, "textures", SEP_STR, nullptr);
BLI_path_join(tex_dir_path, FILE_MAX, usd_dir_path, "textures", SEP_STR);
BLI_dir_create_recursive(tex_dir_path);

View File

@ -152,7 +152,7 @@ std::optional<std::string> USDVolumeWriter::construct_vdb_file_path(const Volume
strcat(vdb_file_name, ".vdb");
char vdb_file_path[FILE_MAX];
BLI_path_join(vdb_file_path, sizeof(vdb_file_path), vdb_directory_path, vdb_file_name, nullptr);
BLI_path_join(vdb_file_path, sizeof(vdb_file_path), vdb_directory_path, vdb_file_name);
return vdb_file_path;
}

View File

@ -29,7 +29,7 @@ std::string register_usd_plugins_for_tests()
}
const size_t path_len = BLI_path_join(
usd_datafiles_dir, FILE_MAX, release_dir.c_str(), "datafiles", "usd", nullptr);
usd_datafiles_dir, FILE_MAX, release_dir.c_str(), "datafiles", "usd");
/* #BLI_path_join removes trailing slashes, but the USD library requires one in order to
* recognize the path as directory. */

View File

@ -765,7 +765,7 @@ MTLParser::MTLParser(StringRefNull mtl_library, StringRefNull obj_filepath)
{
char obj_file_dir[FILE_MAXDIR];
BLI_split_dir_part(obj_filepath.data(), obj_file_dir, FILE_MAXDIR);
BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data(), nullptr);
BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data());
BLI_split_dir_part(mtl_file_path_, mtl_dir_path_, FILE_MAXDIR);
}

View File

@ -1166,12 +1166,10 @@ void wm_homefile_read_ex(bContext *C,
const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (!use_factory_settings) {
if (cfgdir) {
BLI_path_join(
filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE, NULL);
BLI_path_join(filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE);
filepath_startup_is_factory = false;
if (use_userdef) {
BLI_path_join(
filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE, NULL);
BLI_path_join(filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE);
}
}
else {
@ -1214,12 +1212,9 @@ void wm_homefile_read_ex(bContext *C,
/* note that the path is being set even when 'use_factory_settings == true'
* this is done so we can load a templates factory-settings */
if (!use_factory_settings) {
BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template, NULL);
BLI_path_join(filepath_startup,
sizeof(filepath_startup),
app_template_config,
BLENDER_STARTUP_FILE,
NULL);
BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template);
BLI_path_join(
filepath_startup, sizeof(filepath_startup), app_template_config, BLENDER_STARTUP_FILE);
filepath_startup_is_factory = false;
if (BLI_access(filepath_startup, R_OK) != 0) {
filepath_startup[0] = '\0';
@ -1230,11 +1225,8 @@ void wm_homefile_read_ex(bContext *C,
}
if (filepath_startup[0] == '\0') {
BLI_path_join(filepath_startup,
sizeof(filepath_startup),
app_template_system,
BLENDER_STARTUP_FILE,
NULL);
BLI_path_join(
filepath_startup, sizeof(filepath_startup), app_template_system, BLENDER_STARTUP_FILE);
filepath_startup_is_factory = true;
/* Update defaults only for system templates. */
@ -1303,16 +1295,14 @@ void wm_homefile_read_ex(bContext *C,
char temp_path[FILE_MAX];
temp_path[0] = '\0';
if (!use_factory_settings) {
BLI_path_join(
temp_path, sizeof(temp_path), app_template_config, BLENDER_USERPREF_FILE, NULL);
BLI_path_join(temp_path, sizeof(temp_path), app_template_config, BLENDER_USERPREF_FILE);
if (BLI_access(temp_path, R_OK) != 0) {
temp_path[0] = '\0';
}
}
if (temp_path[0] == '\0') {
BLI_path_join(
temp_path, sizeof(temp_path), app_template_system, BLENDER_USERPREF_FILE, NULL);
BLI_path_join(temp_path, sizeof(temp_path), app_template_system, BLENDER_USERPREF_FILE);
}
if (use_userdef) {
@ -2132,7 +2122,7 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
/* update keymaps in user preferences */
WM_keyconfig_update(wm);
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_STARTUP_FILE, NULL);
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_STARTUP_FILE);
printf("Writing homefile: '%s' ", filepath);

View File

@ -218,7 +218,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSE
const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE, NULL);
BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE);
}
/* Draw setup screen if no preferences have been saved yet. */