]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
refactor: Use FMT macro to format exception messages
authorJoel Rosdahl <joel@rosdahl.net>
Tue, 23 Aug 2022 16:21:57 +0000 (18:21 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 24 Aug 2022 17:16:48 +0000 (19:16 +0200)
Using the FMT macro explicitly makes invalid format message
constructions compile-time errors instead of run-time errors.

19 files changed:
src/AtomicFile.cpp
src/Config.cpp
src/Result.cpp
src/ResultExtractor.cpp
src/Stat.cpp
src/TemporaryFile.cpp
src/Util.cpp
src/ccache.cpp
src/compression/types.cpp
src/core/CacheEntryReader.cpp
src/core/Manifest.cpp
src/core/exceptions.hpp
src/core/mainoptions.cpp
src/execute.cpp
src/hashutil.cpp
src/storage/Storage.cpp
src/storage/primary/PrimaryStorage_compress.cpp
src/storage/secondary/HttpStorage.cpp
unittest/TestUtil.cpp

index 9585df816a46e2dfcdf9d3ef0cd61e7fdc005a3c..9d0753b4a1471ef14a56c68f01a3e985c69d03b3 100644 (file)
@@ -23,6 +23,7 @@
 #include "assertions.hpp"
 
 #include <core/exceptions.hpp>
+#include <fmtmacros.hpp>
 
 AtomicFile::AtomicFile(const std::string& path, Mode mode) : m_path(path)
 {
@@ -45,7 +46,7 @@ AtomicFile::write(const std::string& data)
 {
   if (fwrite(data.data(), data.size(), 1, m_stream) != 1) {
     throw core::Error(
-      "failed to write data to {}: {}", m_path, strerror(errno));
+      FMT("failed to write data to {}: {}", m_path, strerror(errno)));
   }
 }
 
@@ -54,7 +55,7 @@ AtomicFile::write(const util::Blob& data)
 {
   if (fwrite(data.data(), data.size(), 1, m_stream) != 1) {
     throw core::Error(
-      "failed to write data to {}: {}", m_path, strerror(errno));
+      FMT("failed to write data to {}: {}", m_path, strerror(errno)));
   }
 }
 
@@ -67,7 +68,7 @@ AtomicFile::commit()
   if (result == EOF) {
     Util::unlink_tmp(m_tmp_path);
     throw core::Error(
-      "failed to write data to {}: {}", m_path, strerror(errno));
+      FMT("failed to write data to {}: {}", m_path, strerror(errno)));
   }
   Util::rename(m_tmp_path, m_path);
 }
index d7c0ea93ac94ddb90458e1f11c03729aeec0a746..92a2a9748eafb3c1c4d2a1d9bfa158f0295dbbf2 100644 (file)
 #include "MiniTrace.hpp"
 #include "Util.hpp"
 #include "assertions.hpp"
-#include "fmtmacros.hpp"
 
 #include <UmaskScope.hpp>
 #include <compression/types.hpp>
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 #include <util/expected.hpp>
 #include <util/file.hpp>
 #include <util/path.hpp>
@@ -209,11 +209,11 @@ parse_bool(const std::string& value,
     if (value == "0" || lower_value == "false" || lower_value == "disable"
         || lower_value == "no") {
       throw core::Error(
-        "invalid boolean environment variable value \"{}\" (did you mean to"
-        " set \"CCACHE_{}{}=true\"?)",
-        value,
-        negate ? "" : "NO",
-        *env_var_key);
+        FMT("invalid boolean environment variable value \"{}\" (did you mean to"
+            " set \"CCACHE_{}{}=true\"?)",
+            value,
+            negate ? "" : "NO",
+            *env_var_key));
     }
     return !negate;
   } else if (value == "true") {
@@ -221,7 +221,7 @@ parse_bool(const std::string& value,
   } else if (value == "false") {
     return false;
   } else {
-    throw core::Error("not a boolean value: \"{}\"", value);
+    throw core::Error(FMT("not a boolean value: \"{}\"", value));
   }
 }
 
@@ -361,7 +361,7 @@ void
 verify_absolute_path(const std::string& value)
 {
   if (!util::is_absolute_path(value)) {
-    throw core::Error("not an absolute path: \"{}\"", value);
+    throw core::Error(FMT("not an absolute path: \"{}\"", value));
   }
 }
 
@@ -417,7 +417,7 @@ parse_config_file(const std::string& path,
       }
       config_line_handler(line, key, value);
     } catch (const core::Error& e) {
-      throw core::Error("{}:{}: {}", path, line_number, e.what());
+      throw core::Error(FMT("{}:{}: {}", path, line_number, e.what()));
     }
   }
   return true;
@@ -649,7 +649,8 @@ Config::update_from_environment()
     try {
       set_item(config_key, value, key, negate, "environment");
     } catch (const core::Error& e) {
-      throw core::Error("CCACHE_{}{}: {}", negate ? "NO" : "", key, e.what());
+      throw core::Error(
+        FMT("CCACHE_{}{}: {}", negate ? "NO" : "", key, e.what()));
     }
   }
 }
