// Ignore any error from fs::create_directories since we can't handle an error
// in another way in this context. The caller takes care of logging when
// trying to open the path for writing.
- fs::create_directories(prefix.parent_path());
+ std::ignore = fs::create_directories(prefix.parent_path());
char timestamp[100];
const auto tm = util::localtime(time_of_invocation);
// it's compiling an assembler file (see
// <https://bugs.llvm.org/show_bug.cgi?id=39782>): remove any preexisting
// output object file.
- util::remove_nfs_safe(ctx.args_info.output_obj, util::LogFailure::no);
+ std::ignore =
+ util::remove_nfs_safe(ctx.args_info.output_obj, util::LogFailure::no);
}
if (ctx.args_info.generating_diagnostics) {
}
if (ctx.args_info.generating_dependencies) {
- depfile::make_paths_relative_in_output_dep(ctx);
+ if (auto r = depfile::make_paths_relative_in_output_dep(ctx); !r) {
+ LOG("Failed to make paths relative in {}: {}",
+ ctx.args_info.output_dep,
+ r.error());
+ return tl::unexpected(Statistic::internal_error);
+ }
}
if (!ctx.args_info.expect_output_obj) {
}
if (is_clang_cu) {
- util::write_file(preprocessed_path, cpp_stdout_data);
+ if (auto r = util::write_file(preprocessed_path, cpp_stdout_data); !r) {
+ LOG("Failed to write {}: {}", preprocessed_path, r.error());
+ return tl::unexpected(Statistic::internal_error);
+ }
auto chunks =
util::split_preprocessed_file_from_clang_cuda(preprocessed_path);
for (size_t i = 0; i < chunks.size(); ++i) {
for (auto it = m_pending_tmp_files.rbegin(); it != m_pending_tmp_files.rend();
++it) {
- util::remove(*it, util::LogFailure::no);
+ std::ignore = util::remove(*it, util::LogFailure::no);
}
m_pending_tmp_files.clear();
}
-// Copyright (C) 2019-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
{
if (m_stream) {
// commit() was not called so remove the lingering temporary file.
- std::ignore = fclose(m_stream); // Not much to do if fclose fails here
- util::remove(m_tmp_path);
+ std::ignore = fclose(m_stream); // Not much to do if this fails
+ std::ignore = util::remove(m_tmp_path); // Or this
}
}
int retcode = fclose(m_stream);
m_stream = nullptr;
if (retcode == EOF) {
- util::remove(m_tmp_path);
+ std::ignore = util::remove(m_tmp_path);
throw core::Error(
FMT("failed to write data to {}: {}", m_path, strerror(errno)));
}
util::XXH3_128 checksum;
util::Fd fd(arg == "-" ? STDIN_FILENO : open(arg.c_str(), O_RDONLY));
if (fd) {
- util::read_fd(*fd, [&checksum](auto data) { checksum.update(data); });
+ auto r =
+ util::read_fd(*fd, [&checksum](auto data) { checksum.update(data); });
+ if (!r) {
+ PRINT(stderr, "Error: Failed to checksum {}: {}\n", arg, r.error());
+ return EXIT_FAILURE;
+ }
const auto digest = checksum.digest();
PRINT(stdout, "{}\n", util::format_base16(digest));
} else {
PRINT(stderr, "Error: Failed to checksum {}\n", arg);
+ return EXIT_FAILURE;
}
break;
}
#include <ccache/core/exceptions.hpp>
#include <ccache/hash.hpp>
#include <ccache/util/assertions.hpp>
+#include <ccache/util/expected.hpp>
#include <ccache/util/file.hpp>
#include <ccache/util/filesystem.hpp>
#include <ccache/util/format.hpp>
}
// Replace absolute paths with relative paths in the provided dependency file.
-void
+tl::expected<void, std::string>
make_paths_relative_in_output_dep(const Context& ctx)
{
if (ctx.config.base_dir().empty()) {
LOG_RAW("Base dir not set, skip using relative paths");
- return; // nothing to do
+ return {}; // nothing to do
}
const auto& output_dep = ctx.args_info.output_dep;
- const auto content = util::read_file<std::string>(output_dep);
- if (!content) {
- LOG("Failed to read dependency file {}: {}", output_dep, content.error());
- return;
- }
- const auto new_content = rewrite_source_paths(ctx, *content);
+ TRY_ASSIGN(auto content, util::read_file<std::string>(output_dep));
+ const auto new_content = rewrite_source_paths(ctx, content);
if (new_content) {
- util::write_file(output_dep, *new_content);
+ TRY(util::write_file(output_dep, *new_content));
} else {
LOG("No paths in dependency file {} made relative", output_dep);
}
+
+ return {};
}
std::vector<std::string>
class Context;
+#include <tl/expected.hpp>
+
#include <optional>
#include <string>
#include <string_view>
std::optional<std::string> rewrite_source_paths(const Context& ctx,
std::string_view file_content);
-void make_paths_relative_in_output_dep(const Context& ctx);
+tl::expected<void, std::string>
+make_paths_relative_in_output_dep(const Context& ctx);
// Split `text` into tokens. A colon token delimits the target tokens from
// dependency tokens. An empty token marks the end of an entry.
fs::path tmp_file_path;
DEFER([&] {
if (!tmp_file_path.empty()) {
- util::remove(tmp_file_path);
+ std::ignore = util::remove(tmp_file_path);
}
});
util::TemporaryFile::create(FMT("{}/cmd_args", temp_dir)));
LOG("Arguments from {}", tmp_file.path);
commandline = util::format_argv_as_win32_command_string(argv + 1, true);
- util::write_fd(*tmp_file.fd, commandline.data(), commandline.length());
+ if (auto r = util::write_fd(
+ *tmp_file.fd, commandline.data(), commandline.length());
+ !r) {
+ LOG("Failed to write {}: {}", tmp_file.path, r.error());
+ return -1;
+ }
commandline = FMT(R"("{}" "@{}")", argv[0], tmp_file.path);
tmp_file_path = tmp_file.path;
}
-// Copyright (C) 2020-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
k_version);
map->unmap();
m_fd.close();
- fs::remove(path);
+ std::ignore = util::remove(path);
return false;
}
m_map = std::move(*map);
// Delete any tmp files older than 1 hour right away.
if (file.mtime() + util::Duration(3600) < current_time
&& util::TemporaryFile::is_tmp_file(file.path())) {
- util::remove(file.path());
+ std::ignore = util::remove(file.path());
continue;
}
if (!l2_content_lock.acquire()) {
LOG("Not removing {} due to lock failure", cache_file.path);
}
- util::remove_nfs_safe(cache_file.path);
+ std::ignore = util::remove_nfs_safe(cache_file.path);
}
LOG("Removed {} from local storage ({})",
// run, but it's only we who can create the file entry now so we don't try
// to handle a race between remove() and create_hard_link() below.
- fs::remove(dest); // Ignore any error.
+ std::ignore = fs::remove(dest); // Ignore any error.
LOG("Hard linking {} to {}", source, dest);
if (auto result = fs::create_hard_link(source, dest); !result) {
LOG("Failed to hard link {} to {}: {}",
l2_progress_receiver(0.5);
for (size_t i = 0; i < files.size(); ++i) {
- util::remove_nfs_safe(files[i].path());
+ std::ignore = util::remove_nfs_safe(files[i].path());
l2_progress_receiver(0.5 + 0.5 * ratio(i, files.size()));
}
// Note: Two ccache processes may move the file at the same time, so failure
// to rename is OK.
LOG("Moving {} to {}", cache_file_path, wanted_path);
- fs::rename(cache_file_path, wanted_path);
+ std::ignore = fs::rename(cache_file_path, wanted_path);
for (const auto& [file_number, dest_path] : m_added_raw_files) {
- fs::rename(dest_path, get_raw_file_path(wanted_path, file_number));
+ std::ignore =
+ fs::rename(dest_path, get_raw_file_path(wanted_path, file_number));
}
}
}
LOG("Cleaning up {}", m_config.temporary_dir());
core::ensure_dir_exists(m_config.temporary_dir());
- util::traverse_directory(m_config.temporary_dir(), [now](const auto& de) {
+
+ auto remove_old = [now](const auto& de) {
if (de.is_directory()) {
return;
}
LOG("Removal failed: {}", result.error().message());
}
}
- }).or_else([&](const auto& error) {
- LOG("Failed to clean up {}: {}", m_config.temporary_dir(), error);
- });
+ };
+ if (auto r = util::traverse_directory(m_config.temporary_dir(), remove_old);
+ !r) {
+ LOG("Failed to clean up {}: {}", m_config.temporary_dir(), r.error());
+ }
- util::write_file(cleaned_stamp, "");
+ if (auto r = util::write_file(cleaned_stamp, ""); !r) {
+ LOG("Failed to create {}: {}", cleaned_stamp, r.error());
+ }
}
fs::path
pid_t pid;
auto argv_mutable = const_cast<char* const*>(argv.data());
- int result = posix_spawnp(&pid, argv[0], &fa, nullptr, argv_mutable, environ);
+ int spawn_result =
+ posix_spawnp(&pid, argv[0], &fa, nullptr, argv_mutable, environ);
int saved_errno = errno;
posix_spawn_file_actions_destroy(&fa);
close(pipefd[1]);
- if (result != 0) {
+ if (spawn_result != 0) {
close(pipefd[0]);
return tl::unexpected(
FMT("posix_spawnp failed: {}", strerror(saved_errno)));
}
- read_fd(pipefd[0], [&](auto data) {
+ auto read_result = read_fd(pipefd[0], [&](auto data) {
output.append(reinterpret_cast<const char*>(data.data()), data.size());
});
return tl::unexpected(FMT("waitpid failed: {}", strerror(errno)));
}
}
+ if (!read_result) {
+ return tl::unexpected(FMT("failed to read pipe: {}", read_result.error()));
+ }
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
return tl::unexpected(FMT("Non-zero exit code: {}", WEXITSTATUS(status)));
}
-// Copyright (C) 2021-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
static tl::expected<void, std::string>
copy_fd(int src_fd, int dst_fd)
{
- return read_fd(src_fd, [&](nonstd::span<const uint8_t> data) {
- write_fd(dst_fd, data.data(), data.size());
+ std::optional<std::string> write_error;
+ auto read_result = read_fd(src_fd, [&](nonstd::span<const uint8_t> data) {
+ auto result = write_fd(dst_fd, data.data(), data.size());
+ if (!result) {
+ write_error = result.error();
+ }
});
+ if (write_error) {
+ return tl::unexpected(
+ FMT("failed to write to FD {}: {}", dst_fd, *write_error));
+ }
+ if (!read_result) {
+ return tl::unexpected(
+ FMT("failed to read from FD {}: {}", src_fd, read_result.error()));
+ }
+ return {};
}
static tl::expected<void, std::string>
is_dir = dir_entry.is_directory();
}
if (is_dir) {
- traverse_directory(path, visitor);
+ TRY(traverse_directory(path, visitor));
} else {
visitor(path);
}
try {
for (const auto& entry : fs::directory_iterator(directory)) {
if (entry.is_directory()) {
- traverse_directory(entry.path(), visitor);
+ TRY(traverse_directory(entry.path(), visitor));
} else {
visitor(entry.path());
}
if (m_lock_manager) {
m_lock_manager->deregister_alive_file(m_alive_file);
}
- fs::remove(m_alive_file);
- fs::remove(m_lock_file);
+ if (auto r = fs::remove(m_alive_file); !r) {
+ LOG("Failed to remove {}: {}", m_alive_file, r.error());
+ }
+ if (auto r = fs::remove(m_lock_file); !r) {
+ LOG("Failed to remove {}: {}", m_lock_file, r.error());
+ }
#else
CloseHandle(m_handle);
#endif
-// Copyright (C) 2010-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2010-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <ccache/util/environment.hpp>
+#include <ccache/util/expected.hpp>
#include <ccache/util/filesystem.hpp>
#include <ccache/util/format.hpp>
#include <ccache/util/path.hpp>
# include <unistd.h>
#endif
+#include <string>
+
namespace fs = util::filesystem;
-int
-main(int argc, char** argv)
+tl::expected<int, std::error_code>
+prepare_test(int argc, char** argv)
{
-#ifdef _WIN32
- util::setenv("_CCACHE_TEST", "1");
-#endif
- util::unsetenv("GCC_COLORS"); // Don't confuse argument processing tests.
-
auto dir_before = *fs::current_path();
- std::string testdir = FMT("testdir/{}", getpid());
- fs::remove_all(testdir);
- fs::create_directories(testdir);
- fs::current_path(testdir);
+ fs::path testdir = FMT("testdir/{}", getpid());
+
+ TRY(fs::remove_all(testdir));
+ TRY(fs::create_directories(testdir));
+ TRY(fs::current_path(testdir));
doctest::Context context;
context.applyCommandLine(argc, argv);
int result = context.run();
- if (result == 0) {
- fs::current_path(dir_before);
- fs::remove_all(testdir);
+ if (result == EXIT_SUCCESS) {
+ TRY(fs::current_path(dir_before));
+ TRY(fs::remove_all(testdir));
} else {
PRINT(stderr, "Note: Test data has been left in {}\n", testdir);
}
return result;
}
+
+int
+main(int argc, char** argv)
+{
+#ifdef _WIN32
+ util::setenv("_CCACHE_TEST", "1");
+#endif
+ util::unsetenv("GCC_COLORS"); // Don't confuse argument processing tests.
+
+ auto result = prepare_test(argc, argv);
+ if (result) {
+ return *result;
+ } else {
+ PRINT(stderr, "error: {}\n", result.error());
+ return EXIT_FAILURE;
+ }
+}
Context ctx;
ctx.orig_args = Args::from_string("cc -c foo.c -fsyntax-only");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
Context ctx;
ctx.orig_args = Args::from_string("cc -c foo.c -E");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
CHECK(process_args(ctx).error() == Statistic::called_for_preprocessing);
}
Context ctx;
ctx.orig_args = Args::from_string("cc -c foo.c -M");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
CHECK(process_args(ctx).error() == Statistic::unsupported_compiler_option);
}
" -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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
Context ctx;
ctx.orig_args =
Args::from_string("cc " + cpp_args + " " + dep_args + " -c foo.c -o foo.o");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
Context ctx;
- util::write_file("foo.c", "");
+ REQUIRE(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);
Context ctx;
- util::write_file("foo.c", "");
+ REQUIRE(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);
Context ctx;
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
ctx.config.set_base_dir(get_root());
std::string arg_string =
FMT("cc -fbuild-session-file={}/foo/bar -c foo.c", ctx.actual_cwd);
{"sloppiness", "ivfsoverlay"}
});
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
ctx.config.set_base_dir(get_root());
std::string arg_string =
FMT("cc -ivfsoverlay {}/foo -c foo.c", ctx.actual_cwd);
{"sloppiness", "modules"}
});
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
ctx.config.set_base_dir(get_root());
std::string arg_string =
FMT("cc -fmodules-cache-path={}/foo/bar -c foo.c", ctx.actual_cwd);
{"sloppiness", "modules"}
});
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
ctx.config.set_base_dir(get_root());
std::string arg_string =
FMT("cc -fmodule-map-file={}/foo/bar -c foo.c", ctx.actual_cwd);
ctx.orig_args =
Args::from_string("cc -c foo.c -o foo.o -MMD -MT bar -MFfoo.d");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
CHECK(result);
ctx.orig_args =
Args::from_string("cc -c foo.c -o foo.o -MMD -MFfoo.d -MT foo -MTbar");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
CHECK(result);
ctx.orig_args =
Args::from_string("cc -c foo.c -o foo.o -MMD -MFfoo.d -MQ foo -MQbar");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
CHECK(result);
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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
Context ctx;
- util::write_file("foo.c", "");
+ REQUIRE(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);
Context ctx;
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
ctx.config.set_base_dir("/");
std::string cwd = ctx.actual_cwd;
std::string arg_string = FMT("cc -isystem{}/foo -c foo.c", cwd);
Context ctx;
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
ctx.config.set_base_dir("/");
std::string cwd = *fs::current_path();
std::string arg_string = FMT("cc -I{}/foo -c foo.c", cwd);
TestContext test_context;
Context ctx;
ctx.orig_args = Args::from_string("cc -g1 -gsplit-dwarf foo.c -c");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
TestContext test_context;
Context ctx;
ctx.orig_args = Args::from_string("cc -gsplit-dwarf -g1 foo.c -c");
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
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", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
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");
+ REQUIRE(util::write_file("foo.c", ""));
+ REQUIRE(util::write_file("foo.optf", "-c foo.c -g -Wall -o"));
+ REQUIRE(util::write_file("bar.optf", "out -DX"));
const auto result = process_args(ctx);
ctx.config.set_compiler_type(CompilerType::nvcc);
ctx.orig_args =
Args::from_string("nvcc -Werror all-warnings -Xcompiler -Werror -c foo.cu");
- util::write_file("foo.cu", "");
+ REQUIRE(util::write_file("foo.cu", ""));
const auto result = process_args(ctx);
CHECK(result);
ctx.config.set_compiler_type(CompilerType::nvcc);
ctx.orig_args = Args::from_string(
"nvcc --Werror all-warnings -Xcompiler -Werror -c foo.cu");
- util::write_file("foo.cu", "");
+ REQUIRE(util::write_file("foo.cu", ""));
const auto result = process_args(ctx);
CHECK(result);
ctx.orig_args =
Args::from_string("clang -c foo.c " + common_args + " " + color_diag + " "
+ extra_args + " " + pch_pth_variants);
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
const auto result = process_args(ctx);
CHECK(result->preprocessor_args.to_string()
{
TestContext test_context;
Context ctx;
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
SUBCASE("intel option")
{
Context ctx;
ctx.config.set_compiler_type(CompilerType::msvc);
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
ctx.orig_args = Args::from_string(
FMT("cl.exe /Fobar.obj /c {}/foo.c /foobar", ctx.actual_cwd));
TestContext test_context;
Context ctx;
ctx.config.set_compiler_type(CompilerType::msvc);
- util::write_file("foo.cpp", "");
- util::write_file("pch.h", "");
- util::write_file("pch.cpp", "");
+ REQUIRE(util::write_file("foo.cpp", ""));
+ REQUIRE(util::write_file("pch.h", ""));
+ REQUIRE(util::write_file("pch.cpp", ""));
SUBCASE("Create PCH")
{
== "cl.exe /Ycpch.h /Fppch.cpp.pch /FIpch.h /c");
}
- util::write_file("pch.cpp.pch", "");
+ REQUIRE(util::write_file("pch.cpp.pch", ""));
ctx.config.update_from_map({
{"sloppiness", "pch_defines,time_macros"}
});
TestContext test_context;
Context ctx;
ctx.config.set_compiler_type(CompilerType::msvc);
- util::write_file("foo.cpp", "");
- util::write_file("pch.h", "");
- util::write_file("pch.cpp", "");
+ REQUIRE(util::write_file("foo.cpp", ""));
+ REQUIRE(util::write_file("pch.h", ""));
+ REQUIRE(util::write_file("pch.cpp", ""));
SUBCASE("Create PCH")
{
== "cl.exe /Yc /Fppch.cpp.pch /FIpch.h /c");
}
- util::write_file("pch.cpp.pch", "");
+ REQUIRE(util::write_file("pch.cpp.pch", ""));
ctx.config.update_from_map({
{"sloppiness", "pch_defines,time_macros"}
});
TestContext test_context;
Context ctx;
ctx.config.set_compiler_type(CompilerType::msvc);
- util::write_file("foo.cpp", "");
- util::write_file("pch.h", "");
- util::write_file("pch.cpp", "");
+ REQUIRE(util::write_file("foo.cpp", ""));
+ REQUIRE(util::write_file("pch.h", ""));
+ REQUIRE(util::write_file("pch.cpp", ""));
SUBCASE("Create PCH")
{
CHECK(result->compiler_args.to_string() == "cl.exe /Yc /c");
}
- util::write_file("pch.pch", "");
+ REQUIRE(util::write_file("pch.pch", ""));
ctx.config.update_from_map({
{"sloppiness", "pch_defines,time_macros"}
});
TestContext test_context;
Context ctx;
ctx.config.set_compiler_type(CompilerType::msvc);
- util::write_file("foo.cpp", "");
- util::write_file("pch.h", "");
- util::write_file("pch.cpp", "");
+ REQUIRE(util::write_file("foo.cpp", ""));
+ REQUIRE(util::write_file("pch.h", ""));
+ REQUIRE(util::write_file("pch.cpp", ""));
SUBCASE("Create PCH")
{
CHECK(result->compiler_args.to_string() == "cl.exe /Yc /c");
}
- util::write_file("pch.pch", "");
+ REQUIRE(util::write_file("pch.pch", ""));
ctx.config.update_from_map({
{"sloppiness", "pch_defines,time_macros"}
});
TestContext test_context;
Context ctx;
ctx.config.set_compiler_type(CompilerType::msvc);
- util::write_file("pch.h", "");
- util::write_file("pch.cpp", "");
+ REQUIRE(util::write_file("pch.h", ""));
+ REQUIRE(util::write_file("pch.cpp", ""));
SUBCASE("/Fp with absolute folder path")
{
TestContext test_context;
Context ctx;
ctx.config.set_compiler_type(CompilerType::msvc);
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
SUBCASE("Only /Z7")
{
TestContext test_context;
Context ctx;
ctx.config.set_compiler_type(CompilerType::clang_cl);
- util::write_file("foo.c", "");
+ REQUIRE(util::write_file("foo.c", ""));
SUBCASE("/Z7")
{
SUBCASE("Follow symlink to actual compiler")
{
const auto cwd = *fs::current_path();
- util::write_file(cwd / "gcc", "");
+ REQUIRE(util::write_file(cwd / "gcc", ""));
CHECK(fs::create_symlink("gcc", cwd / "intermediate"));
const auto cc = cwd / "cc";
CHECK(fs::create_symlink("intermediate", cc));
SUBCASE("Classify clang-cl symlink to clang")
{
const auto cwd = *fs::current_path();
- util::write_file(cwd / "clang", "");
+ REQUIRE(util::write_file(cwd / "clang", ""));
const auto clang_cl = cwd / "clang-cl";
CHECK(fs::create_symlink("clang", clang_cl));
const auto cwd = *fs::current_path();
const auto cc = cwd / "cc";
const auto gcc = cwd / "gcc";
- util::write_file(cwd / "cc", "");
+ REQUIRE(util::write_file(cwd / "cc", ""));
CHECK(fs::create_hard_link(cc, gcc));
CHECK(guess_compiler(cc) == CompilerType::gcc);
const auto cwd = *fs::current_path();
const auto cc = cwd / "cc";
const auto clang = cwd / "clang";
- util::write_file(cwd / "cc", "");
+ REQUIRE(util::write_file(cwd / "cc", ""));
CHECK(fs::create_hard_link(cc, clang));
CHECK(guess_compiler(cc) == CompilerType::clang);
const auto cc = cwd / "cc";
const auto gcc = cwd / "gcc";
const auto clang = cwd / "clang";
- util::write_file(cwd / "cc", "");
+ REQUIRE(util::write_file(cwd / "cc", ""));
CHECK(fs::create_hard_link(cc, gcc));
CHECK(fs::create_hard_link(cc, clang));
std::string base_dir = FMT("C:/{0}/foo/{0}", user);
#endif
- util::write_file(
+ REQUIRE(util::write_file(
"ccache.conf",
- "base_dir = " + base_dir + "\n"
- "cache_dir=\n"
- "cache_dir = $USER$/${USER}/.ccache\n"
- "\n"
- "\n"
- " #A comment\n"
- "\t compiler = foo\n"
- "compiler_check = none\n"
- "compiler_type = nvcc\n"
- "compression=false\n"
- "compression_level= 2\n"
- "cpp_extension = .foo\n"
- "debug_dir = $USER$/${USER}/.ccache_debug\n"
- "debug_level = 2\n"
- "depend_mode = true\n"
- "direct_mode = false\n"
- "disable = true\n"
- "extra_files_to_hash = a:b c:$USER\n"
- "file_clone = true\n"
- "hard_link = true\n"
- "hash_dir = false\n"
- "ignore_headers_in_manifest = a:b/c\n"
- "ignore_options = -a=* -b\n"
- "inode_cache = false\n"
- "keep_comments_cpp = true\n"
- "log_file = $USER${USER} \n"
- "max_files = 17\n"
- "max_size = 123M\n"
- "msvc_dep_prefix = Some other prefix:\n"
- "path = $USER.x\n"
- "pch_external_checksum = true\n"
- "prefix_command = x$USER\n"
- "prefix_command_cpp = y\n"
- "read_only = true\n"
- "read_only_direct = true\n"
- "recache = true\n"
- "reshare = true\n"
- "sloppiness = time_macros ,include_file_mtime"
- " include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines"
- " , no_system_headers,system_headers,clang_index_store,ivfsoverlay,"
- " gcno_cwd,\n"
- "stats = false\n"
- "temporary_dir = ${USER}_foo\n"
- "umask = 777"); // Note: no newline.
+ "base_dir = " + base_dir
+ + "\n"
+ "cache_dir=\n"
+ "cache_dir = $USER$/${USER}/.ccache\n"
+ "\n"
+ "\n"
+ " #A comment\n"
+ "\t compiler = foo\n"
+ "compiler_check = none\n"
+ "compiler_type = nvcc\n"
+ "compression=false\n"
+ "compression_level= 2\n"
+ "cpp_extension = .foo\n"
+ "debug_dir = $USER$/${USER}/.ccache_debug\n"
+ "debug_level = 2\n"
+ "depend_mode = true\n"
+ "direct_mode = false\n"
+ "disable = true\n"
+ "extra_files_to_hash = a:b c:$USER\n"
+ "file_clone = true\n"
+ "hard_link = true\n"
+ "hash_dir = false\n"
+ "ignore_headers_in_manifest = a:b/c\n"
+ "ignore_options = -a=* -b\n"
+ "inode_cache = false\n"
+ "keep_comments_cpp = true\n"
+ "log_file = $USER${USER} \n"
+ "max_files = 17\n"
+ "max_size = 123M\n"
+ "msvc_dep_prefix = Some other prefix:\n"
+ "path = $USER.x\n"
+ "pch_external_checksum = true\n"
+ "prefix_command = x$USER\n"
+ "prefix_command_cpp = y\n"
+ "read_only = true\n"
+ "read_only_direct = true\n"
+ "recache = true\n"
+ "reshare = true\n"
+ "sloppiness = time_macros ,include_file_mtime"
+ " "
+ "include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_"
+ "defines"
+ " , no_system_headers,system_headers,clang_index_store,ivfsoverlay,"
+ " gcno_cwd,\n"
+ "stats = false\n"
+ "temporary_dir = ${USER}_foo\n"
+ "umask = 777")); // Note: no newline.
Config config;
REQUIRE(config.update_from_file("ccache.conf"));
SUBCASE("missing equal sign")
{
- util::write_file("ccache.conf", "no equal sign");
+ REQUIRE(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");
+ REQUIRE(util::write_file("ccache.conf", "# Comment\nfoo = bar"));
CHECK(config.update_from_file("ccache.conf"));
}
SUBCASE("invalid bool")
{
- util::write_file("ccache.conf", "disable=");
+ REQUIRE(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");
+ REQUIRE(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");
+ REQUIRE(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\"");
SUBCASE("empty umask")
{
- util::write_file("ccache.conf", "umask = ");
+ REQUIRE(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");
+ REQUIRE(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.
SUBCASE("unknown sloppiness")
{
- util::write_file("ccache.conf", "sloppiness = time_macros, foo");
+ REQUIRE(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));
SUBCASE("invalid unsigned")
{
- util::write_file("ccache.conf", "max_files =");
+ REQUIRE(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");
+ REQUIRE(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");
+ REQUIRE(util::write_file("ccache.conf", "max_files = foo"));
REQUIRE_THROWS_WITH(config.update_from_file("ccache.conf"),
"ccache.conf:1: invalid unsigned integer: \"foo\"");
}
SUBCASE("relative base dir")
{
- util::write_file("ccache.conf", "base_dir = relative/path");
+ REQUIRE(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 =");
+ REQUIRE(util::write_file("ccache.conf", "base_dir ="));
CHECK(config.update_from_file("ccache.conf"));
}
}
SUBCASE("from config gcc")
{
- util::write_file("ccache.conf", "response_file_format = posix");
+ REQUIRE(util::write_file("ccache.conf", "response_file_format = posix"));
CHECK(config.update_from_file("ccache.conf"));
CHECK(config.response_file_format() == ResponseFileFormat::posix);
SUBCASE("from config msvc")
{
- util::write_file("ccache.conf", "response_file_format = windows");
+ REQUIRE(util::write_file("ccache.conf", "response_file_format = windows"));
CHECK(config.update_from_file("ccache.conf"));
CHECK(config.response_file_format() == ResponseFileFormat::windows);
SUBCASE("from config msvc with clang compiler")
{
- util::write_file("ccache.conf",
- "response_file_format = windows\ncompiler_type = clang");
+ REQUIRE(util::write_file(
+ "ccache.conf", "response_file_format = windows\ncompiler_type = clang"));
CHECK(config.update_from_file("ccache.conf"));
CHECK(config.response_file_format() == ResponseFileFormat::windows);
SUBCASE("guess from compiler gcc")
{
- util::write_file("ccache.conf", "compiler_type = clang");
+ REQUIRE(util::write_file("ccache.conf", "compiler_type = clang"));
CHECK(config.update_from_file("ccache.conf"));
CHECK(config.response_file_format() == ResponseFileFormat::posix);
SUBCASE("guess from compiler msvc")
{
- util::write_file("ccache.conf", "compiler_type = msvc");
+ REQUIRE(util::write_file("ccache.conf", "compiler_type = msvc"));
CHECK(config.update_from_file("ccache.conf"));
CHECK(config.response_file_format() == ResponseFileFormat::windows);
SUBCASE("set new value")
{
- util::write_file("ccache.conf", "path = vanilla\n");
+ REQUIRE(util::write_file("ccache.conf", "path = vanilla\n"));
config.set_value_in_file("ccache.conf", "compiler", "chocolate");
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");
+ REQUIRE(
+ 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<std::string>("ccache.conf");
CHECK(content == "path = vanilla\nstats = chocolate\n");
SUBCASE("unknown option")
{
- util::write_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
+ REQUIRE(
+ util::write_file("ccache.conf", "path = chocolate\nstats = chocolate\n"));
try {
config.set_value_in_file("ccache.conf", "foo", "bar");
CHECK(false);
SUBCASE("unknown sloppiness")
{
- util::write_file("ccache.conf", "path = vanilla\n");
+ REQUIRE(util::write_file("ccache.conf", "path = vanilla\n"));
config.set_value_in_file("ccache.conf", "sloppiness", "foo");
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");
+ REQUIRE(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<std::string>("ccache.conf");
{
TestContext test_context;
- util::write_file(
- "test.conf",
- "absolute_paths_in_stderr = true\n"
#ifndef _WIN32
- "base_dir = /bd\n"
+# define BASE_DIR "/bd\n"
#else
- "base_dir = C:\\bd\n"
+# define BASE_DIR "C:\\bd\n"
#endif
+
+ REQUIRE(util::write_file(
+ "test.conf",
+ "absolute_paths_in_stderr = true\n"
+ "base_dir = " BASE_DIR
"cache_dir = cd\n"
"compiler = c\n"
"compiler_check = cc\n"
"stats = false\n"
"stats_log = sl\n"
"temporary_dir = td\n"
- "umask = 022\n");
+ "umask = 022\n"));
+#undef BASE_DIR
Config config;
config.update_from_file("test.conf");
CHECK_NOTHROW(core::ensure_dir_exists("create/dir"));
CHECK(DirEntry("create/dir").is_directory());
- util::write_file("create/dir/file", "");
+ REQUIRE(util::write_file("create/dir/file", ""));
CHECK_THROWS_AS(core::ensure_dir_exists("create/dir/file"), core::Fatal);
}
TEST_CASE("core::rewrite_stderr_to_absolute_paths")
{
TestContext test_context;
- util::write_file("existing", "");
+ REQUIRE(util::write_file("existing", ""));
std::string input =
"a:1:2\n"
-// Copyright (C) 2021-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
{
TestContext test_context;
- util::write_file("stats.log", "# comment\ndirect_cache_hit\n");
+ REQUIRE(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);
hco(Hash& hash, const std::string& command, const std::string& compiler)
{
#ifdef _WIN32
- util::write_file("command.bat", FMT("@echo off\r\n{}\r\n", command));
+ REQUIRE(util::write_file("command.bat", FMT("@echo off\r\n{}\r\n", command)));
return hash_command_output(hash, "command.bat", compiler);
#else
- util::write_file("command.sh", FMT("#!/bin/sh\n{}\n", command));
+ REQUIRE(util::write_file("command.sh", FMT("#!/bin/sh\n{}\n", command)));
chmod("command.sh", 0555);
return hash_command_output(hash, "./command.sh", compiler);
#endif
CHECK(hco(h1, "echo foo", "not used"));
#ifdef _WIN32
- util::write_file("command.bat", "@echo off\r\necho foo\r\n");
+ REQUIRE(util::write_file("command.bat", "@echo off\r\necho foo\r\n"));
CHECK(hash_command_output(h2, "%compiler%", "command.bat"));
#else
CHECK(hash_command_output(h2, "%compiler% foo", "echo"));
Hash h2;
#ifdef _WIN32
- util::write_file("stderr.bat", "@echo off\r\necho foo>&2\r\n");
+ REQUIRE(util::write_file("stderr.bat", "@echo off\r\necho foo>&2\r\n"));
CHECK(hco(h1, "echo foo", "not used"));
CHECK(hco(h2, "stderr.bat", "not used"));
#else
#ifdef _WIN32
h2.hash("foo\r\nbar\r\n");
- util::write_file("foo.bat", "@echo off\r\necho foo\r\n");
- util::write_file("bar.bat", "@echo off\r\necho bar\r\n");
+ REQUIRE(util::write_file("foo.bat", "@echo off\r\necho foo\r\n"));
+ REQUIRE(util::write_file("bar.bat", "@echo off\r\necho bar\r\n"));
CHECK(hash_multicommand_output(h1, "foo.bat; bar.bat", "not used"));
#else
h2.hash("foo\nbar\n");
-// Copyright (C) 2020-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
return false;
}
bool available = tmp_file->fd && InodeCache::available(*tmp_file->fd);
- fs::remove(tmp_file->path);
+ std::ignore = fs::remove(tmp_file->path);
return available;
}
init(config);
InodeCache inode_cache(config, util::Duration(0));
- util::write_file("a", "");
+ REQUIRE(util::write_file("a", ""));
CHECK(!inode_cache.get("a",
InodeCache::ContentType::checked_for_temporal_macros));
init(config);
InodeCache inode_cache(config, util::Duration(0));
- util::write_file("a", "a text");
+ REQUIRE(util::write_file("a", "a text"));
HashSourceCodeResult result;
result.insert(HashSourceCode::found_date);
CHECK(inode_cache.get_misses() == 0);
CHECK(inode_cache.get_errors() == 0);
- util::write_file("a", "something else");
+ REQUIRE(util::write_file("a", "something else"));
CHECK(!inode_cache.get("a",
InodeCache::ContentType::checked_for_temporal_macros));
init(config);
InodeCache inode_cache(config, util::Duration(0));
- util::write_file("a", "a text");
+ REQUIRE(util::write_file("a", "a text"));
auto binary_digest = Hash().hash("binary").digest();
auto code_digest = Hash().hash("code").digest();
-// Copyright (C) 2011-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2011-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
{
TestContext test_context;
- util::write_file("test", "bad 1 2 3 4 5\n");
+ REQUIRE(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));
{
TestContext test_context;
- util::write_file("test", "0 1 2 3 27 5\n");
+ REQUIRE(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));
content += FMT("{}\n", i);
}
- util::write_file("test", content);
+ REQUIRE(util::write_file("test", content));
const auto counters = StatsFile("test").read();
REQUIRE(counters.size() == count);
{
TestContext test_context;
- util::write_file("test", "0 1 2 3 27 5\n");
+ REQUIRE(util::write_file("test", "0 1 2 3 27 5\n"));
auto counters = StatsFile("test").update([](auto& cs) {
cs.increment(Statistic::internal_error, 1);
-// Copyright (C) 2021-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
{
TestContext test_context;
- fs::create_directories("e/m/p/t/y");
+ REQUIRE(fs::create_directories("e/m/p/t/y"));
- fs::create_directories("0/1");
- fs::create_directories("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");
+ REQUIRE(fs::create_directories("0/1"));
+ REQUIRE(fs::create_directories("0/f/c"));
+ REQUIRE(util::write_file("0/file_a", ""));
+ REQUIRE(util::write_file("0/1/file_b", "1"));
+ REQUIRE(util::write_file("0/1/file_c", "12"));
+ REQUIRE(util::write_file("0/f/c/file_d", "123"));
SUBCASE("nonexistent subdirectory")
{
SUBCASE("Empty")
{
- util::write_file("rsp_file", "");
+ REQUIRE(util::write_file("rsp_file", ""));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::posix);
CHECK(args.size() == 0);
}
SUBCASE("One argument without newline")
{
- util::write_file("rsp_file", "foo");
+ REQUIRE(util::write_file("rsp_file", "foo"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::posix);
CHECK(args.size() == 1);
CHECK(args[0] == "foo");
SUBCASE("One argument with newline")
{
- util::write_file("rsp_file", "foo\n");
+ REQUIRE(util::write_file("rsp_file", "foo\n"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::posix);
CHECK(args.size() == 1);
CHECK(args[0] == "foo");
SUBCASE("Multiple simple arguments")
{
- util::write_file("rsp_file", "x y z\n");
+ REQUIRE(util::write_file("rsp_file", "x y z\n"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::posix);
CHECK(args.size() == 3);
CHECK(args[0] == "x");
SUBCASE("Tricky quoting")
{
- util::write_file(
+ REQUIRE(util::write_file(
"rsp_file",
"first\rsec\\\tond\tthi\\\\rd\nfourth \tfif\\ th \"si'x\\\" th\""
- " 'seve\nth'\\");
+ " 'seve\nth'\\"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::posix);
CHECK(args.size() == 7);
CHECK(args[0] == "first");
SUBCASE("Ignore single quote in MSVC format")
{
- util::write_file("rsp_file", "'a b'");
+ REQUIRE(util::write_file("rsp_file", "'a b'"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::windows);
CHECK(args.size() == 2);
CHECK(args[0] == "'a");
SUBCASE("Backslash as directory separator in MSVC format")
{
- util::write_file("rsp_file", R"("-DDIRSEP='A\B\C'")");
+ REQUIRE(util::write_file("rsp_file", R"("-DDIRSEP='A\B\C'")"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::windows);
CHECK(args.size() == 1);
CHECK(args[0] == R"(-DDIRSEP='A\B\C')");
SUBCASE("Backslash before quote in MSVC format")
{
- util::write_file("rsp_file", R"(/Fo"N.dir\Release\\")");
+ REQUIRE(util::write_file("rsp_file", R"(/Fo"N.dir\Release\\")"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::windows);
CHECK(args.size() == 1);
CHECK(args[0] == R"(/FoN.dir\Release\)");
SUBCASE("Arguments on multiple lines in MSVC format")
{
- util::write_file("rsp_file", "a\nb");
+ REQUIRE(util::write_file("rsp_file", "a\nb"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::windows);
CHECK(args.size() == 2);
CHECK(args[0] == "a");
SUBCASE("Tricky quoting in MSVC format (#1247)")
{
- util::write_file(
+ REQUIRE(util::write_file(
"rsp_file",
R"(\ \\ '\\' "\\" '"\\"' "'\\'" '''\\''' ''"\\"'' '"'\\'"' '""\\""' "''\\''" "'"\\"'" ""'\\'"" """\\""" )"
R"(\'\' '\'\'' "\'\'" ''\'\''' '"\'\'"' "'\'\''" ""\'\'"" '''\'\'''' ''"\'\'"'' '"'\'\''"' '""\'\'""' "''\'\'''" "'"\'\'"'" ""'\'\''"" """\'\'""" )"
- R"(\"\" '\"\"' "\"\"" ''\"\"'' '"\"\""' "'\"\"'" ""\"\""" '''\"\"''' ''"\"\""'' '"'\"\"'"' '""\"\"""' "''\"\"''" "'"\"\""'" ""'\"\"'"" """\"\"""")");
+ R"(\"\" '\"\"' "\"\"" ''\"\"'' '"\"\""' "'\"\"'" ""\"\""" '''\"\"''' ''"\"\""'' '"'\"\"'"' '""\"\"""' "''\"\"''" "'"\"\""'" ""'\"\"'"" """\"\"""")"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::windows);
CHECK(args.size() == 44);
CHECK(args[0] == R"(\)");
{
// See
// https://learn.microsoft.com/en-us/previous-versions//17w5ykft(v=vs.85)?redirectedfrom=MSDN
- util::write_file("rsp_file",
- R"("abc" d e )"
- R"(a\\\b d"e f"g h )"
- R"(a\\\"b c d )"
- R"(a\\\\"b c" d e)");
+ REQUIRE(util::write_file("rsp_file",
+ R"("abc" d e )"
+ R"(a\\\b d"e f"g h )"
+ R"(a\\\"b c d )"
+ R"(a\\\\"b c" d e)"));
args = *Args::from_response_file("rsp_file", ResponseFileFormat::windows);
CHECK(args.size() == 12);
CHECK(args[0] == R"(abc)");
SUBCASE("normal")
{
fs::path filename = "test_normal.txt";
- util::write_file(filename, R"(# 1 "test_cuda.cu"
+ REQUIRE(util::write_file(filename, R"(# 1 "test_cuda.cu"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
void caller() {
# 1 "test_cuda.cu"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
-)");
+)"));
auto result = util::split_preprocessed_file_from_clang_cuda(filename);
SUBCASE("empty file")
{
fs::path filename = "test_empty.txt";
- util::write_file(filename, "");
+ REQUIRE(util::write_file(filename, ""));
CHECK(util::split_preprocessed_file_from_clang_cuda(filename).empty());
}
-// Copyright (C) 2019-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
{
TestContext test_context;
- util::write_file("a", "123");
+ REQUIRE(util::write_file("a", "123"));
util::Fd fd(open("a", O_RDONLY));
DirEntry entry("a", *fd);
{
TestContext test_context;
- util::write_file("a", "");
+ REQUIRE(util::write_file("a", ""));
DirEntry entry("a");
CHECK(entry.size() == 0);
- util::write_file("a", "123", util::WriteFileMode::in_place);
+ REQUIRE(util::write_file("a", "123", util::WriteFileMode::in_place));
CHECK(entry.size() == 0);
entry.refresh();
CHECK(entry.size() == 3);
{
TestContext test_context;
- util::write_file("a", "");
- util::write_file("b", "");
+ REQUIRE(util::write_file("a", ""));
+ REQUIRE(util::write_file("b", ""));
DirEntry entry_a("a");
DirEntry entry_b("b");
CHECK(entry_a.same_inode_as(entry_a));
CHECK(!entry_a.same_inode_as(entry_b));
- util::write_file("a", "change size", util::WriteFileMode::in_place);
+ REQUIRE(util::write_file("a", "change size", util::WriteFileMode::in_place));
CHECK(DirEntry("a").same_inode_as(entry_a));
CHECK(!DirEntry("nonexistent").same_inode_as(DirEntry("nonexistent")));
{
TestContext test_context;
- util::write_file("a", "");
+ REQUIRE(util::write_file("a", ""));
CHECK(DirEntry("a").path() == "a");
CHECK(DirEntry("does_not_exist").path() == "does_not_exist");
}
{
TestContext test_context;
- util::write_file("file", "1234567");
+ REQUIRE(util::write_file("file", "1234567"));
DirEntry de("file");
CHECK(de);
{
TestContext test_context;
- util::write_file("file", "1234567");
+ REQUIRE(util::write_file("file", "1234567"));
#ifdef _WIN32
// SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: 0x2
{
TestContext test_context;
- util::write_file("a", "");
+ REQUIRE(util::write_file("a", ""));
#ifdef _WIN32
REQUIRE(CreateHardLinkA("b", "a", nullptr));
CHECK(entry_a.inode() == entry_b.inode());
CHECK(entry_a.same_inode_as(entry_b));
- util::write_file("a", "1234567", util::WriteFileMode::in_place);
+ REQUIRE(util::write_file("a", "1234567", util::WriteFileMode::in_place));
entry_b.refresh();
CHECK(entry_b.size() == 7);
}
{
TestContext test_context;
- util::write_file("file", "");
+ REQUIRE(util::write_file("file", ""));
DWORD prev_attrs = GetFileAttributesA("file");
REQUIRE(prev_attrs != INVALID_FILE_ATTRIBUTES);
SUBCASE("stdout + stderr")
{
#ifdef _WIN32
- util::write_file("command.bat", "@echo off\r\necho fisk\r\necho sork>&2");
+ REQUIRE(util::write_file("command.bat",
+ "@echo off\r\necho fisk\r\necho sork>&2"));
util::Args args{"command.bat"};
#else
util::Args args{"sh", "-c", "echo fisk; echo sork >&2"};
-// Copyright (C) 2022-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2022-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
TestContext test_context;
REQUIRE(fs::create_directories("dir-with-subdir-and-file/subdir"));
- util::write_file("dir-with-subdir-and-file/subdir/f", "");
+ REQUIRE(util::write_file("dir-with-subdir-and-file/subdir/f", ""));
REQUIRE(fs::create_directory("dir-with-files"));
- util::write_file("dir-with-files/f1", "");
- util::write_file("dir-with-files/f2", "");
+ REQUIRE(util::write_file("dir-with-files/f1", ""));
+ REQUIRE(util::write_file("dir-with-files/f2", ""));
REQUIRE(fs::create_directory("empty-dir"));
std::vector<std::string> visited;
SUBCASE("traverse empty directory")
{
- CHECK_NOTHROW(util::traverse_directory("empty-dir", visitor));
+ std::ignore = util::traverse_directory("empty-dir", visitor);
REQUIRE(visited.size() == 1);
CHECK(visited[0] == "[d] empty-dir");
}
SUBCASE("traverse directory with files")
{
- CHECK_NOTHROW(util::traverse_directory("dir-with-files", visitor));
+ std::ignore = util::traverse_directory("dir-with-files", visitor);
REQUIRE(visited.size() == 3);
fs::path f1("[f] dir-with-files/f1");
fs::path f2("[f] dir-with-files/f2");
SUBCASE("traverse directory hierarchy")
{
- CHECK_NOTHROW(
- util::traverse_directory("dir-with-subdir-and-file", visitor));
+ std::ignore = util::traverse_directory("dir-with-subdir-and-file", visitor);
REQUIRE(visited.size() == 3);
CHECK(visited[0] == fs::path("[f] dir-with-subdir-and-file/subdir/f"));
CHECK(visited[1] == fs::path("[d] dir-with-subdir-and-file/subdir"));
-// Copyright (C) 2020-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
{
TestContext test_context;
- util::write_file("test.alive", "");
+ REQUIRE(util::write_file("test.alive", ""));
const util::TimePoint long_time_ago(0, 0);
util::set_timestamps("test.alive", long_time_ago);
CHECK(symlink("foo", "test.lock") == 0);
{
TestContext test_context;
- util::write_file("test.alive", "");
+ REQUIRE(util::write_file("test.alive", ""));
const util::TimePoint long_time_ago(0, 0);
util::set_timestamps("test.alive", long_time_ago);
CHECK(symlink("foo", "test.lock") == 0);
-// Copyright (C) 2020-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2025 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
}
++m_subdir_counter;
fs::path subtest_dir = m_test_dir / FMT("test_{}", m_subdir_counter);
- fs::create_directories(subtest_dir);
- if (!fs::current_path(subtest_dir)) {
- throw core::Error(FMT("Failed to change directory to {}", subtest_dir));
- }
+ util::throw_on_error<core::Error>(fs::create_directories(subtest_dir),
+ FMT("Failed to create {}: ", subtest_dir));
+ util::throw_on_error<core::Error>(
+ fs::current_path(subtest_dir),
+ FMT("Failed to change directory to {}", subtest_dir));
}
TestContext::~TestContext()
{
- fs::current_path(m_test_dir);
+ std::ignore = fs::current_path(m_test_dir);
}
} // namespace TestUtil