Cleanup: Move blend file path utilities out of blenloader module #105825

Closed
Julian Eisel wants to merge 1 commits from JulianEisel:temp-bke-blend-file-utils into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
16 changed files with 129 additions and 129 deletions

View File

@ -19,6 +19,27 @@ struct ReportList;
struct UserDef;
struct bContext;
/**
* Check whether given path ends with a blend file compatible extension
* (`.blend`, `.ble` or `.blend.gz`).
*
* \param str: The path to check.
* \return true is this path ends with a blender file extension.
*/
bool BKE_has_bfile_extension(const char *str);
/**
* Try to explode given path into its 'library components'
* (i.e. a .blend file, id type/group, and data-block itself).
*
* \param path: the full path to explode.
* \param r_dir: the string that'll contain path up to blend file itself ('library' path).
* WARNING! Must be #FILE_MAX_LIBEXTRA long (it also stores group and name strings)!
Review

Must be at least #FILE_MAX_LIBEXTRA long

Must be at least #FILE_MAX_LIBEXTRA long
* \param r_group: the string that'll contain 'group' part of the path, if any. May be NULL.
* \param r_name: the string that'll contain data's name part of the path, if any. May be NULL.
Review

Should also document that r_group and r_name, if set, will point to sub-strings in r_dir.

Should also document that `r_group` and `r_name`, if set, will point to sub-strings in `r_dir`.
* \return true if path contains a blend file.
*/
bool BKE_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name);
/**
* Shared setup function that makes the data from `bfd` into the current blend file,
* replacing the contents of #G.main.

View File

@ -62,6 +62,78 @@
# include "BPY_extern.h"
#endif
/* -------------------------------------------------------------------- */
/** \name Blend/Library Paths
* \{ */
bool BKE_has_bfile_extension(const char *str)
{
const char *ext_test[4] = {".blend", ".ble", ".blend.gz", nullptr};
return BLI_path_extension_check_array(str, ext_test);
}
bool BKE_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name)
{
/* We might get some data names with slashes,
* so we have to go up in path until we find blend file itself,
* then we know next path item is group, and everything else is data name. */
char *slash = nullptr, *prev_slash = nullptr, c = '\0';
r_dir[0] = '\0';
if (r_group) {
*r_group = nullptr;
}
if (r_name) {
*r_name = nullptr;
}
/* if path leads to an existing directory, we can be sure we're not (in) a library */
if (BLI_is_dir(path)) {
return false;
}
strcpy(r_dir, path);
Review

Should use BLI_strncpy instead, since we expect r_dir to be FILE_MAX_LIBEXTRA long.

Should use `BLI_strncpy` instead, since we expect `r_dir` to be `FILE_MAX_LIBEXTRA` long.
while ((slash = (char *)BLI_path_slash_rfind(r_dir))) {
char tc = *slash;
*slash = '\0';
if (BKE_has_bfile_extension(r_dir) && BLI_is_file(r_dir)) {
break;
}
if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) {
break;
}
if (prev_slash) {
*prev_slash = c;
}
prev_slash = slash;
c = tc;
}
if (!slash) {
return false;
}
if (slash[1] != '\0') {
BLI_assert(strlen(slash + 1) < BLO_GROUP_MAX);
if (r_group) {
*r_group = slash + 1;
}
}
if (prev_slash && (prev_slash[1] != '\0')) {
BLI_assert(strlen(prev_slash + 1) < MAX_ID_NAME - 2);
if (r_name) {
*r_name = prev_slash + 1;
}
}
return true;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Blend File IO (High Level)
* \{ */

View File

@ -313,27 +313,6 @@ void BLO_read_invalidate_message(BlendHandle *bh, struct Main *bmain, const char
#define BLO_GROUP_MAX 32
#define BLO_EMBEDDED_STARTUP_BLEND "<startup.blend>"
/**
* Check whether given path ends with a blend file compatible extension
* (`.blend`, `.ble` or `.blend.gz`).
*
* \param str: The path to check.
* \return true is this path ends with a blender file extension.
*/
bool BLO_has_bfile_extension(const char *str);
/**
* Try to explode given path into its 'library components'
* (i.e. a .blend file, id type/group, and data-block itself).
*
* \param path: the full path to explode.
* \param r_dir: the string that'll contain path up to blend file itself ('library' path).
* WARNING! Must be #FILE_MAX_LIBEXTRA long (it also stores group and name strings)!
* \param r_group: the string that'll contain 'group' part of the path, if any. May be NULL.
* \param r_name: the string that'll contain data's name part of the path, if any. May be NULL.
* \return true if path contains a blend file.
*/
bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name);
/* -------------------------------------------------------------------- */
/** \name BLO Blend File Linking API
* \{ */

View File

@ -1306,76 +1306,6 @@ void blo_filedata_free(FileData *fd)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public Utilities
* \{ */
bool BLO_has_bfile_extension(const char *str)
{
const char *ext_test[4] = {".blend", ".ble", ".blend.gz", nullptr};
return BLI_path_extension_check_array(str, ext_test);
}
bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name)
{
/* We might get some data names with slashes,
* so we have to go up in path until we find blend file itself,
* then we know next path item is group, and everything else is data name. */
char *slash = nullptr, *prev_slash = nullptr, c = '\0';
r_dir[0] = '\0';
if (r_group) {
*r_group = nullptr;
}
if (r_name) {
*r_name = nullptr;
}
/* if path leads to an existing directory, we can be sure we're not (in) a library */
if (BLI_is_dir(path)) {
return false;
}
strcpy(r_dir, path);
while ((slash = (char *)BLI_path_slash_rfind(r_dir))) {
char tc = *slash;
*slash = '\0';
if (BLO_has_bfile_extension(r_dir) && BLI_is_file(r_dir)) {
break;
}
if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) {
break;
}
if (prev_slash) {
*prev_slash = c;
}
prev_slash = slash;
c = tc;
}
if (!slash) {
return false;
}
if (slash[1] != '\0') {
BLI_assert(strlen(slash + 1) < BLO_GROUP_MAX);
if (r_group) {
*r_group = slash + 1;
}
}
if (prev_slash && (prev_slash[1] != '\0')) {
BLI_assert(strlen(prev_slash + 1) < MAX_ID_NAME - 2);
if (r_name) {
*r_name = prev_slash + 1;
}
}
return true;
}
BlendThumbnail *BLO_thumbnail_from_file(const char *filepath)
{
FileData *fd;

View File

@ -9,10 +9,12 @@
#include "AS_asset_representation.h"
#include "AS_asset_representation.hh"
#include "DNA_space_types.h"
#include "BKE_blendfile.h"
#include "BLO_readfile.h"
#include "DNA_space_types.h"
#include "ED_asset_handle.h"
#include "WM_api.h"
@ -58,7 +60,7 @@ void ED_asset_handle_get_full_library_path(const AssetHandle *asset_handle,
return;
}
BLO_library_path_explode(asset_path.c_str(), r_full_lib_path, nullptr, nullptr);
BKE_library_path_explode(asset_path.c_str(), r_full_lib_path, nullptr, nullptr);
}
namespace blender::ed::asset {

View File

@ -39,6 +39,7 @@
#include "BLT_translation.h"
#include "BKE_action.h"
#include "BKE_blendfile.h"
#include "BKE_colorband.h"
#include "BKE_colortools.h"
#include "BKE_constraint.h"
@ -79,8 +80,6 @@
#include "WM_api.h"
#include "WM_types.h"
#include "BLO_readfile.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_view2d.h"
@ -6997,7 +6996,7 @@ int uiTemplateRecentFiles(uiLayout *layout, int rows)
uiItemFullO(layout,
"WM_OT_open_mainfile",
filename,
BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
BKE_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
nullptr,
WM_OP_INVOKE_DEFAULT,
0,

View File

@ -21,10 +21,9 @@
#include "BIF_glutil.h"
#include "BKE_blendfile.h"
#include "BKE_context.h"
#include "BLO_readfile.h"
#include "BLT_translation.h"
#include "BLF_api.h"
@ -142,7 +141,7 @@ static void file_but_enable_drag(uiBut *but,
else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
(file->typeflag & FILE_TYPE_ASSET) != 0) {
char blend_path[FILE_MAX_LIBEXTRA];
if (BLO_library_path_explode(path, blend_path, nullptr, nullptr)) {
if (BKE_library_path_explode(path, blend_path, nullptr, nullptr)) {
const int import_method = ED_fileselect_asset_import_method_get(sfile, file);
BLI_assert(import_method > -1);

View File

@ -11,9 +11,8 @@
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLO_readfile.h"
#include "BKE_appdir.h"
#include "BKE_blendfile.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
@ -2539,7 +2538,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
BLI_split_dirfile(
path, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
else if (BLO_library_path_explode(params->dir, tdir, &group, &name)) {
else if (BKE_library_path_explode(params->dir, tdir, &group, &name)) {
if (group) {
BLI_path_append(tdir, sizeof(tdir), group);
}
@ -2578,7 +2577,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
char tdir[FILE_MAX_LIBEXTRA];
/* If we are 'inside' a blend library, we cannot do anything... */
if (lastdir && BLO_library_path_explode(lastdir, tdir, NULL, NULL)) {
if (lastdir && BKE_library_path_explode(lastdir, tdir, NULL, NULL)) {
BLI_strncpy(params->dir, lastdir, sizeof(params->dir));
}
else {

View File

@ -9,8 +9,8 @@
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BKE_blendfile.h"
#include "BKE_context.h"
#include "BLO_readfile.h"
#include "ED_fileselect.h"
#include "ED_screen.h"
@ -37,5 +37,5 @@ void file_path_to_ui_path(const char *path, char *r_path, int max_size)
char tmp_path[PATH_MAX];
BLI_strncpy(tmp_path, path, sizeof(tmp_path));
BLI_path_slash_rstrip(tmp_path);
BLI_strncpy(r_path, BLO_has_bfile_extension(tmp_path) ? tmp_path : path, max_size);
BLI_strncpy(r_path, BKE_has_bfile_extension(tmp_path) ? tmp_path : path, max_size);
}

View File

@ -48,6 +48,7 @@
#endif
#include "BKE_asset.h"
#include "BKE_blendfile.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_icons.h"
@ -56,7 +57,6 @@
#include "BKE_main.h"
#include "BKE_main_idmap.h"
#include "BKE_preferences.h"
#include "BLO_readfile.h"
#include "DNA_asset_types.h"
#include "DNA_space_types.h"
@ -1353,7 +1353,7 @@ static bool filelist_checkdir_lib(FileList * /*filelist*/, char *r_dir, const bo
char *name;
const bool is_valid = (BLI_is_dir(r_dir) ||
(BLO_library_path_explode(r_dir, tdir, nullptr, &name) &&
(BKE_library_path_explode(r_dir, tdir, nullptr, &name) &&
BLI_is_file(tdir) && !name));
if (do_change && !is_valid) {
@ -1950,7 +1950,7 @@ static const char *fileentry_uiname(const char *root, FileListInternEntry *entry
char *group;
BLI_path_join(abspath, sizeof(abspath), root, relpath);
BLO_library_path_explode(abspath, buff, &group, &name);
BKE_library_path_explode(abspath, buff, &group, &name);
if (!name) {
name = group;
}
@ -2623,7 +2623,7 @@ int ED_path_extension_type(const char *path)
/* ATTENTION: Never return OR'ed bit-flags here, always return a single enum value! Some code
* using this may do `ELEM()`-like checks. */
if (BLO_has_bfile_extension(path)) {
if (BKE_has_bfile_extension(path)) {
return FILE_TYPE_BLENDER;
}
if (file_is_blend_backup(path)) {
@ -2885,7 +2885,7 @@ bool filelist_islibrary(FileList *filelist, char *dir, char **r_group)
if (filelist->asset_library) {
return true;
}
return BLO_library_path_explode(filelist->filelist.root, dir, r_group, nullptr);
return BKE_library_path_explode(filelist->filelist.root, dir, r_group, nullptr);
}
static int groupname_to_code(const char *group)
@ -3041,7 +3041,7 @@ static int filelist_readjob_list_dir(FileListReadJob *job_params,
}
if (!(entry->typeflag & FILE_TYPE_DIR)) {
if (do_lib && BLO_has_bfile_extension(target)) {
if (do_lib && BKE_has_bfile_extension(target)) {
/* If we are considering .blend files as libraries, promote them to directory status. */
entry->typeflag = FILE_TYPE_BLENDER;
/* prevent current file being used as acceptable dir */
@ -3234,7 +3234,7 @@ static std::optional<int> filelist_readjob_list_lib(FileListReadJob *job_params,
* will do a dir listing only when this function does not return any entries. */
/* TODO(jbakker): We should consider introducing its own function to detect if it is a lib and
* call it directly from `filelist_readjob_do` to increase readability. */
const bool is_lib = BLO_library_path_explode(root, dir, &group, nullptr);
const bool is_lib = BKE_library_path_explode(root, dir, &group, nullptr);
if (!is_lib) {
return std::nullopt;
}

View File

@ -13,9 +13,9 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLO_readfile.h"
#include "BLT_translation.h"
#include "BKE_blendfile.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_screen.h"
@ -202,7 +202,7 @@ static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
if (!BLI_listbase_is_empty(&G.recent_files)) {
for (recent = G.recent_files.first; (recent); recent = recent->next) {
const char *file = BLI_path_basename(recent->filepath);
const int icon = BLO_has_bfile_extension(file) ? ICON_FILE_BLEND : ICON_FILE_BACKUP;
const int icon = BKE_has_bfile_extension(file) ? ICON_FILE_BLEND : ICON_FILE_BACKUP;
PointerRNA ptr;
uiItemFullO(layout, "WM_OT_open_mainfile", file, icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
RNA_string_set(&ptr, "filepath", recent->filepath);

View File

@ -10,6 +10,8 @@
#include "MEM_guardedalloc.h"
#include "BKE_blendfile.h"
#include "BLI_fileops.h"
#include "BLI_ghash.h"
#include "BLI_hash_md5.h"
@ -22,8 +24,6 @@
#include "DNA_space_types.h" /* For FILE_MAX_LIBEXTRA */
#include "BLO_readfile.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_metadata.h"
@ -527,7 +527,7 @@ ImBuf *IMB_thumb_manage(const char *filepath, ThumbSize size, ThumbSource source
path = file_path = filepath;
if (source == THB_SOURCE_BLEND) {
if (BLO_library_path_explode(path, path_buff, &blen_group, &blen_id)) {
if (BKE_library_path_explode(path, path_buff, &blen_group, &blen_id)) {
if (blen_group) {
if (!blen_id) {
/* No preview for blen groups */

View File

@ -43,6 +43,7 @@
#include "PIL_time.h"
#include "BLO_readfile.h"
#include "BLT_translation.h"
#include "BLF_api.h"
@ -79,7 +80,6 @@
#include "BKE_undo_system.h"
#include "BKE_workspace.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h" /* to save from an undo memfile */
#include "BLO_writefile.h"
@ -3261,7 +3261,7 @@ static bool wm_save_mainfile_check(bContext * /*C*/, wmOperator *op)
{
char filepath[FILE_MAX];
RNA_string_get(op->ptr, "filepath", filepath);
if (!BLO_has_bfile_extension(filepath)) {
if (!BKE_has_bfile_extension(filepath)) {
/* some users would prefer BLI_path_extension_replace(),
* we keep getting nitpicking bug reports about this - campbell */
BLI_path_extension_ensure(filepath, FILE_MAX, ".blend");

View File

@ -37,6 +37,7 @@
#include "BLO_readfile.h"
#include "BKE_armature.h"
#include "BKE_blendfile.h"
#include "BKE_blendfile_link_append.h"
#include "BKE_context.h"
#include "BKE_global.h"
@ -216,7 +217,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BLI_path_join(path, sizeof(path), root, relname);
/* test if we have a valid data */
if (!BLO_library_path_explode(path, libname, &group, &name)) {
if (!BKE_library_path_explode(path, libname, &group, &name)) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path);
return OPERATOR_CANCELLED;
}
@ -289,7 +290,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BLI_path_join(path, sizeof(path), root, relname);
if (BLO_library_path_explode(path, libname, &group, &name)) {
if (BKE_library_path_explode(path, libname, &group, &name)) {
if (!wm_link_append_item_poll(NULL, path, group, name, do_append)) {
continue;
}
@ -308,7 +309,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BLI_path_join(path, sizeof(path), root, relname);
if (BLO_library_path_explode(path, libname, &group, &name)) {
if (BKE_library_path_explode(path, libname, &group, &name)) {
BlendfileLinkAppendContextItem *item;
if (!wm_link_append_item_poll(op->reports, path, group, name, do_append)) {
@ -610,7 +611,7 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN
void WM_lib_reload(Library *lib, bContext *C, ReportList *reports)
{
if (!BLO_has_bfile_extension(lib->filepath_abs)) {
if (!BKE_has_bfile_extension(lib->filepath_abs)) {
BKE_reportf(reports, RPT_ERROR, "'%s' is not a valid library filepath", lib->filepath_abs);
return;
}
@ -687,7 +688,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
RNA_string_get(op->ptr, "directory", root);
RNA_string_get(op->ptr, "filename", libname);
if (!BLO_has_bfile_extension(libname)) {
if (!BKE_has_bfile_extension(libname)) {
BKE_report(op->reports, RPT_ERROR, "Not a library");
return OPERATOR_CANCELLED;
}
@ -750,7 +751,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
BLI_path_join(path, sizeof(path), root, relname);
if (BLI_path_cmp(path, lib->filepath_abs) == 0 || !BLO_has_bfile_extension(relname)) {
if (BLI_path_cmp(path, lib->filepath_abs) == 0 || !BKE_has_bfile_extension(relname)) {
continue;
}

View File

@ -6,7 +6,6 @@ set(INC
../../intern/guardedalloc
../blender/blenkernel
../blender/blenlib
../blender/blenloader
../blender/depsgraph
../blender/editors/include
../blender/gpu

View File

@ -29,9 +29,8 @@
# include "BLI_threads.h"
# include "BLI_utildefines.h"
# include "BLO_readfile.h" /* only for BLO_has_bfile_extension */
# include "BKE_blender_version.h"
# include "BKE_blendfile.h"
# include "BKE_context.h"
# include "BKE_global.h"
@ -2071,7 +2070,7 @@ static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data)
return -1;
}
if (BLO_has_bfile_extension(filepath)) {
if (BKE_has_bfile_extension(filepath)) {
/* Just pretend a file was loaded, so the user can press Save and it'll
* save at the filepath from the CLI. */
STRNCPY(G_MAIN->filepath, filepath);