@@ -659,7 +660,7 @@ Config::get_string_value(const std::string& key) const
 {
   auto it = k_config_key_table.find(key);
   if (it == k_config_key_table.end()) {
-    throw core::Error("unknown configuration option \"{}\"", key);
+    throw core::Error(FMT("unknown configuration option \"{}\"", key));
   }
 
   switch (it->second) {
@@ -801,7 +802,7 @@ Config::set_value_in_file(const std::string& path,
   UmaskScope umask_scope(m_umask);
 
   if (k_config_key_table.find(key) == k_config_key_table.end()) {
-    throw core::Error("unknown configuration option \"{}\"", key);
+    throw core::Error(FMT("unknown configuration option \"{}\"", key));
   }
 
   // Verify that the value is valid; set_item will throw if not.
@@ -815,7 +816,7 @@ Config::set_value_in_file(const std::string& path,
     const auto result = util::write_file(resolved_path, "");
     if (!result) {
       throw core::Error(
-        "failed to write to {}: {}", resolved_path, result.error());
+        FMT("failed to write to {}: {}", resolved_path, result.error()));
     }
   }
 
@@ -832,7 +833,7 @@ Config::set_value_in_file(const std::string& path,
             output.write(FMT("{}\n", c_line));
           }
         })) {
-    throw core::Error("failed to open {}: {}", path, strerror(errno));
+    throw core::Error(FMT("failed to open {}: {}", path, strerror(errno)));
   }
 
   if (!found) {
@@ -1068,9 +1069,9 @@ Config::check_key_tables_consistency()
   for (const auto& [key, value] : k_env_variable_table) {
     if (k_config_key_table.find(value) == k_config_key_table.end()) {
       throw core::Error(
-        "env var {} mapped to {} which is missing from k_config_key_table",
-        key,
-        value);
+        FMT("env var {} mapped to {} which is missing from k_config_key_table",
+            key,
+            value));
     }
   }
 }
index 0129741181411e07967cea094f10cbd6daaf9a2f..5ad57f2c6981a72c36f1697ef6dd65201877b571 100644 (file)
@@ -26,7 +26,6 @@
 #include "Logging.hpp"
 #include "Stat.hpp"
 #include "Util.hpp"
-#include "fmtmacros.hpp"
 
 #include <ccache.hpp>
 #include <core/CacheEntryReader.hpp>
@@ -36,6 +35,7 @@
 #include <core/Statistic.hpp>
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 #include <util/path.hpp>
 
 #include <fcntl.h>
@@ -88,7 +88,7 @@ get_raw_file_path(std::string_view result_path, uint8_t entry_number)
     // To support more entries in the future, encode to [0-9a-z]. Note that
     // PrimaryStorage::evict currently assumes that the entry number is
     // represented as one character.
-    throw core::Error("Too high raw file entry number: {}", entry_number);
+    throw core::Error(FMT("Too high raw file entry number: {}", entry_number));
   }
 
   const auto prefix = result_path.substr(
@@ -204,20 +204,20 @@ void
 Reader::read(Consumer& consumer)
 {
   if (m_reader.header().entry_type != core::CacheEntryType::result) {
-    throw core::Error("Unexpected cache entry type: {}",
-                      to_string(m_reader.header().entry_type));
+    throw core::Error(FMT("Unexpected cache entry type: {}",
+                          to_string(m_reader.header().entry_type)));
   }
 
   const auto result_format_version = m_reader.read_int<uint8_t>();
   if (result_format_version != k_result_format_version) {
-    throw core::Error("Unknown result format version: {}",
-                      result_format_version);
+    throw core::Error(
+      FMT("Unknown result format version: {}", result_format_version));
   }
 
   const auto n_entries = m_reader.read_int<uint8_t>();
   if (n_entries >= k_max_raw_file_entries) {
-    throw core::Error(
-      "Too many raw file entries: {} > {}", n_entries, k_max_raw_file_entries);
+    throw core::Error(FMT(
+      "Too many raw file entries: {} > {}", n_entries, k_max_raw_file_entries));
   }
 
   uint8_t i;
@@ -226,7 +226,8 @@ Reader::read(Consumer& consumer)
   }
 
   if (i != n_entries) {
-    throw core::Error("Too few entries (read {}, expected {})", i, n_entries);
+    throw core::Error(
+      FMT("Too few entries (read {}, expected {})", i, n_entries));
   }
 
   m_reader.finalize();
@@ -243,7 +244,7 @@ Reader::read_entry(uint8_t entry_number, Reader::Consumer& consumer)
     break;
 
   default:
-    throw core::Error("Unknown entry type: {}", marker);
+    throw core::Error(FMT("Unknown entry type: {}", marker));
   }
 
   const auto type = m_reader.read_int<UnderlyingFileTypeInt>();
