]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
refactor: Use std::filesystem::canonical
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 12 Jul 2023 19:15:31 +0000 (21:15 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Fri, 14 Jul 2023 18:33:17 +0000 (20:33 +0200)
src/Config.cpp
src/Util.cpp
src/Util.hpp
src/ccache.cpp
src/execute.cpp
src/util/path.cpp
src/util/path.hpp
test/run

index 971faac8edb516b43811c026137050a4ac4484d8..f7fef61ae7614483b69c7593ce5a7a94bfe0b607 100644 (file)
@@ -869,7 +869,7 @@ Config::set_value_in_file(const std::string& path,
   Config dummy_config;
   dummy_config.set_item(key, value, std::nullopt, false, "");
 
-  const auto resolved_path = Util::real_path(path);
+  const auto resolved_path = util::real_path(path);
   const auto st = Stat::stat(resolved_path);
   if (!st) {
     Util::ensure_dir_exists(Util::dir_name(resolved_path));
index 2efbe2e99969fcd0ca6162e58f64e7eaa21b6977..61b65b697f67ad6c9cd5c0b7e2376b46bfa51739 100644 (file)
@@ -96,21 +96,6 @@ find_first_ansi_csi_seq(std::string_view string)
   }
 }
 
-size_t
-path_max(const std::string& path)
-{
-#ifdef PATH_MAX
-  (void)path;
-  return PATH_MAX;
-#elif defined(MAXPATHLEN)
-  (void)path;
-  return MAXPATHLEN;
-#elif defined(_PC_PATH_MAX)
-  long maxlen = pathconf(path.c_str(), _PC_PATH_MAX);
-  return maxlen >= 4096 ? maxlen : 4096;
-#endif
-}
-
 template<typename T>
 std::vector<T>
 split_into(std::string_view string,
@@ -159,7 +144,7 @@ rewrite_stderr_to_absolute_paths(std::string_view text)
     } else {
       std::string path(line.substr(0, path_end));
       if (Stat::stat(path)) {
-        result += Util::real_path(path);
+        result += util::real_path(path);
         auto tail = line.substr(path_end);
         result.append(tail.data(), tail.length());
       } else {
@@ -582,7 +567,7 @@ make_relative_path(const std::string& base_dir,
     path = Util::dir_name(path);
   }
   const auto path_suffix = std::string(original_path.substr(path.length()));
-  const auto real_path = Util::real_path(std::string(path));
+  const auto real_path = util::real_path(path);
 
   const auto add_relpath_candidates = [&](auto p) {
     const std::string normalized_path =
@@ -737,47 +722,6 @@ parse_duration(std::string_view duration)
   }
 }
 
-std::string
-real_path(const std::string& path, bool return_empty_on_error)
-{
-  size_t buffer_size = path_max(path);
-  std::unique_ptr<char[]> managed_buffer(new char[buffer_size]);
-  char* buffer = managed_buffer.get();
-  char* resolved = nullptr;
-
-#ifdef HAVE_REALPATH
-  resolved = realpath(path.c_str(), buffer);
-#elif defined(_WIN32)
-  const char* c_path = path.c_str();
-  if (c_path[0] == '/') {
-    c_path++; // Skip leading slash.
-  }
-  HANDLE path_handle = CreateFile(c_path,
-                                  GENERIC_READ,
-                                  FILE_SHARE_READ,
-                                  nullptr,
-                                  OPEN_EXISTING,
-                                  FILE_ATTRIBUTE_NORMAL,
-                                  nullptr);
-  if (INVALID_HANDLE_VALUE != path_handle) {
-    bool ok = GetFinalPathNameByHandle(
-      path_handle, buffer, buffer_size, FILE_NAME_NORMALIZED);
-    CloseHandle(path_handle);
-    if (!ok) {
-      return path;
-    }
-    resolved = buffer + 4; // Strip \\?\ from the file name.
-  } else {
-    snprintf(buffer, buffer_size, "%s", c_path);
-    resolved = buffer;
-  }
-#else
-#  error No realpath function available
-#endif
-
-  return resolved ? resolved : (return_empty_on_error ? "" : path);
-}
-
 std::string_view
 remove_extension(std::string_view path)
 {
index 9ff59de73bac5686a337698376e9264dc30d1005..bf7a0ec9b469a3e11958abce80b9192646f4b698 100644 (file)
@@ -179,12 +179,6 @@ std::string normalize_concrete_absolute_path(const std::string& path);
 // into seconds. Throws `core::Error` on error.
 uint64_t parse_duration(std::string_view duration);
 
-// Return a normalized absolute path of `path`. On error (e.g. if the `path`
-// doesn't exist) the empty string is returned if return_empty_on_error is true,
-// otherwise `path` unmodified.
-std::string real_path(const std::string& path,
-                      bool return_empty_on_error = false);
-
 // Return a view into `path` containing the given path without the filename
 // extension as determined by `get_extension()`.
 std::string_view remove_extension(std::string_view path);
index 20bd454bd0a05407d4bcc9af10045fd4f3e0277f..d43cc0ddcf112f79996d91fc9abbe318e6e6274f 100644 (file)
@@ -242,7 +242,7 @@ guess_compiler(std::string_view path)
 
 #ifndef _WIN32
   // Follow symlinks to the real compiler to learn its name. We're not using
-  // Util::real_path in order to save some unnecessary stat calls.
+  // util::real_path in order to save some unnecessary stat calls.
   while (true) {
     std::error_code ec;
     auto symlink_target = fs::read_symlink(compiler_path, ec);
@@ -1523,8 +1523,7 @@ hash_common_info(const Context& ctx,
     if (!ctx.args_info.profile_path.empty()) {
       dir = ctx.args_info.profile_path;
     } else {
-      dir =
-        Util::real_path(std::string(Util::dir_name(ctx.args_info.output_obj)));
+      dir = util::real_path(Util::dir_name(ctx.args_info.output_obj));
     }
     std::string_view stem =
       Util::remove_extension(Util::base_name(ctx.args_info.output_obj));
index 2b3b499a0fd74daa8cdd5b063cca713523572009..10263ba12734d25fb02f316e3449632bb4e4418f 100644 (file)
@@ -367,7 +367,7 @@ find_executable_in_path(const std::string& name,
   }
 
   const auto real_exclude_path =
-    exclude_path ? Util::real_path(*exclude_path) : "";
+    exclude_path ? util::real_path(*exclude_path) : "";
 
   // Search the path list looking for the first compiler of the right name that
   // isn't us.
@@ -396,7 +396,7 @@ find_executable_in_path(const std::string& name,
         access(candidate.c_str(), X_OK) == 0;
 #endif
       if (candidate_exists) {
-        const auto real_candidate = Util::real_path(candidate);
+        const auto real_candidate = util::real_path(candidate);
         if ((real_exclude_path.empty() || real_candidate != real_exclude_path)
             && !Util::is_ccache_executable(real_candidate)) {
           return candidate;
index d1e6b7e858537f465dc497d64c35d3c36dd50692..5a9ab4addf051dfc431705383895f067e961bc17 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2023 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -29,6 +29,8 @@ const char k_dev_null_path[] = "/dev/null";
 const char k_path_delimiter[] = ":";
 #endif
 
+namespace fs = std::filesystem;
+
 namespace util {
 
 const char*
@@ -85,6 +87,14 @@ path_starts_with(std::string_view path, std::string_view prefix)
   return true;
 }
 
+std::string
+real_path(std::string_view path)
+{
+  std::error_code ec;
+  auto real_path = fs::canonical(path, ec).string();
+  return ec ? std::string(path) : real_path;
+}
+
 std::vector<std::string>
 split_path_list(std::string_view path_list)
 {
index 6fa3291e0defc787ca238c341b70e5b254e83507..476fbcc1d528364702e53aef19c62a9fd6b10018 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2023 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -38,6 +38,10 @@ bool is_full_path(std::string_view path);
 // Windows
 bool path_starts_with(std::string_view path, std::string_view prefix);
 
+// Return a normalized absolute path of `path`. On error (e.g. if the `path`
+// doesn't exist) path is returned unmodified.
+std::string real_path(std::string_view path);
+
 // Split a list of paths (such as the content of $PATH on Unix platforms or
 // %PATH% on Windows platforms) into paths.
 std::vector<std::string> split_path_list(std::string_view path_list);
index 43a573125952f18ce076d559687369cdf163a37d..7a27d38a745535162c2b7a86895b294b6dd761e5 100755 (executable)
--- a/test/run
+++ b/test/run
@@ -473,9 +473,13 @@ TEST() {
     remove_cache
     rm -rf $ABS_TESTDIR/run $ABS_TESTDIR/run.real
 
-    # Verify that tests behave well when apparent CWD != actual CWD.
-    mkdir $ABS_TESTDIR/run.real
-    ln -s run.real $ABS_TESTDIR/run
+    if $HOST_OS_WINDOWS; then
+        mkdir $ABS_TESTDIR/run
+    else
+       # Verify that tests behave well when apparent CWD != actual CWD.
+       mkdir $ABS_TESTDIR/run.real
+       ln -s run.real $ABS_TESTDIR/run
+    fi
 
     cd $ABS_TESTDIR/run
     if type SUITE_${suite_name}_SETUP >/dev/null 2>&1; then