From b526e8d61efb33e2d3c7cb2f187c91eef437aeb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Capelle?= Date: Tue, 25 Jun 2024 14:28:43 +0200 Subject: [PATCH] Minor cleaning of test_helpers. --- src/shared/test_helpers.cpp | 28 ++++++++++--- src/shared/test_helpers.h | 64 ++++++++++++++++++----------- test/usvfs_test/usvfs_test_base.cpp | 27 ++++-------- 3 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/shared/test_helpers.cpp b/src/shared/test_helpers.cpp index 923b9e6..1d551f7 100644 --- a/src/shared/test_helpers.cpp +++ b/src/shared/test_helpers.cpp @@ -9,7 +9,7 @@ namespace test { - std::string FuncFailed::msg(const char* func, const char* arg1, const unsigned long* res, const char* what) + std::string FuncFailed::msg(std::string_view func, const char* arg1, const unsigned long* res, const char* what) { std::string buffer; buffer.reserve(128); @@ -26,6 +26,25 @@ namespace test { return buffer; } + + ScopedFILE ScopedFILE::open(const std::filesystem::path& filepath, std::wstring_view mode, errno_t& err) { + FILE* fp = nullptr; + err = _wfopen_s(&fp, filepath.c_str(), mode.data()); + if (err || !fp) { + return ScopedFILE(); + } + return ScopedFILE(fp); + } + + ScopedFILE ScopedFILE::open(const std::filesystem::path& filepath, std::wstring_view mode) { + errno_t err; + auto file = open(filepath, mode, err); + if (err || !file) { + throw_testWinFuncFailed("_wfopen_s", filepath.string().c_str(), err); + } + return file; + } + path path_of_test_bin(const path& relative) { path base(winapi::wide::getModuleFileName(nullptr)); return relative.empty() ? base.parent_path() : base.parent_path() / relative; @@ -87,10 +106,7 @@ namespace test { { using namespace std; - ScopedFILE f; - errno_t err = _wfopen_s(f, file.c_str(), binary ? L"rb" : L"rt"); - if (err || !f) - throw_testWinFuncFailed("_wfopen_s", file.string().c_str(), err); + const auto f = ScopedFILE::open(file, binary ? L"rb" : L"rt"); if (fseek(f, 0, SEEK_END)) throw_testWinFuncFailed("fseek", (unsigned long) 0); @@ -107,7 +123,7 @@ namespace test { std::vector content(static_cast(size)); content.resize(fread(content.data(), sizeof(char), content.size(), f)); - return std::move(content); + return content; } bool compare_files(const path& file1, const path& file2, bool binary) diff --git a/src/shared/test_helpers.h b/src/shared/test_helpers.h index cfe86ed..76720cf 100644 --- a/src/shared/test_helpers.h +++ b/src/shared/test_helpers.h @@ -4,28 +4,29 @@ #include "windows_sane.h" +#include #include - + namespace test { class FuncFailed : public std::runtime_error { public: - FuncFailed(const char* func) - : std::runtime_error(msg(func)) {} - FuncFailed(const char* func, unsigned long res) - : std::runtime_error(msg(func, nullptr, &res)) {} - FuncFailed(const char* func, const char* arg1) - : std::runtime_error(msg(func, arg1)) {} - FuncFailed(const char* func, const char* arg1, unsigned long res) - : std::runtime_error(msg(func, arg1, &res)) {} - FuncFailed(const char* func, const char* what, const char* arg1) - : std::runtime_error(msg(func, arg1, nullptr, what)) {} - FuncFailed(const char* func, const char* what, const char* arg1, unsigned long res) - : std::runtime_error(msg(func, arg1, &res, what)) {} + FuncFailed(const char* func) + : std::runtime_error(msg(func)) {} + FuncFailed(const char* func, unsigned long res) + : std::runtime_error(msg(func, nullptr, &res)) {} + FuncFailed(const char* func, const char* arg1) + : std::runtime_error(msg(func, arg1)) {} + FuncFailed(const char* func, const char* arg1, unsigned long res) + : std::runtime_error(msg(func, arg1, &res)) {} + FuncFailed(const char* func, const char* what, const char* arg1) + : std::runtime_error(msg(func, arg1, nullptr, what)) {} + FuncFailed(const char* func, const char* what, const char* arg1, unsigned long res) + : std::runtime_error(msg(func, arg1, &res, what)) {} private: - std::string msg(const char* func, const char* arg1 = nullptr, const unsigned long* res = nullptr, const char* what = nullptr); + std::string msg(std::string_view func, const char* arg1 = nullptr, const unsigned long* res = nullptr, const char* what = nullptr); }; class WinFuncFailed : public std::runtime_error @@ -52,12 +53,12 @@ namespace test { return WinFuncFailed(std::format("{} failed : result=({:#x}), lastError={}", func, res, m_gle)); } - WinFuncFailed operator()(std::basic_string_view func, std::basic_string_view arg1) + WinFuncFailed operator()(std::string_view func, std::basic_string_view arg1) { return WinFuncFailed(std::format("{} failed : {}, lastError={}", func, arg1, m_gle)); } - WinFuncFailed operator()(std::basic_string_view func, std::basic_string_view arg1, unsigned long res) + WinFuncFailed operator()(std::string_view func, std::basic_string_view arg1, unsigned long res) { return WinFuncFailed(std::format("{} failed : {}, result=({:#x}), lastError={}", func, arg1, res, m_gle)); } @@ -68,25 +69,38 @@ namespace test { // trick to guarantee the evalutation of GetLastError() before the evalution of the parameters to the WinFuncFailed message generation template - [[noreturn]] void throw_testWinFuncFailed(std::basic_string_view func, Args&&... args) { + [[noreturn]] void throw_testWinFuncFailed(std::string_view func, Args&&... args) { ::test::WinFuncFailedGenerator exceptionGenerator; throw exceptionGenerator(func, std::forward(args)... ); } class ScopedFILE { public: - ScopedFILE(FILE* f = nullptr) : m_f(f) {} + + // try to open the given filepath with the given mode, if it fails, set err to + // the return code of _wfopen_s and return a nulled scoped file + // + static ScopedFILE open(const std::filesystem::path& filepath, std::wstring_view mode, errno_t& err); + + // same as above but throw a WinFuncFailed() exception if opening the file failed + // + static ScopedFILE open(const std::filesystem::path& filepath, std::wstring_view mode); + + public: + ScopedFILE(FILE* f = nullptr) : m_f(f, &fclose) {} + + ScopedFILE(ScopedFILE&& other) noexcept = default; + ~ScopedFILE() = default; + ScopedFILE(const ScopedFILE&) = delete; - ScopedFILE(ScopedFILE&& other) noexcept : m_f(other.m_f) { other.m_f = nullptr; } - ~ScopedFILE() { if (m_f) fclose(m_f); } - void close() { if (m_f) { fclose(m_f); m_f = nullptr; } } + void close() { m_f = nullptr; } + + operator bool() const { return static_cast(m_f); } + operator FILE*() const { return m_f.get(); } - operator bool() const { return m_f; } - operator FILE*() const { return m_f; } - operator FILE**() { return &m_f; } private: - FILE* m_f; + std::unique_ptr m_f; }; using std::filesystem::path; diff --git a/test/usvfs_test/usvfs_test_base.cpp b/test/usvfs_test/usvfs_test_base.cpp index c887970..a2c2fb4 100644 --- a/test/usvfs_test/usvfs_test_base.cpp +++ b/test/usvfs_test/usvfs_test_base.cpp @@ -100,14 +100,11 @@ class usvfs_connector { using path = test::path; usvfs_connector(const usvfs_test_options& options) - : m_exit_future(m_exit_signal.get_future()) + : m_usvfs_log(test::ScopedFILE::open(options.usvfs_log, L"wt")), + m_exit_future(m_exit_signal.get_future()) { winapi::ex::wide::createPath(options.usvfs_log.parent_path().c_str()); - errno_t err = _wfopen_s(m_usvfs_log, options.usvfs_log.c_str(), L"wt"); - if (err || !m_usvfs_log) - throw_testWinFuncFailed("_wfopen_s", options.usvfs_log.string().c_str(), err); - std::wcout << "Connecting VFS..." << std::endl; std::unique_ptr parameters{ @@ -273,11 +270,7 @@ class mappings_reader mappings_list read(const path& mapfile) { - test::ScopedFILE map; - errno_t err = _wfopen_s(map, mapfile.c_str(), L"rt"); - if (err || !map) - throw_testWinFuncFailed("_wfopen_s", mapfile.string().c_str(), err); - + const auto map = test::ScopedFILE::open(mapfile, L"rt"); mappings_list mappings; char line[1024]; @@ -564,10 +557,7 @@ bool usvfs_test_base::recursive_compare_dirs(path rel_path, path gold_base, path test::ScopedFILE usvfs_test_base::output() { - test::ScopedFILE log; - errno_t err = _wfopen_s(log, m_o.output.c_str(), m_clean_output ? L"wt" : L"at"); - if (err || !log) - throw_testWinFuncFailed("_wfopen_s", m_o.output.string().c_str(), err); + auto log = test::ScopedFILE::open(m_o.output, m_clean_output ? L"wt" : L"at"); m_clean_output = false; return log; } @@ -576,8 +566,8 @@ void usvfs_test_base::clean_output() { using namespace std; - test::ScopedFILE in; - errno_t err = _wfopen_s(in, m_o.output.c_str(), L"rt"); + errno_t err; + auto in = test::ScopedFILE::open(m_o.output, L"rt", err); if (err == ENOENT) { wcerr << L"warning: no " << m_o.output << L" to clean." << endl; return; @@ -585,14 +575,11 @@ void usvfs_test_base::clean_output() else if (err || !in) throw_testWinFuncFailed("_wfopen_s", m_o.output.string().c_str(), err); - test::ScopedFILE out; path clean = m_o.output.parent_path() / m_o.output.stem(); clean += OUTPUT_CLEAN_SUFFIX; clean += m_o.output.extension(); - err = _wfopen_s(out, clean.c_str(), L"wt"); - if (err || !in) - throw_testWinFuncFailed("_wfopen_s", clean.string().c_str(), err); + auto out = test::ScopedFILE::open(clean, L"wt"); wcout << L"Cleaning " << m_o.output << " to " << clean << endl; char line[1024];