@@ -270,10 +271,10 @@ Reader::read_entry(uint8_t entry_number, Reader::Consumer& consumer)
       auto st = Stat::stat(raw_path, Stat::OnError::throw_error);
       if (st.size() != file_len) {
         throw core::Error(
-          "Bad file size of {} (actual {} bytes, expected {} bytes)",
-          raw_path,
-          st.size(),
-          file_len);
+          FMT("Bad file size of {} (actual {} bytes, expected {} bytes)",
+              raw_path,
+              st.size(),
+              file_len));
       }
     }
 
@@ -391,7 +392,7 @@ Result::Writer::write_embedded_file_entry(core::CacheEntryWriter& writer,
 {
   Fd file(open(path.c_str(), O_RDONLY | O_BINARY));
   if (!file) {
-    throw core::Error("Failed to open {} for reading", path);
+    throw core::Error(FMT("Failed to open {} for reading", path));
   }
 
   uint64_t remain = file_size;
@@ -403,10 +404,11 @@ Result::Writer::write_embedded_file_entry(core::CacheEntryWriter& writer,
       if (errno == EINTR) {
         continue;
       }
-      throw core::Error("Error reading from {}: {}", path, strerror(errno));
+      throw core::Error(
+        FMT("Error reading from {}: {}", path, strerror(errno)));
     }
     if (bytes_read == 0) {
-      throw core::Error("Error reading from {}: end of file", path);
+      throw core::Error(FMT("Error reading from {}: end of file", path));
     }
     writer.write(buf, bytes_read);
     remain -= bytes_read;
@@ -423,7 +425,7 @@ Result::Writer::write_raw_file_entry(const std::string& path,
     Util::clone_hard_link_or_copy_file(m_ctx, path, raw_file, true);
   } catch (core::Error& e) {
     throw core::Error(
-      "Failed to store {} as raw file {}: {}", path, raw_file, e.what());
+      FMT("Failed to store {} as raw file {}: {}", path, raw_file, e.what()));
   }
   const auto new_stat = Stat::stat(raw_file);
   return {
index 2c917d88a16febb24a6d715c363d55a88f81741f..ec38c01899a21d51ad277e5ec83198dd36f6ecbb 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 #include <util/file.hpp>
 
 #include <fcntl.h>
@@ -56,7 +57,7 @@ ResultExtractor::on_entry_start(uint8_t /*entry_number*/,
       open(m_dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666));
     if (!m_dest_fd) {
       throw core::Error(
-        "Failed to open {} for writing: {}", m_dest_path, strerror(errno));
+        FMT("Failed to open {} for writing: {}", m_dest_path, strerror(errno)));
     }
   } else if (raw_file->empty()) {
     PRINT_RAW(stderr,
@@ -66,7 +67,7 @@ ResultExtractor::on_entry_start(uint8_t /*entry_number*/,
       Util::copy_file(*raw_file, m_dest_path, false);
     } catch (core::Error& e) {
       throw core::Error(
-        "Failed to copy {} to {}: {}", *raw_file, m_dest_path, e.what());
+        FMT("Failed to copy {} to {}: {}", *raw_file, m_dest_path, e.what()));
     }
   }
 }
@@ -78,7 +79,8 @@ ResultExtractor::on_entry_data(const uint8_t* data, size_t size)
 
   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());
+    throw core::Error(
+      FMT("Failed to write to {}: {}", m_dest_path, result.error()));
   }
 }
 
index 6e8d44eb9acc46451a4bfc3fe4b4f6c96f2aa923..356bd920c63b0b3a34d3cf06bced885e34b166cf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -24,6 +24,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 
 #ifdef _WIN32
 #  include <third_party/win32/winerror_to_errno.h>
