Merge branch 'blender-v3.6-release'

This commit is contained in:
Campbell Barton 2023-05-24 16:34:05 +10:00
commit b621c6ba07
3 changed files with 106 additions and 89 deletions

View File

@ -38,7 +38,17 @@ extern "C" {
* (most likely doesn't exist or no access).
*/
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
int BLI_copy(const char *file, const char *to) ATTR_NONNULL();
/**
* \return 0 on success.
*/
int BLI_copy(const char *path_src, const char *path_dst) ATTR_NONNULL();
/**
* When `path_src` points to a directory, moves all its contents into `path_dst`,
* else rename `path_src` itself to `path_dst`.
* \return 0 on success.
*/
int BLI_path_move(const char *path_src, const char *path_dst) ATTR_NONNULL();
/**
* Rename a file or directory.
@ -76,13 +86,8 @@ int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL();
* \return zero on success (matching 'remove' behavior).
*/
int BLI_delete_soft(const char *filepath, const char **error_message) ATTR_NONNULL();
/**
* When `path` points to a directory, moves all its contents into `to`,
* else rename `path` itself to `to`.
*/
int BLI_path_move(const char *path, const char *to) ATTR_NONNULL();
#if 0 /* Unused */
int BLI_create_symlink(const char *path, const char *to) ATTR_NONNULL();
int BLI_create_symlink(const char *path, const char *path_dst) ATTR_NONNULL();
#endif
/* Keep in sync with the definition of struct `direntry` in `BLI_fileops_types.h`. */

View File

@ -43,9 +43,13 @@
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
#include "BLI_sys_types.h" /* for intptr_t support */
#include "BLI_utildefines.h"
/** Sizes above this must be allocated. */
#define FILE_MAX_STATIC_BUF 256
#ifdef WIN32
/* Text string used as the "verb" for Windows shell operations. */
static char *windows_operation_string(FileExternalOperation operation)
@ -655,75 +659,93 @@ int BLI_delete_soft(const char *file, const char **error_message)
return err;
}
int BLI_path_move(const char *file, const char *to)
/**
* MS-Windows doesn't support moving to a directory, it has to be
* `mv filepath filepath` and not `mv filepath destination_directory` (same for copying).
*
* So when `path_dst` ends with as slash:
* ensure the filename component of `path_src` is added to a copy of `path_dst`.
*/
static const char *path_destination_ensure_filename(const char *path_src,
const char *path_dst,
char *buf,
size_t buf_size)
{
char str[MAXPATHLEN + 12];
int err;
/* windows doesn't support moving to a directory
* it has to be 'mv filepath filepath' and not
* 'mv filepath destination_directory' */
STRNCPY(str, to);
/* points 'to' to a directory ? */
if (BLI_path_slash_rfind(str) == (str + strlen(str) - 1)) {
if (BLI_path_slash_rfind(file) != NULL) {
strcat(str, BLI_path_slash_rfind(file) + 1);
const char *filename_src = BLI_path_basename(path_src);
/* Unlikely but possible this has no slashes. */
if (filename_src != path_src) {
const size_t path_dst_len = strlen(path_dst);
/* Check if `path_dst` points to a directory. */
if (path_dst_len && BLI_path_slash_is_native_compat(path_dst[path_dst_len - 1])) {
size_t buf_size_needed = path_dst_len + strlen(filename_src) + 1;
char *path_dst_with_filename = (buf_size_needed <= buf_size) ?
buf :
MEM_mallocN(buf_size_needed, __func__);
BLI_string_join(path_dst_with_filename, buf_size_needed, path_dst, filename_src);
return path_dst_with_filename;
}
}
return path_dst;
}
UTF16_ENCODE(file);
UTF16_ENCODE(str);
err = !MoveFileW(file_16, str_16);
UTF16_UN_ENCODE(str);
UTF16_UN_ENCODE(file);
int BLI_path_move(const char *path_src, const char *path_dst)
{
char path_dst_buf[FILE_MAX_STATIC_BUF];
const char *path_dst_with_filename = path_destination_ensure_filename(
path_src, path_dst, path_dst_buf, sizeof(path_dst_buf));
int err;
UTF16_ENCODE(path_src);
UTF16_ENCODE(path_dst_with_filename);
err = !MoveFileW(path_src_16, path_dst_with_filename_16);
UTF16_UN_ENCODE(path_dst_with_filename);
UTF16_UN_ENCODE(path_src);
if (err) {
callLocalErrorCallBack("Unable to move file");
printf(" Move from '%s' to '%s' failed\n", file, str);
printf(" Move from '%s' to '%s' failed\n", path_src, path_dst_with_filename);
}
if (!ELEM(path_dst_with_filename, path_dst_buf, path_dst)) {
MEM_freeN((void *)path_dst_with_filename);
}
return err;
}
int BLI_copy(const char *file, const char *to)
int BLI_copy(const char *path_src, const char *path_dst)
{
char str[MAXPATHLEN + 12];
char path_dst_buf[FILE_MAX_STATIC_BUF];
const char *path_dst_with_filename = path_destination_ensure_filename(
path_src, path_dst, path_dst_buf, sizeof(path_dst_buf));
int err;
/* windows doesn't support copying to a directory
* it has to be 'cp filepath filepath' and not
* 'cp filepath destdir' */
STRNCPY(str, to);
/* points 'to' to a directory ? */
if (BLI_path_slash_rfind(str) == (str + strlen(str) - 1)) {
if (BLI_path_slash_rfind(file) != NULL) {
strcat(str, BLI_path_slash_rfind(file) + 1);
}
}
UTF16_ENCODE(file);
UTF16_ENCODE(str);
err = !CopyFileW(file_16, str_16, false);
UTF16_UN_ENCODE(str);
UTF16_UN_ENCODE(file);
UTF16_ENCODE(path_src);
UTF16_ENCODE(path_dst_with_filename);
err = !CopyFileW(path_src_16, path_dst_with_filename_16, false);
UTF16_UN_ENCODE(path_dst_with_filename);
UTF16_UN_ENCODE(path_src);
if (err) {
callLocalErrorCallBack("Unable to copy file!");
printf(" Copy from '%s' to '%s' failed\n", file, str);
printf(" Copy from '%s' to '%s' failed\n", path_src, path_dst_with_filename);
}
if (!ELEM(path_dst_with_filename, path_dst_buf, path_dst)) {
MEM_freeN((void *)path_dst_with_filename);
}
return err;
}
# if 0
int BLI_create_symlink(const char *file, const char *to)
int BLI_create_symlink(const char *path_src, const char *path_dst)
{
/* See patch from #30870, should this ever become needed. */
callLocalErrorCallBack("Linking files is unsupported on Windows");
(void)file;
(void)to;
(void)path_src;
(void)path_dst;
return 1;
}
# endif
@ -1277,69 +1299,59 @@ static int move_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
int BLI_path_move(const char *path, const char *to)
int BLI_path_move(const char *path_src, const char *path_dst)
{
int ret = recursive_operation(path, to, move_callback_pre, move_single_file, NULL);
int ret = recursive_operation(path_src, path_dst, move_callback_pre, move_single_file, NULL);
if (ret && ret != -1) {
return recursive_operation(path, NULL, NULL, delete_single_file, delete_callback_post);
return recursive_operation(path_src, NULL, NULL, delete_single_file, delete_callback_post);
}
return ret;
}
static const char *check_destination(const char *file, const char *to)
static const char *path_destination_ensure_filename(const char *path_src,
const char *path_dst,
char *buf,
size_t buf_size)
{
struct stat st;
if (!stat(to, &st)) {
if (S_ISDIR(st.st_mode)) {
char *str, *path;
const char *filename;
size_t len = 0;
str = strip_last_slash(file);
filename = BLI_path_slash_rfind(str);
if (!filename) {
MEM_freeN(str);
return (char *)to;
}
/* skip slash */
filename += 1;
len = strlen(to) + strlen(filename) + 1;
path = MEM_callocN(len + 1, "check_destination path");
BLI_path_join(path, len + 1, to, filename);
MEM_freeN(str);
return path;
if (BLI_is_dir(path_dst)) {
char *path_src_no_slash = strip_last_slash(path_src);
const char *filename_src = BLI_path_basename(path_src_no_slash);
if (filename_src != path_src_no_slash) {
const size_t buf_size_needed = strlen(path_dst) + 1 + strlen(filename_src) + 1;
char *path_dst_with_filename = (buf_size_needed <= buf_size) ?
buf :
MEM_mallocN(buf_size_needed, __func__);
BLI_path_join(path_dst_with_filename, buf_size_needed, path_dst, filename_src);
path_dst = path_dst_with_filename;
}
MEM_freeN(path_src_no_slash);
}
return to;
return path_dst;
}
int BLI_copy(const char *file, const char *to)
int BLI_copy(const char *path_src, const char *path_dst)
{
const char *actual_to = check_destination(file, to);
char path_dst_buf[FILE_MAX_STATIC_BUF];
const char *path_dst_with_filename = path_destination_ensure_filename(
path_src, path_dst, path_dst_buf, sizeof(path_dst_buf));
int ret;
ret = recursive_operation(file, actual_to, copy_callback_pre, copy_single_file, NULL);
ret = recursive_operation(
path_src, path_dst_with_filename, copy_callback_pre, copy_single_file, NULL);
if (actual_to != to) {
MEM_freeN((void *)actual_to);
if (!ELEM(path_dst_with_filename, path_dst_buf, path_dst)) {
MEM_freeN((void *)path_dst_with_filename);
}
return ret;
}
# if 0
int BLI_create_symlink(const char *file, const char *to)
int BLI_create_symlink(const char *path_src, const char *path_dst)
{
return symlink(to, file);
return symlink(path_dst, path_src);
}
# endif

View File

@ -71,7 +71,7 @@ void path_reference_copy(const Set<std::pair<std::string, std::string>> &copy_se
fprintf(stderr, "Can't make directory for '%s', not copying\n", dst);
continue;
}
if (!BLI_copy(src, dst)) {
if (BLI_copy(src, dst) != 0) {
fprintf(stderr, "Can't copy '%s' to '%s'\n", src, dst);
continue;
}