83 lines
2.7 KiB
C++
83 lines
2.7 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
#include "IO_path_util.hh"
|
|
|
|
#include "BLI_fileops.h"
|
|
#include "BLI_path_util.h"
|
|
|
|
namespace blender::io {
|
|
|
|
std::string path_reference(StringRefNull filepath,
|
|
StringRefNull base_src,
|
|
StringRefNull base_dst,
|
|
ePathReferenceMode mode,
|
|
Set<std::pair<std::string, std::string>> *copy_set)
|
|
{
|
|
const bool is_relative = BLI_path_is_rel(filepath.c_str());
|
|
char filepath_abs[PATH_MAX];
|
|
BLI_strncpy(filepath_abs, filepath.c_str(), PATH_MAX);
|
|
BLI_path_abs(filepath_abs, base_src.c_str());
|
|
BLI_path_normalize(nullptr, filepath_abs);
|
|
|
|
/* Figure out final mode to be used. */
|
|
if (mode == PATH_REFERENCE_MATCH) {
|
|
mode = is_relative ? PATH_REFERENCE_RELATIVE : PATH_REFERENCE_ABSOLUTE;
|
|
}
|
|
else if (mode == PATH_REFERENCE_AUTO) {
|
|
mode = BLI_path_contains(base_dst.c_str(), filepath_abs) ? PATH_REFERENCE_RELATIVE :
|
|
PATH_REFERENCE_ABSOLUTE;
|
|
}
|
|
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);
|
|
copy_set->add(std::make_pair(filepath_abs, filepath_cpy));
|
|
BLI_strncpy(filepath_abs, filepath_cpy, PATH_MAX);
|
|
mode = PATH_REFERENCE_RELATIVE;
|
|
}
|
|
|
|
/* Now we know the final path mode. */
|
|
if (mode == PATH_REFERENCE_ABSOLUTE) {
|
|
return filepath_abs;
|
|
}
|
|
if (mode == PATH_REFERENCE_RELATIVE) {
|
|
char rel_path[PATH_MAX];
|
|
BLI_strncpy(rel_path, filepath_abs, PATH_MAX);
|
|
BLI_path_rel(rel_path, base_dst.c_str());
|
|
/* Can't always find relative path (e.g. between different drives). */
|
|
if (!BLI_path_is_rel(rel_path)) {
|
|
return filepath_abs;
|
|
}
|
|
return rel_path + 2; /* Skip blender's internal "//" prefix. */
|
|
}
|
|
if (mode == PATH_REFERENCE_STRIP) {
|
|
return BLI_path_basename(filepath_abs);
|
|
}
|
|
BLI_assert_msg(false, "Invalid path reference mode");
|
|
return filepath_abs;
|
|
}
|
|
|
|
void path_reference_copy(const Set<std::pair<std::string, std::string>> ©_set)
|
|
{
|
|
for (const auto © : copy_set) {
|
|
const char *src = copy.first.c_str();
|
|
const char *dst = copy.second.c_str();
|
|
if (!BLI_exists(src)) {
|
|
fprintf(stderr, "Missing source file '%s', not copying\n", src);
|
|
continue;
|
|
}
|
|
if (0 == BLI_path_cmp_normalized(src, dst)) {
|
|
continue; /* Source and dest are the same. */
|
|
}
|
|
if (!BLI_make_existing_file(dst)) {
|
|
fprintf(stderr, "Can't make directory for '%s', not copying\n", dst);
|
|
continue;
|
|
}
|
|
if (!BLI_copy(src, dst)) {
|
|
fprintf(stderr, "Can't copy '%s' to '%s'\n", src, dst);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace blender::io
|