@@ -212,7 +213,7 @@ Stat::Stat(StatFunction stat_function,
   } else {
     m_errno = errno;
     if (on_error == OnError::throw_error) {
-      throw core::Error("failed to stat {}: {}", path, strerror(errno));
+      throw core::Error(FMT("failed to stat {}: {}", path, strerror(errno)));
     }
     if (on_error == OnError::log) {
       LOG("Failed to stat {}: {}", path, strerror(errno));
index 238dc011f587a936d15ed719d99cbce831b621e5..0d7e80bfb9bf0488e0eeca2d4cd6bdec1cb73f80 100644 (file)
@@ -51,7 +51,7 @@ TemporaryFile::TemporaryFile(std::string_view path_prefix,
 #endif
   if (!fd) {
     throw core::Fatal(
-      "Failed to create temporary file for {}: {}", path, strerror(errno));
+      FMT("Failed to create temporary file for {}: {}", path, strerror(errno)));
   }
 
   Util::set_cloexec_flag(*fd);
index c689fe6086e62ccfb99b61941d75075dd4e9a38f..4e713d9fa735f1af2ec7ac60184a3781a3b6037b 100644 (file)
 #include "Logging.hpp"
 #include "TemporaryFile.hpp"
 #include "Win32Util.hpp"
-#include "fmtmacros.hpp"
 
 #include <Finalizer.hpp>
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 #include <util/file.hpp>
 #include <util/path.hpp>
 #include <util/string.hpp>
@@ -226,7 +226,7 @@ clone_file(const std::string& src, const std::string& dest, bool via_tmp_file)
 #  if defined(__linux__)
   Fd src_fd(open(src.c_str(), O_RDONLY));
   if (!src_fd) {
-    throw core::Error("{}: {}", src, strerror(errno));
+    throw core::Error(FMT("{}: {}", src, strerror(errno)));
   }
 
   Fd dest_fd;
@@ -239,7 +239,7 @@ clone_file(const std::string& src, const std::string& dest, bool via_tmp_file)
     dest_fd =
       Fd(open(dest.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666));
     if (!dest_fd) {
-      throw core::Error("{}: {}", src, strerror(errno));
+      throw core::Error(FMT("{}: {}", src, strerror(errno)));
     }
   }
 
@@ -349,7 +349,7 @@ copy_file(const std::string& src, const std::string& dest, bool via_tmp_file)
 {
   Fd src_fd(open(src.c_str(), O_RDONLY | O_BINARY));
   if (!src_fd) {
-    throw core::Error("{}: {}", src, strerror(errno));
+    throw core::Error(FMT("{}: {}", src, strerror(errno)));
   }
 
   Fd dest_fd;
@@ -362,7 +362,7 @@ copy_file(const std::string& src, const std::string& dest, bool via_tmp_file)
     dest_fd =
       Fd(open(dest.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666));
     if (!dest_fd) {
-      throw core::Error("{}: {}", dest, strerror(errno));
+      throw core::Error(FMT("{}: {}", dest, strerror(errno)));
     }
   }
 
@@ -448,7 +448,7 @@ expand_environment_variables(const std::string& str)
         ++right;
       }
       if (curly && *right != '}') {
-        throw core::Error("syntax error: missing '}}' after \"{}\"", left);
+        throw core::Error(FMT("syntax error: missing '}}' after \"{}\"", left));
       }
       if (right == left) {
         // Special case: don't consider a single $ the left of a variable.
@@ -458,7 +458,7 @@ expand_environment_variables(const std::string& str)
         std::string name(left, right - left);
         const char* value = getenv(name.c_str());
         if (!value) {
-          throw core::Error("environment variable \"{}\" not set", name);
+          throw core::Error(FMT("environment variable \"{}\" not set", name));
         }
         result += value;
         if (!curly) {
@@ -574,7 +574,7 @@ ensure_dir_exists(std::string_view dir)
 {
   if (!create_dir(dir)) {
     throw core::Fatal(
-      "Failed to create directory {}: {}", dir, strerror(errno));
+      FMT("Failed to create directory {}: {}", dir, strerror(errno)));
   }
 }
 
@@ -738,15 +738,15 @@ hard_link(const std::string& oldpath, const std::string& newpath)
 #ifndef _WIN32
   if (link(oldpath.c_str(), newpath.c_str()) != 0) {
     throw core::Error(
-      "failed to link {} to {}: {}", oldpath, newpath, strerror(errno));
+      FMT("failed to link {} to {}: {}", oldpath, newpath, strerror(errno)));
   }
 #else
   if (!CreateHardLink(newpath.c_str(), oldpath.c_str(), nullptr)) {
     DWORD error = GetLastError();
-    throw core::Error("failed to link {} to {}: {}",
-                      oldpath,
-                      newpath,
-                      Win32Util::error_message(error));
+    throw core::Error(FMT("failed to link {} to {}: {}",
+                          oldpath,
+                          newpath,
+                          Win32Util::error_message(error)));
   }
 #endif
 }
@@ -977,8 +977,8 @@ parse_duration(const std::string& duration)
     factor = 1;
     break;
   default:
-    throw core::Error(
-      "invalid suffix (supported: d (day) and s (second)): \"{}\"", duration);
+    throw core::Error(FMT(
+      "invalid suffix (supported: d (day) and s (second)): \"{}\"", duration));
   }
 
   const auto value =
@@ -998,7 +998,7 @@ parse_size(const std::string& value)
   char* p;
   double result = strtod(value.c_str(), &p);
   if (errno != 0 || result < 0 || p == value.c_str() || value.empty()) {
-    throw core::Error("invalid size: \"{}\"", value);
+    throw core::Error(FMT("invalid size: \"{}\"", value));
   }
 
   while (isspace(*p)) {
@@ -1022,7 +1022,7 @@ parse_size(const std::string& value)
       result *= multiplier;
       break;
     default:
-      throw core::Error("invalid size: \"{}\"", value);
+      throw core::Error(FMT("invalid size: \"{}\"", value));
     }
   } else {
     // Default suffix: G.
@@ -1099,7 +1099,7 @@ rename(const std::string& oldpath, const std::string& newpath)
 #ifndef _WIN32
   if (::rename(oldpath.c_str(), newpath.c_str()) != 0) {
     throw core::Error(
-      "failed to rename {} to {}: {}", oldpath, newpath, strerror(errno));
+      FMT("failed to rename {} to {}: {}", oldpath, newpath, strerror(errno)));
   }
 #else
   // Windows' rename() won't overwrite an existing file, so need to use
