Welcome to mirror list, hosted at ThFree Co, Russian Federation.

path_util.cc « intern « common « io « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 18632b410f80e7d3de7cbfd58a18bf1140f3adf1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* 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>> &copy_set)
{
  for (const auto &copy : 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