]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
refactor: Use util::{read_fd,read_file,write_file} functions
authorJoel Rosdahl <joel@rosdahl.net>
Mon, 15 Aug 2022 19:25:37 +0000 (21:25 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Mon, 15 Aug 2022 20:13:32 +0000 (22:13 +0200)
31 files changed:
src/Args.cpp
src/Args.hpp
src/Config.cpp
src/Config.hpp
src/Depfile.cpp
src/Hash.cpp
src/Hash.hpp
src/ResultExtractor.cpp
src/ResultRetriever.cpp
src/Util.cpp
src/ccache.cpp
src/core/mainoptions.cpp
src/execute.cpp
src/hashutil.cpp
src/storage/primary/PrimaryStorage.cpp
src/storage/primary/StatsFile.cpp
src/util/LockFile.cpp
src/util/file.cpp
unittest/test_Args.cpp
unittest/test_AtomicFile.cpp
unittest/test_Config.cpp
unittest/test_InodeCache.cpp
unittest/test_Stat.cpp
unittest/test_Util.cpp
unittest/test_argprocessing.cpp
unittest/test_ccache.cpp
unittest/test_core_StatsLog.cpp
unittest/test_hashutil.cpp
unittest/test_storage_primary_StatsFile.cpp
unittest/test_storage_primary_util.cpp
unittest/test_util_LockFile.cpp

index 9b1dfbd1ef5a4b50a6b3bc9ac10d16b1471578fc..41a429e6102b7935ea80078718760af781aafc92 100644 (file)
@@ -21,6 +21,7 @@
 #include "Util.hpp"
 
 #include <core/exceptions.hpp>
+#include <util/file.hpp>
 #include <util/string.hpp>
 
 Args::Args(Args&& other) noexcept : m_args(std::move(other.m_args))
@@ -48,17 +49,15 @@ Args::from_string(const std::string& command)
 std::optional<Args>
 Args::from_atfile(const std::string& filename, AtFileFormat format)
 {
-  std::string argtext;
-  try {
-    argtext = Util::read_text_file(filename);
-  } catch (core::Error&) {
+  const auto argtext = util::read_file<std::string>(filename);
+  if (!argtext) {
     return std::nullopt;
   }
 
   Args args;
-  auto pos = argtext.c_str();
+  auto pos = argtext->c_str();
   std::string argbuf;
-  argbuf.resize(argtext.length() + 1);
+  argbuf.resize(argtext->length() + 1);
   auto argpos = argbuf.begin();
 
   // Used to track quoting state; if \0 we are not inside quotes. Otherwise
index 1df0529f0ba1038804b32a057a2eee5ba0434846..eeb66ad93c3fffaa3bdb0857a52913601439f5be 100644 (file)
 #pragma once
 
 #include "NonCopyable.hpp"
-#include "Util.hpp"
 
 #include <deque>
 #include <optional>
 #include <string>
 #include <string_view>
+#include <vector>
 
 class Args
 {
index a6cefe14fb3503346b2e65b34fa8a0decbb62291..d7c0ea93ac94ddb90458e1f11c03729aeec0a746 100644 (file)
@@ -29,6 +29,7 @@
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
 #include <util/expected.hpp>
+#include <util/file.hpp>
 #include <util/path.hpp>
 #include <util/string.hpp>
 
@@ -811,10 +812,10 @@ Config::set_value_in_file(const std::string& path,
   const auto st = Stat::stat(resolved_path);
   if (!st) {
     Util::ensure_dir_exists(Util::dir_name(resolved_path));
-    try {
-      Util::write_file(resolved_path, "");
-    } catch (const core::Error& e) {
-      throw core::Error("failed to write to {}: {}", resolved_path, e.what());
+    const auto result = util::write_file(resolved_path, "");
+    if (!result) {
+      throw core::Error(
+        "failed to write to {}: {}", resolved_path, result.error());
     }
   }
 
index 1d62b00105d2d341447b19202ca386f3f794d72e..33f66445e801c0631c907dc42669c6e5cae30461 100644 (file)
@@ -19,7 +19,6 @@
 #pragma once
 
 #include "NonCopyable.hpp"
-#include "Util.hpp"
 
 #include <core/Sloppiness.hpp>
 
index f944bfed81e72e6d42f273916106d366df283d9e..e85b6ccdb9a49d04350b94a831878e03f477e12d 100644 (file)
@@ -24,6 +24,7 @@
 #include "assertions.hpp"
 
 #include <core/exceptions.hpp>
+#include <util/file.hpp>
 #include <util/path.hpp>
 
 #include <algorithm>
@@ -127,16 +128,14 @@ make_paths_relative_in_output_dep(const Context& ctx)
   }
 
   const std::string& output_dep = ctx.args_info.output_dep;
-  std::string file_content;
-  try {
-    file_content = Util::read_file(output_dep);
-  } catch (const core::Error& e) {
-    LOG("Cannot open dependency file {}: {}", output_dep, e.what());
+  const auto file_content = util::read_file<std::string>(output_dep);
+  if (!file_content) {
+    LOG("Cannot open dependency file {}: {}", output_dep, file_content.error());
     return;
   }
-  const auto new_content = rewrite_source_paths(ctx, file_content);
+  const auto new_content = rewrite_source_paths(ctx, *file_content);
   if (new_content) {
-    Util::write_file(output_dep, *new_content);
+    util::write_file(output_dep, *new_content);
   } else {
     LOG("No paths in dependency file {} made relative", output_dep);
   }
index 93df21b1eeab8aea6311a8d3be26ea02c01b0924..442369e91b2ce52da8653bae4f5f54769ffb8138 100644 (file)
@@ -23,6 +23,7 @@
 #include "fmtmacros.hpp"
 
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -110,24 +111,23 @@ Hash::hash(int64_t x)
   return *this;
 }
 
-bool
+nonstd::expected<void, std::string>
 Hash::hash_fd(int fd)
 {
-  return Util::read_fd(
+  return util::read_fd(
     fd, [this](const void* data, size_t size) { hash(data, size); });
 }
 
-bool
+nonstd::expected<void, std::string>
 Hash::hash_file(const std::string& path)
 {
   Fd fd(open(path.c_str(), O_RDONLY | O_BINARY));
   if (!fd) {
     LOG("Failed to open {}: {}", path, strerror(errno));
-    return false;
+    return nonstd::make_unexpected(strerror(errno));
   }
 
-  bool ret = hash_fd(*fd);
-  return ret;
+  return hash_fd(*fd);
 }
 
 void
index 269026e370fcb56d56fe1624f757269e09f3d47c..3e8d5573c1a40686b0fb4462359c1b85088d67f3 100644 (file)
@@ -21,6 +21,7 @@
 #include "Digest.hpp"
 
 #include "third_party/blake3/blake3.h"
+#include <third_party/nonstd/expected.hpp>
 
 #include <cstdint>
 #include <cstdio>
@@ -80,21 +81,17 @@ public:
   // text input file followed by a newline.
   Hash& hash(int64_t x);
 
-  // Add contents read from an open file descriptor to the hash.
+  // Add file contents to the hash.
   //
   // If hash debugging is enabled, the data is written verbatim to the text
   // input file.
-  //
-  // Returns true on success, otherwise false.
-  bool hash_fd(int fd);
+  nonstd::expected<void, std::string> hash_file(const std::string& path);
 
-  // Add file contents to the hash.
+  // Add contents read from an open file descriptor to the hash.
   //
   // If hash debugging is enabled, the data is written verbatim to the text
   // input file.
-  //
-  // Returns true on success, otherwise false.
-  bool hash_file(const std::string& path);
+  nonstd::expected<void, std::string> hash_fd(int fd);
 
   // Add `text` to the text debug file.
   void add_debug_text(std::string_view text);
index 6eb8e06e6979ced962011fe618d7e0434136c0ed..2c917d88a16febb24a6d715c363d55a88f81741f 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -75,10 +76,9 @@ ResultExtractor::on_entry_data(const uint8_t* data, size_t size)
 {
   ASSERT(m_dest_fd);
 
-  try {
-    Util::write_fd(*m_dest_fd, data, size);
-  } catch (core::Error& e) {
-    throw core::Error("Failed to write to {}: {}", m_dest_path, e.what());
+  const auto result = util::write_fd(*m_dest_fd, data, size);
+  if (!result) {
+    throw core::Error("Failed to write to {}: {}", m_dest_path, result.error());
   }
 }
 
index c3f0f51cf76c2c3b0279c2311014e63cdb9d36a8..a7edbc1848b7b0973934bd22e12549815c8ec5ac 100644 (file)
@@ -146,10 +146,10 @@ ResultRetriever::on_entry_data(const uint8_t* data, size_t size)
       || (m_dest_file_type == FileType::dependency && !m_dest_path.empty())) {
     m_dest_data.append(reinterpret_cast<const char*>(data), size);
   } else if (m_dest_fd) {
-    try {
-      Util::write_fd(*m_dest_fd, data, size);
-    } catch (core::Error& e) {
-      throw WriteError(FMT("Failed to write to {}: {}", m_dest_path, e.what()));
+    const auto result = util::write_fd(*m_dest_fd, data, size);
+    if (!result) {
+      throw WriteError(
+        FMT("Failed to write to {}: {}", m_dest_path, result.error()));
     }
   }
 }
@@ -178,24 +178,26 @@ void
 ResultRetriever::write_dependency_file()
 {
   ASSERT(m_ctx.args_info.dependency_target);
-  const auto& dep_target = *m_ctx.args_info.dependency_target;
-
-  try {
-    size_t start_pos = 0;
-    const size_t colon_pos = m_dest_data.find(": ");
-    if (colon_pos != std::string::npos) {
-      const auto obj_in_dep_file =
-        std::string_view(m_dest_data).substr(0, colon_pos);
-      if (obj_in_dep_file != dep_target) {
-        Util::write_fd(*m_dest_fd, dep_target.data(), dep_target.length());
-        start_pos = colon_pos;
-      }
-    }
 
-    Util::write_fd(*m_dest_fd,
-                   m_dest_data.data() + start_pos,
-                   m_dest_data.length() - start_pos);
-  } catch (core::Error& e) {
-    throw WriteError(FMT("Failed to write to {}: {}", m_dest_path, e.what()));
+  auto write_data = [&](auto data, auto size) {
+    const auto result = util::write_fd(*m_dest_fd, data, size);
+    if (!result) {
+      throw WriteError(
+        FMT("Failed to write to {}: {}", m_dest_path, result.error()));
+    }
+  };
+
+  size_t start_pos = 0;
+  const size_t colon_pos = m_dest_data.find(": ");
+  if (colon_pos != std::string::npos) {
+    const auto obj_in_dep_file =
+      std::string_view(m_dest_data).substr(0, colon_pos);
+    const auto& dep_target = *m_ctx.args_info.dependency_target;
+    if (obj_in_dep_file != dep_target) {
+      write_data(dep_target.data(), dep_target.length());
+      start_pos = colon_pos;
+    }
   }
+
+  write_data(m_dest_data.data() + start_pos, m_dest_data.length() - start_pos);
 }
index 80b7b97d717d289f08c043d6ea88dfbf3170983c..2216cdd5ae106441e20748d8c3b50ff4e0c9e18b 100644 (file)
@@ -29,6 +29,7 @@
 #include <Finalizer.hpp>
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 #include <util/path.hpp>
 #include <util/string.hpp>
 
@@ -354,8 +355,9 @@ common_dir_prefix_length(std::string_view dir, std::string_view path)
 void
 copy_fd(int fd_in, int fd_out)
 {
-  read_fd(fd_in,
-          [=](const void* data, size_t size) { write_fd(fd_out, data, size); });
+  util::read_fd(fd_in, [=](const void* data, size_t size) {
+    util::write_fd(fd_out, data, size);
+  });
 }
 
 void
@@ -511,7 +513,7 @@ fallocate(int fd, long new_size)
   }
   int err = 0;
   try {
-    write_fd(fd, buf, bytes_to_write);
+    util::write_fd(fd, buf, bytes_to_write);
   } catch (core::Error&) {
     err = errno;
   }
@@ -1244,10 +1246,10 @@ send_to_fd(const Context& ctx, const std::string& text, int fd)
     text_to_send = &modified_text;
   }
 
-  try {
-    write_fd(fd, text_to_send->data(), text_to_send->length());
-  } catch (core::Error& e) {
-    throw core::Error("Failed to write to {}: {}", fd, e.what());
+  const auto result =
+    util::write_fd(fd, text_to_send->data(), text_to_send->length());
+  if (!result) {
+    throw core::Error("Failed to write to {}: {}", fd, result.error());
   }
 }
 
index 3326ada17fd8af69e8e2cf729a39c639c302d234..7cb1aaf7346ca4ff4db7cb9599847820101a264d 100644 (file)
@@ -58,6 +58,7 @@
 #include <core/wincompat.hpp>
 #include <storage/Storage.hpp>
 #include <util/expected.hpp>
+#include <util/file.hpp>
 #include <util/path.hpp>
 #include <util/string.hpp>
 
@@ -455,17 +456,16 @@ print_included_files(const Context& ctx, FILE* fp)
 static nonstd::expected<void, Failure>
 process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path)
 {
-  std::string data;
-  try {
-    data = Util::read_file(path);
-  } catch (core::Error&) {
+  auto data = util::read_file<std::string>(path);
+  if (!data) {
+    LOG("Failed reading {}: {}", path, data.error());
     return nonstd::make_unexpected(Statistic::internal_error);
   }
 
   // Bytes between p and q are pending to be hashed.
-  const char* p = &data[0];
-  char* q = &data[0];
-  const char* end = p + data.length();
+  char* q = &(*data)[0];
+  const char* p = q;
+  const char* end = p + data->length();
 
   // There must be at least 7 characters (# 1 "x") left to potentially find an
   // include file path.
@@ -508,7 +508,7 @@ process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path)
             // HP/AIX:
             || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e'
                 && q[5] == ' '))
-        && (q == data.data() || q[-1] == '\n')) {
+        && (q == data->data() || q[-1] == '\n')) {
       // Workarounds for preprocessor linemarker bugs in GCC version 6.
       if (q[2] == '3') {
         if (util::starts_with(q, hash_31_command_line_newline)) {
@@ -593,7 +593,7 @@ process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path)
       return nonstd::make_unexpected(
         Failure(Statistic::unsupported_code_directive));
     } else if (strncmp(q, "___________", 10) == 0
-               && (q == data.data() || q[-1] == '\n')) {
+               && (q == data->data() || q[-1] == '\n')) {
       // Unfortunately the distcc-pump wrapper outputs standard output lines:
       // __________Using distcc-pump from /usr/bin
       // __________Using # distcc servers in pump mode
@@ -636,16 +636,16 @@ process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path)
 static std::optional<Digest>
 result_key_from_depfile(Context& ctx, Hash& hash)
 {
-  std::string file_content;
-  try {
-    file_content = Util::read_file(ctx.args_info.output_dep);
-  } catch (const core::Error& e) {
-    LOG(
-      "Cannot open dependency file {}: {}", ctx.args_info.output_dep, e.what());
+  const auto file_content =
+    util::read_file<std::string>(ctx.args_info.output_dep);
+  if (!file_content) {
+    LOG("Cannot open dependency file {}: {}",
+        ctx.args_info.output_dep,
+        file_content.error());
     return std::nullopt;
   }
 
-  for (std::string_view token : Depfile::tokenize(file_content)) {
+  for (std::string_view token : Depfile::tokenize(*file_content)) {
     if (util::ends_with(token, ":")) {
       continue;
     }
@@ -720,8 +720,8 @@ do_execute(Context& ctx, Args& args, const bool capture_stdout = true)
                        std::move(tmp_stderr.fd));
   if (status != 0 && !ctx.diagnostics_color_failed
       && ctx.config.compiler_type() == CompilerType::gcc) {
-    auto errors = Util::read_file(tmp_stderr.path);
-    if (errors.find("fdiagnostics-color") != std::string::npos) {
+    const auto errors = util::read_file<std::string>(tmp_stderr.path);
+    if (errors && errors->find("fdiagnostics-color") != std::string::npos) {
       // GCC versions older than 4.9 don't understand -fdiagnostics-color, and
       // non-GCC compilers misclassified as CompilerType::gcc might not do it
       // either. We assume that if the error message contains
@@ -737,17 +737,23 @@ do_execute(Context& ctx, Args& args, const bool capture_stdout = true)
     }
   }
 
-  try {
-    return DoExecuteResult{
-      status,
-      capture_stdout ? Util::read_file(tmp_stdout.path) : std::string(),
-      Util::read_file(tmp_stderr.path),
-    };
-  } catch (core::Error&) {
-    // The stdout or stderr file was removed - cleanup in progress? Better bail
-    // out.
+  std::string stdout_data;
+  if (capture_stdout) {
+    auto stdout_data_result = util::read_file<std::string>(tmp_stdout.path);
+    if (!stdout_data_result) {
+      // The stdout file was removed - cleanup in progress? Better bail out.
+      return nonstd::make_unexpected(Statistic::missing_cache_file);
+    }
+    stdout_data = std::move(*stdout_data_result);
+  }
+
+  auto stderr_data_result = util::read_file<std::string>(tmp_stderr.path);
+  if (!stderr_data_result) {
+    // The stdout file was removed - cleanup in progress? Better bail out.
     return nonstd::make_unexpected(Statistic::missing_cache_file);
   }
+
+  return DoExecuteResult{status, stdout_data, *stderr_data_result};
 }
 
 static core::Manifest
index 456a1b0673ecf238438461cb6e0ad1d2d2132e94..936689c848e9ff3468bb532da56da3f984418c93 100644 (file)
@@ -40,6 +40,7 @@
 #include <util/TextTable.hpp>
 #include <util/XXH3_128.hpp>
 #include <util/expected.hpp>
+#include <util/file.hpp>
 #include <util/string.hpp>
 
 #include <fcntl.h>
@@ -417,7 +418,7 @@ process_main_options(int argc, const char* const* argv)
       util::XXH3_128 checksum;
       Fd fd(arg == "-" ? STDIN_FILENO : open(arg.c_str(), O_RDONLY));
       if (fd) {
-        Util::read_fd(*fd, [&checksum](const void* data, size_t size) {
+        util::read_fd(*fd, [&checksum](const void* data, size_t size) {
           checksum.update(data, size);
         });
         const auto digest = checksum.digest();
@@ -455,12 +456,12 @@ process_main_options(int argc, const char* const* argv)
 
     case HASH_FILE: {
       Hash hash;
-      const bool ok =
+      const auto result =
         arg == "-" ? hash.hash_fd(STDIN_FILENO) : hash.hash_file(arg);
-      if (ok) {
+      if (result) {
         PRINT(stdout, "{}\n", hash.digest().to_string());
       } else {
-        PRINT(stderr, "Error: Failed to hash {}\n", arg);
+        PRINT(stderr, "Error: Failed to hash {}: {}\n", arg, result.error());
         return EXIT_FAILURE;
       }
       break;
index 10ab89f04fb2717d3093a3b27cd9d96a5b1f831f..9d9e08b09c764bf1b14a936a23eadf0269ec6cde 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 #include <util/path.hpp>
 
 #ifdef HAVE_UNISTD_H
@@ -148,7 +149,7 @@ win32execute(const char* path,
   if (args.length() > 8192) {
     TemporaryFile tmp_file(FMT("{}/cmd_args", temp_dir));
     args = Win32Util::argv_to_string(argv + 1, sh, true);
-    Util::write_fd(*tmp_file.fd, args.data(), args.length());
+    util::write_fd(*tmp_file.fd, args.data(), args.length());
     args = FMT(R"("{}" "@{}")", full_path, tmp_file.path);
     tmp_file_path = tmp_file.path;
     LOG("Arguments from {}", tmp_file.path);
index 865698d1328705e2f24991abda0be0eecfcafedd..251049af3a0bac05db9da5f6e14692edb7a25caa 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 #include <util/string.hpp>
 
 #ifdef INODE_CACHE_SUPPORTED
@@ -199,20 +200,18 @@ do_hash_file(const Context& ctx,
   (void)ctx;
 #endif
 
-  std::string data;
-  try {
-    data = Util::read_file(path, size_hint);
-  } catch (core::Error&) {
+  const auto data = util::read_file<std::string>(path, size_hint);
+  if (!data) {
     return HASH_SOURCE_CODE_ERROR;
   }
 
   int result = HASH_SOURCE_CODE_OK;
   if (check_temporal_macros) {
-    result |= check_for_temporal_macros(data);
+    result |= check_for_temporal_macros(*data);
   }
 
   Hash hash;
-  hash.hash(data);
+  hash.hash(*data);
   digest = hash.digest();
 
 #ifdef INODE_CACHE_SUPPORTED
@@ -424,9 +423,10 @@ hash_command_output(Hash& hash,
     return false;
   }
   int fd = _open_osfhandle((intptr_t)pipe_out[0], O_BINARY);
-  bool ok = hash.hash_fd(fd);
-  if (!ok) {
-    LOG("Error hashing compiler check command output: {}", strerror(errno));
+  const auto compiler_check_result = hash.hash_fd(fd);
+  if (!compiler_check_result) {
+    LOG("Error hashing compiler check command output: {}",
+        compiler_check_result.error());
   }
   WaitForSingleObject(pi.hProcess, INFINITE);
   DWORD exitcode;
@@ -438,7 +438,7 @@ hash_command_output(Hash& hash,
     LOG("Compiler check command returned {}", exitcode);
     return false;
   }
-  return ok;
+  return bool(compiler_check_result);
 #else
   int pipefd[2];
   if (pipe(pipefd) == -1) {
@@ -461,9 +461,10 @@ hash_command_output(Hash& hash,
   } else {
     // Parent.
     close(pipefd[1]);
-    bool ok = hash.hash_fd(pipefd[0]);
-    if (!ok) {
-      LOG("Error hashing compiler check command output: {}", strerror(errno));
+    const auto hash_result = hash.hash_fd(pipefd[0]);
+    if (!hash_result) {
+      LOG("Error hashing compiler check command output: {}",
+          hash_result.error());
     }
     close(pipefd[0]);
 
@@ -480,7 +481,7 @@ hash_command_output(Hash& hash,
       LOG("Compiler check command returned {}", WEXITSTATUS(status));
       return false;
     }
-    return ok;
+    return bool(hash_result);
   }
 #endif
 }
index 63813abb0232695bec801ad4daf0902fd625bc1e..b5cf31cb43ae50a6a3eda2cdaaeeafea7d96ed70 100644 (file)
@@ -321,7 +321,7 @@ PrimaryStorage::clean_internal_tempdir()
                    }
                  });
 
-  Util::write_file(cleaned_stamp, "");
+  util::write_file(cleaned_stamp, "");
 }
 
 std::optional<core::StatisticsCounters>
index 7e9503ceb6132d0aeb022482f190a6ca8a506c29..4d51b78743bd1ce25270c52e1c1515b85b5bc8a8 100644 (file)
 
 #include <AtomicFile.hpp>
 #include <Logging.hpp>
-#include <Util.hpp>
 #include <core/exceptions.hpp>
 #include <fmtmacros.hpp>
 #include <util/LockFile.hpp>
+#include <util/file.hpp>
 
 namespace storage::primary {
 
@@ -36,16 +36,14 @@ StatsFile::read() const
 {
   core::StatisticsCounters counters;
 
-  std::string data;
-  try {
-    data = Util::read_file(m_path);
-  } catch (const core::Error&) {
+  const auto data = util::read_file<std::string>(m_path);
+  if (!data) {
     // Ignore.
     return counters;
   }
 
   size_t i = 0;
-  const char* str = data.c_str();
+  const char* str = data->c_str();
   while (true) {
     char* end;
     const uint64_t value = std::strtoull(str, &end, 10);
index 8d4034c4c8b01465cfbd1dbc91a65dbc0eb02b95..7dee3c9ea951a86d677b0b870a0e385334797c24 100644 (file)
@@ -364,11 +364,11 @@ LongLivedLockFile::LongLivedLockFile(const std::string& path)
 void
 LongLivedLockFile::on_after_acquire()
 {
-  try {
-    Util::write_file(m_alive_file, "");
-  } catch (const core::Error& e) {
-    LOG("Failed to create {}: {}", m_alive_file, e.what());
+  const auto result = util::write_file(m_alive_file, "");
+  if (!result) {
+    LOG("Failed to write {}: {}", m_alive_file, result.error());
   }
+
   LOG_RAW("Starting keep-alive thread");
   m_keep_alive_thread = std::thread([=] {
     while (true) {
index 99f7998a0d0e0c9454c94eb1d70e013fac22ed1d..d50d027b743d1c8937a6e914bb02db81e901fdaa 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <Fd.hpp>
 #include <Logging.hpp>
-#include <Util.hpp>
+#include <Stat.hpp>
 #include <fmtmacros.hpp>
 
 #ifdef HAVE_UNISTD_H
index 81a609de25211043283f53399e3ca80c39c4187a..8ae2470c7199be4f1559d2fea546572da477fb6e 100644 (file)
@@ -19,6 +19,8 @@
 #include "../src/Args.hpp"
 #include "TestUtil.hpp"
 
+#include <util/file.hpp>
+
 #include "third_party/doctest.h"
 
 TEST_SUITE_BEGIN("Args");
@@ -89,14 +91,14 @@ TEST_CASE("Args::from_atfile")
 
   SUBCASE("Empty")
   {
-    Util::write_file("at_file", "");
+    util::write_file("at_file", "");
     args = *Args::from_atfile("at_file");
     CHECK(args.size() == 0);
   }
 
   SUBCASE("One argument without newline")
   {
-    Util::write_file("at_file", "foo");
+    util::write_file("at_file", "foo");
     args = *Args::from_atfile("at_file");
     CHECK(args.size() == 1);
     CHECK(args[0] == "foo");
@@ -104,7 +106,7 @@ TEST_CASE("Args::from_atfile")
 
   SUBCASE("One argument with newline")
   {
-    Util::write_file("at_file", "foo\n");
+    util::write_file("at_file", "foo\n");
     args = *Args::from_atfile("at_file");
     CHECK(args.size() == 1);
     CHECK(args[0] == "foo");
@@ -112,7 +114,7 @@ TEST_CASE("Args::from_atfile")
 
   SUBCASE("Multiple simple arguments")
   {
-    Util::write_file("at_file", "x y z\n");
+    util::write_file("at_file", "x y z\n");
     args = *Args::from_atfile("at_file");
     CHECK(args.size() == 3);
     CHECK(args[0] == "x");
@@ -122,7 +124,7 @@ TEST_CASE("Args::from_atfile")
 
   SUBCASE("Tricky quoting")
   {
-    Util::write_file(
+    util::write_file(
       "at_file",
       "first\rsec\\\tond\tthi\\\\rd\nfourth  \tfif\\ th \"si'x\\\" th\""
       " 'seve\nth'\\");
@@ -139,7 +141,7 @@ TEST_CASE("Args::from_atfile")
 
   SUBCASE("Only escape double quote and backslash in alternate format")
   {
-    Util::write_file("at_file", "\"\\\"\\a\\ \\\\\\ \\b\\\"\"\\");
+    util::write_file("at_file", "\"\\\"\\a\\ \\\\\\ \\b\\\"\"\\");
     args = *Args::from_atfile("at_file", Args::AtFileFormat::msvc);
     CHECK(args.size() == 1);
     CHECK(args[0] == "\"\\a\\ \\\\ \\b\"\\");
@@ -147,7 +149,7 @@ TEST_CASE("Args::from_atfile")
 
   SUBCASE("Ignore single quote in alternate format")
   {
-    Util::write_file("at_file", "'a b'");
+    util::write_file("at_file", "'a b'");
     args = *Args::from_atfile("at_file", Args::AtFileFormat::msvc);
     CHECK(args.size() == 2);
     CHECK(args[0] == "'a");
index a572040c4d8fef668d57a9a648cbcd98ae01a9af..7bd38ed24650b115a0f76794231fac262280e04b 100644 (file)
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 #include "../src/AtomicFile.hpp"
-#include "../src/Util.hpp"
 #include "TestUtil.hpp"
 
+#include <Stat.hpp>
+#include <util/file.hpp>
+
 #include "third_party/doctest.h"
 
 using TestUtil::TestContext;
@@ -35,7 +37,7 @@ TEST_CASE("Base case")
   atomic_file.write(util::Blob{0x65, 0x6c});
   fputs("lo", atomic_file.stream());
   atomic_file.commit();
-  CHECK(Util::read_file("test") == "hello");
+  CHECK(*util::read_file<std::string>("test") == "hello");
 }
 
 TEST_CASE("Not committing")
@@ -46,7 +48,7 @@ TEST_CASE("Not committing")
     AtomicFile atomic_file("test", AtomicFile::Mode::text);
     atomic_file.write("hello");
   }
-  CHECK_THROWS_WITH(Util::read_file("test"), "No such file or directory");
+  CHECK(!Stat::stat("test"));
 }
 
 TEST_SUITE_END();
index 29fe65c0626fb462ba6c9660bf3a932e897b60c7..ac8241cf9c78aff27ae2868b72f9f0345af7f53a 100644 (file)
@@ -22,6 +22,7 @@
 #include "TestUtil.hpp"
 
 #include <core/exceptions.hpp>
+#include <util/file.hpp>
 
 #include "third_party/doctest.h"
 #include "third_party/fmt/core.h"
@@ -91,7 +92,7 @@ TEST_CASE("Config::update_from_file")
   std::string base_dir = FMT("C:/{0}/foo/{0}", user);
 #endif
 
-  Util::write_file(
+  util::write_file(
     "ccache.conf",
     "base_dir = " + base_dir + "\n"
     "cache_dir=\n"
@@ -192,31 +193,31 @@ TEST_CASE("Config::update_from_file, error handling")
 
   SUBCASE("missing equal sign")
   {
-    Util::write_file("ccache.conf", "no equal sign");
+    util::write_file("ccache.conf", "no equal sign");
     REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
                         "ccache.conf:1: missing equal sign");
   }
 
   SUBCASE("unknown key")
   {
-    Util::write_file("ccache.conf", "# Comment\nfoo = bar");
+    util::write_file("ccache.conf", "# Comment\nfoo = bar");
     CHECK(config.update_from_file("ccache.conf"));
   }
 
   SUBCASE("invalid bool")
   {
-    Util::write_file("ccache.conf", "disable=");
+    util::write_file("ccache.conf", "disable=");
     REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
                         "ccache.conf:1: not a boolean value: \"\"");
 
-    Util::write_file("ccache.conf", "disable=foo");
+    util::write_file("ccache.conf", "disable=foo");
     REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
                         "ccache.conf:1: not a boolean value: \"foo\"");
   }
 
   SUBCASE("invalid variable reference")
   {
-    Util::write_file("ccache.conf", "base_dir = ${foo");
+    util::write_file("ccache.conf", "base_dir = ${foo");
     REQUIRE_THROWS_WITH(
       config.update_from_file("ccache.conf"),
       "ccache.conf:1: syntax error: missing '}' after \"foo\"");
@@ -225,14 +226,14 @@ TEST_CASE("Config::update_from_file, error handling")
 
   SUBCASE("empty umask")
   {
-    Util::write_file("ccache.conf", "umask = ");
+    util::write_file("ccache.conf", "umask = ");
     CHECK(config.update_from_file("ccache.conf"));
     CHECK(config.umask() == std::nullopt);
   }
 
   SUBCASE("invalid size")
   {
-    Util::write_file("ccache.conf", "max_size = foo");
+    util::write_file("ccache.conf", "max_size = foo");
     REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
                         "ccache.conf:1: invalid size: \"foo\"");
     // Other cases tested in test_Util.c.
@@ -240,7 +241,7 @@ TEST_CASE("Config::update_from_file, error handling")
 
   SUBCASE("unknown sloppiness")
   {
-    Util::write_file("ccache.conf", "sloppiness = time_macros, foo");
+    util::write_file("ccache.conf", "sloppiness = time_macros, foo");
     CHECK(config.update_from_file("ccache.conf"));
     CHECK(config.sloppiness().to_bitmask()
           == static_cast<uint32_t>(core::Sloppy::time_macros));
@@ -248,15 +249,15 @@ TEST_CASE("Config::update_from_file, error handling")
 
   SUBCASE("invalid unsigned")
   {
-    Util::write_file("ccache.conf", "max_files =");
+    util::write_file("ccache.conf", "max_files =");
     REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
                         "ccache.conf:1: invalid unsigned integer: \"\"");
 
-    Util::write_file("ccache.conf", "max_files = -42");
+    util::write_file("ccache.conf", "max_files = -42");
     REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
                         "ccache.conf:1: invalid unsigned integer: \"-42\"");
 
-    Util::write_file("ccache.conf", "max_files = foo");
+    util::write_file("ccache.conf", "max_files = foo");
     REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
                         "ccache.conf:1: invalid unsigned integer: \"foo\"");
   }
@@ -268,12 +269,12 @@ TEST_CASE("Config::update_from_file, error handling")
 
   SUBCASE("relative base dir")
   {
-    Util::write_file("ccache.conf", "base_dir = relative/path");
+    util::write_file("ccache.conf", "base_dir = relative/path");
     REQUIRE_THROWS_WITH(
       config.update_from_file("ccache.conf"),
       "ccache.conf:1: not an absolute path: \"relative/path\"");
 
-    Util::write_file("ccache.conf", "base_dir =");
+    util::write_file("ccache.conf", "base_dir =");
     CHECK(config.update_from_file("ccache.conf"));
   }
 }
@@ -300,23 +301,23 @@ TEST_CASE("Config::set_value_in_file")
 
   SUBCASE("set new value")
   {
-    Util::write_file("ccache.conf", "path = vanilla\n");
+    util::write_file("ccache.conf", "path = vanilla\n");
     config.set_value_in_file("ccache.conf", "compiler", "chocolate");
-    std::string content = Util::read_file("ccache.conf");
+    std::string content = *util::read_file<std::string>("ccache.conf");
     CHECK(content == "path = vanilla\ncompiler = chocolate\n");
   }
 
   SUBCASE("existing value")
   {
-    Util::write_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
+    util::write_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
     config.set_value_in_file("ccache.conf", "path", "vanilla");
-    std::string content = Util::read_file("ccache.conf");
+    std::string content = *util::read_file<std::string>("ccache.conf");
     CHECK(content == "path = vanilla\nstats = chocolate\n");
   }
 
   SUBCASE("unknown option")
   {
-    Util::write_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
+    util::write_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
     try {
       config.set_value_in_file("ccache.conf", "foo", "bar");
       CHECK(false);
@@ -324,24 +325,24 @@ TEST_CASE("Config::set_value_in_file")
       CHECK(std::string(e.what()) == "unknown configuration option \"foo\"");
     }
 
-    std::string content = Util::read_file("ccache.conf");
+    std::string content = *util::read_file<std::string>("ccache.conf");
     CHECK(content == "path = chocolate\nstats = chocolate\n");
   }
 
   SUBCASE("unknown sloppiness")
   {
-    Util::write_file("ccache.conf", "path = vanilla\n");
+    util::write_file("ccache.conf", "path = vanilla\n");
     config.set_value_in_file("ccache.conf", "sloppiness", "foo");
-    std::string content = Util::read_file("ccache.conf");
+    std::string content = *util::read_file<std::string>("ccache.conf");
     CHECK(content == "path = vanilla\nsloppiness = foo\n");
   }
 
   SUBCASE("comments are kept")
   {
-    Util::write_file("ccache.conf", "# c1\npath = blueberry\n#c2\n");
+    util::write_file("ccache.conf", "# c1\npath = blueberry\n#c2\n");
     config.set_value_in_file("ccache.conf", "path", "vanilla");
     config.set_value_in_file("ccache.conf", "compiler", "chocolate");
-    std::string content = Util::read_file("ccache.conf");
+    std::string content = *util::read_file<std::string>("ccache.conf");
     CHECK(content == "# c1\npath = vanilla\n#c2\ncompiler = chocolate\n");
   }
 }
@@ -371,7 +372,7 @@ TEST_CASE("Config::visit_items")
 {
   TestContext test_context;
 
-  Util::write_file(
+  util::write_file(
     "test.conf",
     "absolute_paths_in_stderr = true\n"
 #ifndef _WIN32
index d66e21f6277995c86c2f963ff71631b265325cd9..c546b1643bb8fc3c8d435cc9fcf7d12eee4d3d86 100644 (file)
@@ -24,6 +24,7 @@
 #include "TestUtil.hpp"
 
 #include <Fd.hpp>
+#include <util/file.hpp>
 
 #include "third_party/doctest.h"
 
@@ -99,7 +100,7 @@ TEST_CASE("Test lookup nonexistent")
   init(config);
 
   InodeCache inode_cache(config);
-  Util::write_file("a", "");
+  util::write_file("a", "");
 
   Digest digest;
   int return_value;
@@ -121,7 +122,7 @@ TEST_CASE("Test put and lookup")
   init(config);
 
   InodeCache inode_cache(config);
-  Util::write_file("a", "a text");
+  util::write_file("a", "a text");
 
   CHECK(put(inode_cache, "a", "a text", 1));
 
@@ -138,7 +139,7 @@ TEST_CASE("Test put and lookup")
   CHECK(inode_cache.get_misses() == 0);
   CHECK(inode_cache.get_errors() == 0);
 
-  Util::write_file("a", "something else");
+  util::write_file("a", "something else");
 
   CHECK(!inode_cache.get("a",
                          InodeCache::ContentType::checked_for_temporal_macros,
@@ -187,7 +188,7 @@ TEST_CASE("Test content type")
   init(config);
 
   InodeCache inode_cache(config);
-  Util::write_file("a", "a text");
+  util::write_file("a", "a text");
   Digest binary_digest = Hash().hash("binary").digest();
   Digest code_digest = Hash().hash("code").digest();
 
index a6e41b338cbc469ae868b533d523f757156fcdf9..09e4131802bf1d0c9944e7c039be4e928b1dd9e6 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 
 #include "third_party/doctest.h"
 
@@ -186,15 +187,15 @@ TEST_CASE("Same i-node as")
 {
   TestContext test_context;
 
-  Util::write_file("a", "");
-  Util::write_file("b", "");
+  util::write_file("a", "");
+  util::write_file("b", "");
   auto a_stat = Stat::stat("a");
   auto b_stat = Stat::stat("b");
 
   CHECK(a_stat.same_inode_as(a_stat));
   CHECK(!a_stat.same_inode_as(b_stat));
 
-  Util::write_file("a", "change size");
+  util::write_file("a", "change size");
   auto new_a_stat = Stat::stat("a");
   CHECK(new_a_stat.same_inode_as(a_stat));
 
@@ -233,7 +234,7 @@ TEST_CASE("Return values when file exists")
 {
   TestContext test_context;
 
-  Util::write_file("file", "1234567");
+  util::write_file("file", "1234567");
 
   auto stat = Stat::stat("file");
   CHECK(stat);
@@ -330,7 +331,7 @@ TEST_CASE("Symlinks" * doctest::skip(!symlinks_supported()))
 {
   TestContext test_context;
 
-  Util::write_file("file", "1234567");
+  util::write_file("file", "1234567");
 
 #ifdef _WIN32
   REQUIRE(CreateSymbolicLinkA(
@@ -413,7 +414,7 @@ TEST_CASE("Hard links")
 {
   TestContext test_context;
 
-  Util::write_file("a", "");
+  util::write_file("a", "");
 
 #ifdef _WIN32
   REQUIRE(CreateHardLinkA("b", "a", nullptr));
@@ -441,7 +442,7 @@ TEST_CASE("Hard links")
   CHECK(stat_a.inode() == stat_b.inode());
   CHECK(stat_a.same_inode_as(stat_b));
 
-  Util::write_file("a", "1234567");
+  util::write_file("a", "1234567");
   stat_a = Stat::stat("a");
   stat_b = Stat::stat("b");
 
@@ -532,7 +533,7 @@ TEST_CASE("Win32 Readonly File")
 {
   TestContext test_context;
 
-  Util::write_file("file", "");
+  util::write_file("file", "");
 
   DWORD prev_attrs = GetFileAttributesA("file");
   REQUIRE(prev_attrs != INVALID_FILE_ATTRIBUTES);
@@ -629,7 +630,7 @@ TEST_CASE("Win32 No Sharing")
   Finalizer cleanup([&] { CloseHandle(handle); });
 
   // Sanity check we can't open the file for read/write access.
-  REQUIRE_THROWS_AS(Util::read_file("file"), const core::Error&);
+  REQUIRE(!util::read_file<std::string>("file"));
 
   SUBCASE("stat file no sharing")
   {
index 821c7d2e363d368ca828df6e362ca5cd3ca63af8..4c77fe348b3fadf32cc9436bb9e025c228e5dbf2 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 
 #include "third_party/doctest.h"
 
@@ -131,7 +132,7 @@ TEST_CASE("Util::create_dir")
   CHECK(Util::create_dir("create/dir"));
   CHECK(Stat::stat("create/dir").is_directory());
 
-  Util::write_file("create/dir/file", "");
+  util::write_file("create/dir/file", "");
   CHECK(!Util::create_dir("create/dir/file"));
 }
 
@@ -175,7 +176,7 @@ TEST_CASE("Util::ensure_dir_exists")
   CHECK_NOTHROW(Util::ensure_dir_exists("create/dir"));
   CHECK(Stat::stat("create/dir").is_directory());
 
-  Util::write_file("create/dir/file", "");
+  util::write_file("create/dir/file", "");
   CHECK_THROWS_WITH(
     Util::ensure_dir_exists("create/dir/file"),
     "Failed to create directory create/dir/file: Not a directory");
@@ -346,17 +347,17 @@ TEST_CASE("Util::hard_link")
 
   SUBCASE("Link file to nonexistent destination")
   {
-    Util::write_file("old", "content");
+    util::write_file("old", "content");
     CHECK_NOTHROW(Util::hard_link("old", "new"));
-    CHECK(Util::read_file("new") == "content");
+    CHECK(*util::read_file<std::string>("new") == "content");
   }
 
   SUBCASE("Link file to existing destination")
   {
-    Util::write_file("old", "content");
-    Util::write_file("new", "other content");
+    util::write_file("old", "content");
+    util::write_file("new", "other content");
     CHECK_NOTHROW(Util::hard_link("old", "new"));
-    CHECK(Util::read_file("new") == "content");
+    CHECK(*util::read_file<std::string>("new") == "content");
   }
 
   SUBCASE("Link nonexistent file")
@@ -600,7 +601,7 @@ TEST_CASE("Util::normalize_concrete_absolute_path")
 #ifndef _WIN32
   TestContext test_context;
 
-  Util::write_file("file", "");
+  util::write_file("file", "");
   REQUIRE(Util::create_dir("dir1/dir2"));
   REQUIRE(symlink("dir1/dir2", "symlink") == 0);
   const auto cwd = Util::get_actual_cwd();
index 5de5eb2b03b7e2a2fa3d51be9b7b98abbe158c98..1a59f6a207435b2fbf287b842e701dfc187e190b 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <core/Statistic.hpp>
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 
 #include "third_party/doctest.h"
 
@@ -79,7 +80,7 @@ TEST_CASE("pass -fsyntax-only to compiler only")
   Context ctx;
 
   ctx.orig_args = Args::from_string("cc -c foo.c -fsyntax-only");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -96,7 +97,7 @@ TEST_CASE("dash_E_should_result_in_called_for_preprocessing")
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c foo.c -E");
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   CHECK(process_args(ctx).error == Statistic::called_for_preprocessing);
 }
 
@@ -107,7 +108,7 @@ TEST_CASE("dash_M_should_be_unsupported")
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c foo.c -M");
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   CHECK(process_args(ctx).error == Statistic::unsupported_compiler_option);
 }
 
@@ -119,7 +120,7 @@ TEST_CASE("dependency_args_to_preprocessor_if_run_second_cpp_is_false")
     " -Wp,-MT,wpmt -Wp,-MQ,wpmq -Wp,-MF,wpf";
   Context ctx;
   ctx.orig_args = Args::from_string("cc " + dep_args + " -c foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_run_second_cpp(false);
 
   const ProcessArgsResult result = process_args(ctx);
@@ -138,7 +139,7 @@ TEST_CASE("dependency_args_to_compiler_if_run_second_cpp_is_true")
     " -Wp,-MT,wpmt -Wp,-MQ,wpmq -Wp,-MF,wpf";
   Context ctx;
   ctx.orig_args = Args::from_string("cc " + dep_args + " -c foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -162,7 +163,7 @@ TEST_CASE("cpp_only_args_to_preprocessor_if_run_second_cpp_is_false")
   Context ctx;
   ctx.orig_args =
     Args::from_string("cc " + cpp_args + " " + dep_args + " -c foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_run_second_cpp(false);
 
   const ProcessArgsResult result = process_args(ctx);
@@ -188,7 +189,7 @@ TEST_CASE(
   Context ctx;
   ctx.orig_args =
     Args::from_string("cc " + cpp_args + " " + dep_args + " -c foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -206,7 +207,7 @@ TEST_CASE(
   const std::string dep_args = "-MMD -MFfoo.d -MT mt -MTmt -MQmq";
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c " + dep_args + " foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -221,7 +222,7 @@ TEST_CASE("MQ_flag_should_not_be_added_if_run_second_cpp_is_true")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c -MD foo.c -MF foo.d -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -236,7 +237,7 @@ TEST_CASE("MQ_flag_should_be_added_if_run_second_cpp_is_false")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c -MD foo.c -MF foo.d -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_run_second_cpp(false);
 
   const ProcessArgsResult result = process_args(ctx);
@@ -252,7 +253,7 @@ TEST_CASE("MF_should_be_added_if_run_second_cpp_is_false")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c -MD foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_run_second_cpp(false);
 
   const ProcessArgsResult result = process_args(ctx);
@@ -268,7 +269,7 @@ TEST_CASE("MF_should_not_be_added_if_run_second_cpp_is_true")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c -MD foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -283,7 +284,7 @@ TEST_CASE("equal_sign_after_MF_should_be_removed")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("cc -c -MF=path foo.c -o foo.o");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -299,7 +300,7 @@ TEST_CASE("sysroot_should_be_rewritten_if_basedir_is_used")
 
   Context ctx;
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_base_dir(get_root());
   std::string arg_string =
     FMT("cc --sysroot={}/foo/bar -c foo.c", ctx.actual_cwd);
@@ -317,7 +318,7 @@ TEST_CASE(
 
   Context ctx;
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_base_dir(get_root());
   std::string arg_string = FMT("cc --sysroot {}/foo -c foo.c", ctx.actual_cwd);
   ctx.orig_args = Args::from_string(arg_string);
@@ -336,7 +337,7 @@ TEST_CASE("MF_flag_with_immediate_argument_should_work_as_last_argument")
   ctx.orig_args =
     Args::from_string("cc -c foo.c -o foo.o -MMD -MT bar -MFfoo.d");
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
   CHECK(!result.error);
@@ -353,7 +354,7 @@ TEST_CASE("MT_flag_with_immediate_argument_should_work_as_last_argument")
   ctx.orig_args =
     Args::from_string("cc -c foo.c -o foo.o -MMD -MFfoo.d -MT foo -MTbar");
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
   CHECK(!result.error);
@@ -372,7 +373,7 @@ TEST_CASE("MQ_flag_with_immediate_argument_should_work_as_last_argument")
   ctx.orig_args =
     Args::from_string("cc -c foo.c -o foo.o -MMD -MFfoo.d -MQ foo -MQbar");
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
   CHECK(!result.error);
@@ -388,7 +389,7 @@ TEST_CASE("MQ_flag_without_immediate_argument_should_not_add_MQobj")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("gcc -c -MD -MP -MFfoo.d -MQ foo.d foo.c");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -404,7 +405,7 @@ TEST_CASE("MT_flag_without_immediate_argument_should_not_add_MTobj")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("gcc -c -MD -MP -MFfoo.d -MT foo.d foo.c");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -420,7 +421,7 @@ TEST_CASE("MQ_flag_with_immediate_argument_should_not_add_MQobj")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("gcc -c -MD -MP -MFfoo.d -MQfoo.d foo.c");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -435,7 +436,7 @@ TEST_CASE("MT_flag_with_immediate_argument_should_not_add_MQobj")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("gcc -c -MD -MP -MFfoo.d -MTfoo.d foo.c");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -452,7 +453,7 @@ TEST_CASE(
 
   Context ctx;
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_base_dir(get_root());
   std::string arg_string = FMT("cc -isystem {}/foo -c foo.c", ctx.actual_cwd);
   ctx.orig_args = Args::from_string(arg_string);
@@ -468,7 +469,7 @@ TEST_CASE("isystem_flag_with_concat_arg_should_be_rewritten_if_basedir_is_used")
 
   Context ctx;
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_base_dir("/"); // posix
   // Windows path doesn't work concatenated.
   std::string cwd = get_posix_path(ctx.actual_cwd);
@@ -486,7 +487,7 @@ TEST_CASE("I_flag_with_concat_arg_should_be_rewritten_if_basedir_is_used")
 
   Context ctx;
 
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
   ctx.config.set_base_dir("/"); // posix
   // Windows path doesn't work concatenated.
   std::string cwd = get_posix_path(ctx.actual_cwd);
@@ -503,7 +504,7 @@ TEST_CASE("debug_flag_order_with_known_option_first")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("cc -g1 -gsplit-dwarf foo.c -c");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -518,7 +519,7 @@ TEST_CASE("debug_flag_order_with_known_option_last")
   TestContext test_context;
   Context ctx;
   ctx.orig_args = Args::from_string("cc -gsplit-dwarf -g1 foo.c -c");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -534,7 +535,7 @@ TEST_CASE("options_not_to_be_passed_to_the_preprocessor")
   Context ctx;
   ctx.orig_args = Args::from_string(
     "cc -Wa,foo foo.c -g -c -DX -Werror -Xlinker fie -Xlinker,fum -Wno-error");
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -552,9 +553,9 @@ TEST_CASE("cuda_option_file")
   Context ctx;
   ctx.config.set_compiler_type(CompilerType::nvcc);
   ctx.orig_args = Args::from_string("nvcc -optf foo.optf,bar.optf");
-  Util::write_file("foo.c", "");
-  Util::write_file("foo.optf", "-c foo.c -g -Wall -o");
-  Util::write_file("bar.optf", "out -DX");
+  util::write_file("foo.c", "");
+  util::write_file("foo.optf", "-c foo.c -g -Wall -o");
+  util::write_file("bar.optf", "out -DX");
 
   const ProcessArgsResult result = process_args(ctx);
 
@@ -589,7 +590,7 @@ TEST_CASE("-Xclang")
   ctx.orig_args =
     Args::from_string("clang -c foo.c " + common_args + " " + color_diag + " "
                       + extra_args + " " + pch_pth_variants);
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   const ProcessArgsResult result = process_args(ctx);
   CHECK(result.preprocessor_args.to_string()
@@ -604,7 +605,7 @@ TEST_CASE("-x")
 {
   TestContext test_context;
   Context ctx;
-  Util::write_file("foo.c", "");
+  util::write_file("foo.c", "");
 
   SUBCASE("intel option")
   {
index b8d41197a4505ce05c18051de566f386bf7b77e2..30f3bdd72bb06a9d7ea4563d6b98fc4c266cd83e 100644 (file)
@@ -22,6 +22,7 @@
 #include "TestUtil.hpp"
 
 #include <core/wincompat.hpp>
+#include <util/file.hpp>
 
 #include "third_party/doctest.h"
 
@@ -186,7 +187,7 @@ TEST_CASE("guess_compiler")
   SUBCASE("Follow symlink to actual compiler")
   {
     const auto cwd = Util::get_actual_cwd();
-    Util::write_file(FMT("{}/gcc", cwd), "");
+    util::write_file(FMT("{}/gcc", cwd), "");
     CHECK(symlink("gcc", FMT("{}/intermediate", cwd).c_str()) == 0);
     const auto cc = FMT("{}/cc", cwd);
     CHECK(symlink("intermediate", cc.c_str()) == 0);
index 132288ade0d97cf86d9009feeee6ecf0e04f0b21..d31c7502fe740f937e607b042e6c059b241e71cc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -20,6 +20,7 @@
 
 #include <Util.hpp>
 #include <core/StatsLog.hpp>
+#include <util/file.hpp>
 
 #include <third_party/doctest.h>
 
@@ -33,7 +34,7 @@ TEST_CASE("read")
 {
   TestContext test_context;
 
-  Util::write_file("stats.log", "# comment\ndirect_cache_hit\n");
+  util::write_file("stats.log", "# comment\ndirect_cache_hit\n");
   const auto counters = StatsLog("stats.log").read();
 
   CHECK(counters.get(Statistic::direct_cache_hit) == 1);
@@ -48,7 +49,7 @@ TEST_CASE("log_result")
   stats_log.log_result("foo.c", {"cache_miss"});
   stats_log.log_result("bar.c", {"preprocessed_cache_hit"});
 
-  CHECK(Util::read_file("stats.log")
+  CHECK(*util::read_file<std::string>("stats.log")
         == "# foo.c\ncache_miss\n# bar.c\npreprocessed_cache_hit\n");
 }
 
index 3c1459fc3b19df4711eea702c6a2b825d33caeba..e6f62627c210125d3be2969d7e77e6592d1523e3 100644 (file)
@@ -20,6 +20,8 @@
 #include "../src/hashutil.hpp"
 #include "TestUtil.hpp"
 
+#include <util/file.hpp>
+
 #include "third_party/doctest.h"
 
 using TestUtil::TestContext;
@@ -74,12 +76,12 @@ TEST_CASE("hash_command_output_stdout_versus_stderr")
   Hash h2;
 
 #ifndef _WIN32
-  Util::write_file("stderr.sh", "#!/bin/sh\necho foo >&2\n");
+  util::write_file("stderr.sh", "#!/bin/sh\necho foo >&2\n");
   chmod("stderr.sh", 0555);
   CHECK(hash_command_output(h1, "echo foo", "not used"));
   CHECK(hash_command_output(h2, "./stderr.sh", "not used"));
 #else
-  Util::write_file("stderr.bat", "@echo off\r\necho foo>&2\r\n");
+  util::write_file("stderr.bat", "@echo off\r\necho foo>&2\r\n");
   CHECK(hash_command_output(h1, "echo foo", "not used"));
   CHECK(hash_command_output(h2, "stderr.bat", "not used"));
 #endif
@@ -92,12 +94,12 @@ TEST_CASE("hash_multicommand_output")
   Hash h2;
 
 #ifndef _WIN32
-  Util::write_file("foo.sh", "#!/bin/sh\necho foo\necho bar\n");
+  util::write_file("foo.sh", "#!/bin/sh\necho foo\necho bar\n");
   chmod("foo.sh", 0555);
   CHECK(hash_multicommand_output(h2, "echo foo; echo bar", "not used"));
   CHECK(hash_multicommand_output(h1, "./foo.sh", "not used"));
 #else
-  Util::write_file("foo.bat", "@echo off\r\necho foo\r\necho bar\r\n");
+  util::write_file("foo.bat", "@echo off\r\necho foo\r\necho bar\r\n");
   CHECK(hash_multicommand_output(h2, "echo foo; echo bar", "not used"));
   CHECK(hash_multicommand_output(h1, "foo.bat", "not used"));
 #endif
index 2a7cdadb9588a76bfa29f592e9ad189b4499e889..374d60c7d37f44964a4b4c64433562a406bc6e2d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2011-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -22,6 +22,7 @@
 #include <core/Statistic.hpp>
 #include <fmtmacros.hpp>
 #include <storage/primary/StatsFile.hpp>
+#include <util/file.hpp>
 
 #include <third_party/doctest.h>
 
@@ -45,7 +46,7 @@ TEST_CASE("Read bad")
 {
   TestContext test_context;
 
-  Util::write_file("test", "bad 1 2 3 4 5\n");
+  util::write_file("test", "bad 1 2 3 4 5\n");
   const auto counters = StatsFile("test").read();
 
   REQUIRE(counters.size() == static_cast<size_t>(Statistic::END));
@@ -56,7 +57,7 @@ TEST_CASE("Read existing")
 {
   TestContext test_context;
 
-  Util::write_file("test", "0 1 2 3 27 5\n");
+  util::write_file("test", "0 1 2 3 27 5\n");
   const auto counters = StatsFile("test").read();
 
   REQUIRE(counters.size() == static_cast<size_t>(Statistic::END));
@@ -74,7 +75,7 @@ TEST_CASE("Read future counters")
     content += FMT("{}\n", i);
   }
 
-  Util::write_file("test", content);
+  util::write_file("test", content);
   const auto counters = StatsFile("test").read();
 
   REQUIRE(counters.size() == count);
@@ -87,7 +88,7 @@ TEST_CASE("Update")
 {
   TestContext test_context;
 
-  Util::write_file("test", "0 1 2 3 27 5\n");
+  util::write_file("test", "0 1 2 3 27 5\n");
 
   auto counters = StatsFile("test").update([](auto& cs) {
     cs.increment(Statistic::internal_error, 1);
index 58d2742e1fc39337c63b8b0a7d0421e0d471c95e..f56cd33ff4b070c420963c6f71e85f1792ef6704 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <Util.hpp>
 #include <storage/primary/util.hpp>
+#include <util/file.hpp>
 
 #include <third_party/doctest.h>
 
@@ -77,10 +78,10 @@ TEST_CASE("storage::primary::get_level_1_files")
 
   Util::create_dir("0/1");
   Util::create_dir("0/f/c");
-  Util::write_file("0/file_a", "");
-  Util::write_file("0/1/file_b", "1");
-  Util::write_file("0/1/file_c", "12");
-  Util::write_file("0/f/c/file_d", "123");
+  util::write_file("0/file_a", "");
+  util::write_file("0/1/file_b", "1");
+  util::write_file("0/1/file_c", "12");
+  util::write_file("0/f/c/file_d", "123");
 
   auto null_receiver = [](double) {};
 
index 96979eeb33794d25d83388c089d79ab327655d6e..f8fe05db1bcd463d741437f3d43f6d8b4d4b90e8 100644 (file)
@@ -135,7 +135,7 @@ TEST_CASE("Break stale lock, blocking")
 {
   TestContext test_context;
 
-  Util::write_file("test.alive", "");
+  util::write_file("test.alive", "");
   const timespec long_time_ago{0, 0};
   util::set_timestamps("test.alive", long_time_ago);
   CHECK(symlink("foo", "test.lock") == 0);
@@ -149,7 +149,7 @@ TEST_CASE("Break stale lock, non-blocking")
 {
   TestContext test_context;
 
-  Util::write_file("test.alive", "");
+  util::write_file("test.alive", "");
   const timespec long_time_ago{0, 0};
   util::set_timestamps("test.alive", long_time_ago);
   CHECK(symlink("foo", "test.lock") == 0);