@@ -1107,10 +1107,10 @@ rename(const std::string& oldpath, const std::string& newpath)
   if (!MoveFileExA(
         oldpath.c_str(), newpath.c_str(), MOVEFILE_REPLACE_EXISTING)) {
     DWORD error = GetLastError();
-    throw core::Error("failed to rename {} to {}: {}",
-                      oldpath,
-                      newpath,
-                      Win32Util::error_message(error));
+    throw core::Error(FMT("failed to rename {} to {}: {}",
+                          oldpath,
+                          newpath,
+                          Win32Util::error_message(error)));
   }
 #endif
 }
@@ -1146,7 +1146,7 @@ send_to_fd(const Context& ctx, const std::string& text, int fd)
   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());
+    throw core::Error(FMT("Failed to write to {}: {}", fd, result.error()));
   }
 }
 
@@ -1259,9 +1259,9 @@ traverse(const std::string& path, const TraverseVisitor& visitor)
           if (stat.error_number() == ENOENT || stat.error_number() == ESTALE) {
             continue;
           }
-          throw core::Error("failed to lstat {}: {}",
-                            entry_path,
-                            strerror(stat.error_number()));
+          throw core::Error(FMT("failed to lstat {}: {}",
+                                entry_path,
+                                strerror(stat.error_number())));
         }
         is_dir = stat.is_directory();
       }
@@ -1276,7 +1276,8 @@ traverse(const std::string& path, const TraverseVisitor& visitor)
   } else if (errno == ENOTDIR) {
     visitor(path, false);
   } else {
-    throw core::Error("failed to open directory {}: {}", path, strerror(errno));
+    throw core::Error(
+      FMT("failed to open directory {}: {}", path, strerror(errno)));
   }
 }
 
@@ -1299,7 +1300,8 @@ traverse(const std::string& path, const TraverseVisitor& visitor)
   } else if (std::filesystem::exists(path)) {
     visitor(path, false);
   } else {
-    throw core::Error("failed to open directory {}: {}", path, strerror(errno));
+    throw core::Error(
+      FMT("failed to open directory {}: {}", path, strerror(errno)));
   }
 }
 
@@ -1378,10 +1380,10 @@ wipe_path(const std::string& path)
   traverse(path, [](const std::string& p, bool is_dir) {
     if (is_dir) {
       if (rmdir(p.c_str()) != 0 && errno != ENOENT && errno != ESTALE) {
-        throw core::Error("failed to rmdir {}: {}", p, strerror(errno));
+        throw core::Error(FMT("failed to rmdir {}: {}", p, strerror(errno)));
       }
     } else if (unlink(p.c_str()) != 0 && errno != ENOENT && errno != ESTALE) {
-      throw core::Error("failed to unlink {}: {}", p, strerror(errno));
+      throw core::Error(FMT("failed to unlink {}: {}", p, strerror(errno)));
     }
   });
 }
