Changeset View
Changeset View
Standalone View
Standalone View
source/blender/io/common/intern/path_util.cc
- This file was added.
| /* 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; | |||||
| } | |||||
| else 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. */ | |||||
| } | |||||
| else 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 | |||||