index fe5bdf88b4d4d8a04c2c69d431476f8d86b76f7e..6b44e39e772bc82027638cdff4fbaed26ba6fec8 100644 (file)
@@ -151,7 +151,7 @@ add_prefix(const Context& ctx, Args& args, const std::string& prefix_command)
   for (const auto& word : Util::split_into_strings(prefix_command, " ")) {
     std::string path = find_executable(ctx, word, ctx.orig_args[0]);
     if (path.empty()) {
-      throw core::Fatal("{}: {}", word, strerror(errno));
+      throw core::Fatal(FMT("{}: {}", word, strerror(errno)));
     }
 
     prefix.push_back(path);
@@ -1927,7 +1927,8 @@ from_cache(Context& ctx, FromCacheCallMode mode, const Digest& result_key)
   try {
     File file(*result_path, "rb");
     if (!file) {
-      throw core::Error("Failed to open {}: {}", *result_path, strerror(errno));
+      throw core::Error(
+        FMT("Failed to open {}: {}", *result_path, strerror(errno)));
     }
     core::FileReader file_reader(file.get());
     core::CacheEntryReader cache_entry_reader(file_reader);
@@ -1978,7 +1979,7 @@ find_compiler(Context& ctx,
       : find_executable_function(ctx, compiler, ctx.orig_args[0]);
 
   if (resolved_compiler.empty()) {
-    throw core::Fatal("Could not find compiler \"{}\" in PATH", compiler);
+    throw core::Fatal(FMT("Could not find compiler \"{}\" in PATH", compiler));
   }
 
   if (Util::is_ccache_executable(resolved_compiler)) {
@@ -2148,7 +2149,7 @@ cache_compilation(int argc, const char* const* argv)
     auto execv_argv = saved_orig_args.to_argv();
     execute_noreturn(execv_argv.data(), saved_temp_dir);
     throw core::Fatal(
-      "execute_noreturn of {} failed: {}", execv_argv[0], strerror(errno));
+      FMT("execute_noreturn of {} failed: {}", execv_argv[0], strerror(errno)));
   }
 
   return EXIT_SUCCESS;
index d0e91f6099882ebc3bd63509f077bf4dde05c0b9..04e0e9df7fe49c5c18e026448c6dfb33936e1ad0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -22,6 +22,7 @@
 #include <Context.hpp>
 #include <assertions.hpp>
 #include <core/exceptions.hpp>
+#include <fmtmacros.hpp>
 
 namespace compression {
 
@@ -48,7 +49,7 @@ type_from_int(const uint8_t type)
     return Type::zstd;
   }
 
-  throw core::Error("Unknown type: {}", type);
+  throw core::Error(FMT("Unknown type: {}", type));
 }
 
 std::string
index 26ae366e26a36dafb571af5727fc36d5e8a91639..ea166d6d021291cddfd71e82dd8dd47c587750b7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -19,6 +19,7 @@
 #include "CacheEntryReader.hpp"
 
 #include <core/exceptions.hpp>
+#include <fmtmacros.hpp>
 
 namespace {
 
@@ -33,7 +34,7 @@ cache_entry_type_from_int(const uint8_t entry_type)
     return core::CacheEntryType::manifest;
     break;
   default:
-    throw core::Error("Unknown entry type: {}", entry_type);
+    throw core::Error(FMT("Unknown entry type: {}", entry_type));
   }
 }
 
@@ -46,12 +47,13 @@ CacheEntryReader::CacheEntryReader(core::Reader& reader)
 {
   const auto magic = m_checksumming_reader.read_int<uint16_t>();
   if (magic != core::k_ccache_magic) {
-    throw core::Error("Bad magic value: 0x{:04x}", magic);
+    throw core::Error(FMT("Bad magic value: 0x{:04x}", magic));
   }
 
   const auto entry_format_version = m_checksumming_reader.read_int<uint8_t>();
   if (entry_format_version != core::k_entry_format_version) {
-    throw core::Error("Unknown entry format version: {}", entry_format_version);
+    throw core::Error(
+      FMT("Unknown entry format version: {}", entry_format_version));
   }
 
   const auto entry_type = m_checksumming_reader.read_int<uint8_t>();
@@ -97,9 +99,10 @@ CacheEntryReader::finalize()
   const util::XXH3_128::Digest null_digest;
 
   if (actual != expected && actual != null_digest && expected != null_digest) {
-    throw core::Error("Incorrect checksum (actual {}, expected {})",
-                      Util::format_base16(actual.bytes(), actual.size()),
-                      Util::format_base16(expected.bytes(), expected.size()));
+    throw core::Error(
+      FMT("Incorrect checksum (actual {}, expected {})",
+          Util::format_base16(actual.bytes(), actual.size()),
+          Util::format_base16(expected.bytes(), expected.size())));
   }
 
   m_decompressor->finalize();
index f57c90e695cb8e6d6c200c2abe22c8c6b0242f8e..9bbe12964c403b086d3d53b526a896c2b810b056 100644 (file)
@@ -85,8 +85,8 @@ Manifest::read(Reader& reader)
 
   const auto format_version = reader.read_int<uint8_t>();
   if (format_version != k_format_version) {
-    throw core::Error(
-      "Unknown format version: {} != {}", format_version, k_format_version);
+    throw core::Error(FMT(
+      "Unknown format version: {} != {}", format_version, k_format_version));
   }
 
   const auto file_count = reader.read_int<uint32_t>();
index 1171b07ac4545724735ec3daa79ec5f9ee6f0f9d..7bdf5094302e6079d43e428f93ebe958ce096fda 100644 (file)
@@ -38,44 +38,14 @@ class ErrorBase : public std::runtime_error
 // treated similar to Fatal.
 class Error : public ErrorBase
 {
-public:
-  // Special case: If given only one string, don't parse it as a format string.
-  Error(const std::string& message);
-
-  // `args` are forwarded to `fmt::format`.
-  template<typename... T> inline Error(const char* format, T&&... args);
+  using ErrorBase::ErrorBase;
 };
 
-inline Error::Error(const std::string& message) : ErrorBase(message)
-{
-}
-
-template<typename... T>
-inline Error::Error(const char* format, T&&... args)
-  : ErrorBase(fmt::format(format, std::forward<T>(args)...))
-{
-}
-
 // Throw a Fatal to make ccache print the error message to stderr and exit
 // with a non-zero exit code.
 class Fatal : public ErrorBase
 {
-public:
-  // Special case: If given only one string, don't parse it as a format string.
-  Fatal(const std::string& message);
-
-  // `args` are forwarded to `fmt::format`.
-  template<typename... T> inline Fatal(const char* format, T&&... args);
+  using ErrorBase::ErrorBase;
 };
 
-inline Fatal::Fatal(const std::string& message) : ErrorBase(message)
-{
-}
-
-template<typename... T>
-inline Fatal::Fatal(const char* format, T&&... args)
-  : ErrorBase(fmt::format(format, std::forward<T>(args)...))
-{
-}
-
 } // namespace core
index cff3f884834ef5c6f2f59d7149535d93b7f8f291..87c318c43900a48e8d7fe609a17b8d5e715ad4fe 100644 (file)
@@ -251,8 +251,8 @@ trim_dir(const std::string& dir,
     if (!is_dir) {
       const auto name = Util::base_name(path);
       if (name == "ccache.conf" || name == "stats") {
-        throw Fatal("this looks like a primary cache directory (found {})",
-                    path);
+        throw Fatal(
+          FMT("this looks like a primary cache directory (found {})", path));
       }
       files.push_back({path, stat});
     }
@@ -541,7 +541,7 @@ process_main_options(int argc, const char* const* argv)
       // for the -o=K=V case (key "=K" and value "V").
       size_t eq_pos = arg.find('=', 1);
       if (eq_pos == std::string::npos) {
-        throw Error("missing equal sign in \"{}\"", arg);
+        throw Error(FMT("missing equal sign in \"{}\"", arg));
       }
       std::string key = arg.substr(0, eq_pos);
       std::string value = arg.substr(eq_pos + 1);
index 9d9e08b09c764bf1b14a936a23eadf0269ec6cde..a217d65815f1af7674e3258a1fdec1ee9ceba242 100644 (file)
 #include "TemporaryFile.hpp"
 #include "Util.hpp"
 #include "Win32Util.hpp"
-#include "fmtmacros.hpp"
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 #include <util/file.hpp>
 #include <util/path.hpp>
 
@@ -203,7 +203,7 @@ execute(Context& ctx, const char* const* argv, Fd&& fd_out, Fd&& fd_err)
   }
 
   if (ctx.compiler_pid == -1) {
-    throw core::Fatal("Failed to fork: {}", strerror(errno));
+    throw core::Fatal(FMT("Failed to fork: {}", strerror(errno)));
   }
 
   if (ctx.compiler_pid == 0) {
@@ -225,7 +225,7 @@ execute(Context& ctx, const char* const* argv, Fd&& fd_out, Fd&& fd_err)
     if (result == -1 && errno == EINTR) {
       continue;
     }
-    throw core::Fatal("waitpid failed: {}", strerror(errno));
+    throw core::Fatal(FMT("waitpid failed: {}", strerror(errno)));
   }
 
   {
index 251049af3a0bac05db9da5f6e14692edb7a25caa..990561ffa1b4ea4b5342614e13897aff75cbc4eb 100644 (file)
 #include "Util.hpp"
 #include "Win32Util.hpp"
 #include "execute.hpp"
-#include "fmtmacros.hpp"
 #include "macroskip.hpp"
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 #include <util/file.hpp>
 #include <util/string.hpp>
 
@@ -442,12 +442,12 @@ hash_command_output(Hash& hash,
 #else
   int pipefd[2];
   if (pipe(pipefd) == -1) {
-    throw core::Fatal("pipe failed: {}", strerror(errno));
+    throw core::Fatal(FMT("pipe failed: {}", strerror(errno)));
   }
 
   pid_t pid = fork();
   if (pid == -1) {
-    throw core::Fatal("fork failed: {}", strerror(errno));
+    throw core::Fatal(FMT("fork failed: {}", strerror(errno)));
   }
 
   if (pid == 0) {
index d56f8ec8b5f6ab39d937c51384f12dd7e50cd01d..e3f9b96365ede94eb6e671b0a91dbdb1d4db4cb1 100644 (file)
@@ -119,7 +119,8 @@ parse_storage_config(const std::string_view entry)
     Util::split_into_views(entry, "|", util::Tokenizer::Mode::include_empty);
 
   if (parts.empty() || parts.front().empty()) {
-    throw core::Error("secondary storage config must provide a URL: {}", entry);
+    throw core::Error(
+      FMT("secondary storage config must provide a URL: {}", entry));
   }
 
   SecondaryStorageConfig result;
@@ -131,11 +132,11 @@ parse_storage_config(const std::string_view entry)
   try {
     std::ignore = result.params.url.str();
   } catch (const std::exception& e) {
-    throw core::Error("Cannot parse URL {}: {}", url_str, e.what());
+    throw core::Error(FMT("Cannot parse URL {}: {}", url_str, e.what()));
   }
 
   if (result.params.url.scheme().empty()) {
-    throw core::Error("URL scheme must not be empty: {}", entry);
+    throw core::Error(FMT("URL scheme must not be empty: {}", entry));
   }
 
   for (size_t i = 1; i < parts.size(); ++i) {
@@ -150,8 +151,8 @@ parse_storage_config(const std::string_view entry)
       result.read_only = (value == "true");
     } else if (key == "shards") {
       if (url_str.find('*') == std::string::npos) {
-        throw core::Error(R"(Missing "*" in URL when using shards: "{}")",
-                          url_str);
+        throw core::Error(
+          FMT(R"(Missing "*" in URL when using shards: "{}")", url_str));
       }
       for (const auto& shard : util::Tokenizer(value, ",")) {
         double weight = 1.0;
@@ -159,13 +160,13 @@ parse_storage_config(const std::string_view entry)
         const auto lp_pos = shard.find('(');
         if (lp_pos != std::string_view::npos) {
           if (shard.back() != ')') {
-            throw core::Error("Invalid shard name: \"{}\"", shard);
+            throw core::Error(FMT("Invalid shard name: \"{}\"", shard));
           }
           weight =
             util::value_or_throw<core::Error>(util::parse_double(std::string(
               shard.substr(lp_pos + 1, shard.length() - lp_pos - 2))));
           if (weight < 0.0) {
-            throw core::Error("Invalid shard weight: \"{}\"", weight);
+            throw core::Error(FMT("Invalid shard weight: \"{}\"", weight));
           }
           name = shard.substr(0, lp_pos);
         } else {
@@ -278,7 +279,7 @@ Storage::get(const Digest& key,
   try {
     util::write_file(tmp_file.path, value);
   } catch (const core::Error& e) {
-    throw core::Fatal("Error writing to {}: {}", tmp_file.path, e.what());
+    throw core::Fatal(FMT("Error writing to {}: {}", tmp_file.path, e.what()));
   }
 
   if (share_hits) {
@@ -370,8 +371,8 @@ Storage::add_secondary_storages()
     redact_url_for_logging(url_for_logging);
     const auto storage = get_storage(config.params.url);
     if (!storage) {
-      throw core::Error("unknown secondary storage URL: {}",
-                        url_for_logging.str());
+      throw core::Error(
+        FMT("unknown secondary storage URL: {}", url_for_logging.str()));
     }
     m_secondary_storages.push_back(std::make_unique<SecondaryStorageEntry>(
       SecondaryStorageEntry{config, url_for_logging.str(), storage, {}}));
index 24fdbb7a417c9dcb8ce0340e9e1c8471d7334d91..1f54c487c4f0335cc7612d19740f97b0b40ab717 100644 (file)
@@ -121,7 +121,7 @@ open_file(const std::string& path, const char* const mode)
   File f(path, mode);
   if (!f) {
     throw core::Error(
-      "failed to open {} for reading: {}", path, strerror(errno));
+      FMT("failed to open {} for reading: {}", path, strerror(errno)));
   }
   return f;
 }
@@ -130,7 +130,7 @@ static std::unique_ptr<core::CacheEntryReader>
 create_reader(const CacheFile& cache_file, core::Reader& reader)
 {
   if (cache_file.type() == CacheFile::Type::unknown) {
-    throw core::Error("unknown file type for {}", cache_file.path());
+    throw core::Error(FMT("unknown file type for {}", cache_file.path()));
   }
 
   return std::make_unique<core::CacheEntryReader>(reader);
index 5fed19d0c83ba761da367755466be744709b50ae..5e11cfe6a37f93cb81d7875cc0faf478fb510a98 100644 (file)
@@ -86,8 +86,8 @@ std::string
 get_url(const Url& url)
 {
   if (url.host().empty()) {
-    throw core::Fatal("A host is required in HTTP storage URL \"{}\"",
-                      url.str());
+    throw core::Fatal(
+      FMT("A host is required in HTTP storage URL \"{}\"", url.str()));
   }
 
   // httplib requires a partial URL with just scheme, host and port.
@@ -101,8 +101,8 @@ HttpStorageBackend::HttpStorageBackend(const Params& params)
   if (!params.url.user_info().empty()) {
     const auto [user, password] = util::split_once(params.url.user_info(), ':');
     if (!password) {
-      throw core::Fatal("Expected username:password in URL but got \"{}\"",
-                        params.url.user_info());
+      throw core::Fatal(FMT("Expected username:password in URL but got \"{}\"",
+                            params.url.user_info()));
     }
     m_http_client.set_basic_auth(std::string(user), std::string(*password));
   }
index d97ddba91b7699765579f133ade730e1309952b9..ea8abc95200be3dffe1e4aff8426a8d1c224d204 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
 #include "TestUtil.hpp"
 
 #include "../src/Util.hpp"
-#include "../src/fmtmacros.hpp"
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>
@@ -57,7 +57,7 @@ check_chdir(const std::string& dir)
 {
   if (chdir(dir.c_str()) != 0) {
     throw core::Error(
-      "failed to change directory to {}: {}", dir, strerror(errno));
+      FMT("failed to change directory to {}: {}", dir, strerror(errno)));
   }
 }