Merge branch 'Issue-1248' into v1.x
This commit is contained in:
		@@ -24,5 +24,3 @@ target_link_libraries(latency PRIVATE benchmark::benchmark spdlog::spdlog)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
add_executable(formatter-bench formatter-bench.cpp)
 | 
					add_executable(formatter-bench formatter-bench.cpp)
 | 
				
			||||||
target_link_libraries(formatter-bench PRIVATE benchmark::benchmark spdlog::spdlog)
 | 
					target_link_libraries(formatter-bench PRIVATE benchmark::benchmark spdlog::spdlog)
 | 
				
			||||||
 | 
					 | 
				
			||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,26 +16,6 @@
 | 
				
			|||||||
#include "spdlog/sinks/null_sink.h"
 | 
					#include "spdlog/sinks/null_sink.h"
 | 
				
			||||||
#include "spdlog/sinks/rotating_file_sink.h"
 | 
					#include "spdlog/sinks/rotating_file_sink.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void prepare_logdir()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    spdlog::info("Preparing latency_logs directory..");
 | 
					 | 
				
			||||||
#ifdef _WIN32
 | 
					 | 
				
			||||||
    system("if not exist logs mkdir latency_logs");
 | 
					 | 
				
			||||||
    system("del /F /Q logs\\*");
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    auto rv = system("mkdir -p latency_logs");
 | 
					 | 
				
			||||||
    if (rv != 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        throw std::runtime_error("Failed to mkdir -p latency_logs");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    rv = system("rm -f latency_logs/*");
 | 
					 | 
				
			||||||
    if (rv != 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        throw std::runtime_error("Failed to rm -f latency_logs/*");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bench_c_string(benchmark::State &state, std::shared_ptr<spdlog::logger> logger)
 | 
					void bench_c_string(benchmark::State &state, std::shared_ptr<spdlog::logger> logger)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
 | 
					    const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
 | 
				
			||||||
@@ -83,8 +63,6 @@ int main(int argc, char *argv[])
 | 
				
			|||||||
    size_t rotating_files = 5;
 | 
					    size_t rotating_files = 5;
 | 
				
			||||||
    int n_threads = benchmark::CPUInfo::Get().num_cpus;
 | 
					    int n_threads = benchmark::CPUInfo::Get().num_cpus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    prepare_logdir();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // disabled loggers
 | 
					    // disabled loggers
 | 
				
			||||||
    auto disabled_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
 | 
					    auto disabled_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
 | 
				
			||||||
    disabled_logger->set_level(spdlog::level::off);
 | 
					    disabled_logger->set_level(spdlog::level::off);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,4 +12,3 @@ foreach i : bench_matrix
 | 
				
			|||||||
  benchmark('bench_' + i[0], bench_exe, args: i[2])
 | 
					  benchmark('bench_' + i[0], bench_exe, args: i[2])
 | 
				
			||||||
endforeach
 | 
					endforeach
 | 
				
			||||||
 | 
					
 | 
				
			||||||
run_command(find_program('mkdir'), meson.current_build_dir() + '/logs')
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,5 +25,3 @@ if(SPDLOG_BUILD_EXAMPLE_HO)
 | 
				
			|||||||
    target_link_libraries(example_header_only PRIVATE spdlog::spdlog_header_only)
 | 
					    target_link_libraries(example_header_only PRIVATE spdlog::spdlog_header_only)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Create logs directory
 | 
					 | 
				
			||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
executable('example', 'example.cpp', dependencies: spdlog_dep)
 | 
					executable('example', 'example.cpp', dependencies: spdlog_dep)
 | 
				
			||||||
executable('example_header_only', 'example.cpp', dependencies: spdlog_headeronly_dep)
 | 
					executable('example_header_only', 'example.cpp', dependencies: spdlog_headeronly_dep)
 | 
				
			||||||
run_command(find_program('mkdir'), meson.current_build_dir() + '/logs')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,28 +28,31 @@ SPDLOG_INLINE file_helper::~file_helper()
 | 
				
			|||||||
SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
 | 
					SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    close();
 | 
					    close();
 | 
				
			||||||
 | 
					    filename_ = fname;
 | 
				
			||||||
    auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab");
 | 
					    auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab");
 | 
				
			||||||
    _filename = fname;
 | 
					    
 | 
				
			||||||
    for (int tries = 0; tries < open_tries; ++tries)
 | 
					    for (int tries = 0; tries < open_tries_; ++tries)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        // create containing folder if not exists already.
 | 
				
			||||||
 | 
					        os::create_dir(os::dir_name(fname));
 | 
				
			||||||
        if (!os::fopen_s(&fd_, fname, mode))
 | 
					        if (!os::fopen_s(&fd_, fname, mode))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        details::os::sleep_for_millis(open_interval);
 | 
					        details::os::sleep_for_millis(open_interval_);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SPDLOG_THROW(spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno));
 | 
					    SPDLOG_THROW(spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPDLOG_INLINE void file_helper::reopen(bool truncate)
 | 
					SPDLOG_INLINE void file_helper::reopen(bool truncate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (_filename.empty())
 | 
					    if (filename_.empty())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        SPDLOG_THROW(spdlog_ex("Failed re opening file - was not opened before"));
 | 
					        SPDLOG_THROW(spdlog_ex("Failed re opening file - was not opened before"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    open(_filename, truncate);
 | 
					    this->open(filename_, truncate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPDLOG_INLINE void file_helper::flush()
 | 
					SPDLOG_INLINE void file_helper::flush()
 | 
				
			||||||
@@ -72,7 +75,7 @@ SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf)
 | 
				
			|||||||
    auto data = buf.data();
 | 
					    auto data = buf.data();
 | 
				
			||||||
    if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
 | 
					    if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        SPDLOG_THROW(spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno));
 | 
					        SPDLOG_THROW(spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,19 +83,14 @@ SPDLOG_INLINE size_t file_helper::size() const
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    if (fd_ == nullptr)
 | 
					    if (fd_ == nullptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        SPDLOG_THROW(spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename)));
 | 
					        SPDLOG_THROW(spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return os::filesize(fd_);
 | 
					    return os::filesize(fd_);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPDLOG_INLINE const filename_t &file_helper::filename() const
 | 
					SPDLOG_INLINE const filename_t &file_helper::filename() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return _filename;
 | 
					    return filename_;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SPDLOG_INLINE bool file_helper::file_exists(const filename_t &fname)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return os::file_exists(fname);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -129,5 +127,6 @@ SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension
 | 
				
			|||||||
    // finally - return a valid base and extension tuple
 | 
					    // finally - return a valid base and extension tuple
 | 
				
			||||||
    return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
 | 
					    return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace details
 | 
					} // namespace details
 | 
				
			||||||
} // namespace spdlog
 | 
					} // namespace spdlog
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,6 @@ public:
 | 
				
			|||||||
    void write(const memory_buf_t &buf);
 | 
					    void write(const memory_buf_t &buf);
 | 
				
			||||||
    size_t size() const;
 | 
					    size_t size() const;
 | 
				
			||||||
    const filename_t &filename() const;
 | 
					    const filename_t &filename() const;
 | 
				
			||||||
    static bool file_exists(const filename_t &fname);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    // return file path and its extension:
 | 
					    // return file path and its extension:
 | 
				
			||||||
@@ -47,10 +46,10 @@ public:
 | 
				
			|||||||
    static std::tuple<filename_t, filename_t> split_by_extension(const filename_t &fname);
 | 
					    static std::tuple<filename_t, filename_t> split_by_extension(const filename_t &fname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    const int open_tries = 5;
 | 
					    const int open_tries_ = 5;
 | 
				
			||||||
    const int open_interval = 10;
 | 
					    const int open_interval_ = 10;
 | 
				
			||||||
    std::FILE *fd_{nullptr};
 | 
					    std::FILE *fd_{nullptr};
 | 
				
			||||||
    filename_t _filename;
 | 
					    filename_t filename_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace details
 | 
					} // namespace details
 | 
				
			||||||
} // namespace spdlog
 | 
					} // namespace spdlog
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@
 | 
				
			|||||||
#include <cstring>
 | 
					#include <cstring>
 | 
				
			||||||
#include <ctime>
 | 
					#include <ctime>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <sstream>
 | 
				
			||||||
#include <thread>
 | 
					#include <thread>
 | 
				
			||||||
#include <array>
 | 
					#include <array>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
@@ -42,6 +43,8 @@
 | 
				
			|||||||
#include <limits>
 | 
					#include <limits>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <direct.h> // for _mkdir/_wmkdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else // unix
 | 
					#else // unix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
@@ -91,17 +94,17 @@ SPDLOG_INLINE std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
    std::tm tm;
 | 
					    std::tm tm;
 | 
				
			||||||
    localtime_s(&tm, &time_tt);
 | 
					    ::localtime_s(&tm, &time_tt);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    std::tm tm;
 | 
					    std::tm tm;
 | 
				
			||||||
    localtime_r(&time_tt, &tm);
 | 
					    ::localtime_r(&time_tt, &tm);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    return tm;
 | 
					    return tm;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPDLOG_INLINE std::tm localtime() SPDLOG_NOEXCEPT
 | 
					SPDLOG_INLINE std::tm localtime() SPDLOG_NOEXCEPT
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    std::time_t now_t = time(nullptr);
 | 
					    std::time_t now_t = ::time(nullptr);
 | 
				
			||||||
    return localtime(now_t);
 | 
					    return localtime(now_t);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,17 +113,17 @@ SPDLOG_INLINE std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
    std::tm tm;
 | 
					    std::tm tm;
 | 
				
			||||||
    gmtime_s(&tm, &time_tt);
 | 
					    ::gmtime_s(&tm, &time_tt);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    std::tm tm;
 | 
					    std::tm tm;
 | 
				
			||||||
    gmtime_r(&time_tt, &tm);
 | 
					    ::gmtime_r(&time_tt, &tm);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    return tm;
 | 
					    return tm;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPDLOG_INLINE std::tm gmtime() SPDLOG_NOEXCEPT
 | 
					SPDLOG_INLINE std::tm gmtime() SPDLOG_NOEXCEPT
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    std::time_t now_t = time(nullptr);
 | 
					    std::time_t now_t = ::time(nullptr);
 | 
				
			||||||
    return gmtime(now_t);
 | 
					    return gmtime(now_t);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -129,13 +132,13 @@ SPDLOG_INLINE void prevent_child_fd(FILE *f)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
#if !defined(__cplusplus_winrt)
 | 
					#if !defined(__cplusplus_winrt)
 | 
				
			||||||
    auto file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(f)));
 | 
					    auto file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(::_fileno(f)));
 | 
				
			||||||
    if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0))
 | 
					    if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0))
 | 
				
			||||||
        SPDLOG_THROW(spdlog_ex("SetHandleInformation failed", errno));
 | 
					        SPDLOG_THROW(spdlog_ex("SetHandleInformation failed", errno));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    auto fd = fileno(f);
 | 
					    auto fd = ::fileno(f);
 | 
				
			||||||
    if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
 | 
					    if (::fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        SPDLOG_THROW(spdlog_ex("fcntl with FD_CLOEXEC failed", errno));
 | 
					        SPDLOG_THROW(spdlog_ex("fcntl with FD_CLOEXEC failed", errno));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -147,12 +150,12 @@ SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
#ifdef SPDLOG_WCHAR_FILENAMES
 | 
					#ifdef SPDLOG_WCHAR_FILENAMES
 | 
				
			||||||
    *fp = _wfsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
 | 
					    *fp = ::_wfsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    *fp = _fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
 | 
					    *fp = ::_fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#else // unix
 | 
					#else // unix
 | 
				
			||||||
    *fp = fopen((filename.c_str()), mode.c_str());
 | 
					    *fp = ::fopen((filename.c_str()), mode.c_str());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef SPDLOG_PREVENT_CHILD_FD
 | 
					#ifdef SPDLOG_PREVENT_CHILD_FD
 | 
				
			||||||
@@ -167,7 +170,7 @@ SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename
 | 
				
			|||||||
SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT
 | 
					SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
 | 
					#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
 | 
				
			||||||
    return _wremove(filename.c_str());
 | 
					    return ::_wremove(filename.c_str());
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    return std::remove(filename.c_str());
 | 
					    return std::remove(filename.c_str());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -175,28 +178,28 @@ SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
SPDLOG_INLINE int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT
 | 
					SPDLOG_INLINE int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return file_exists(filename) ? remove(filename) : 0;
 | 
					    return path_exists(filename) ? remove(filename) : 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPDLOG_INLINE int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT
 | 
					SPDLOG_INLINE int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
 | 
					#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
 | 
				
			||||||
    return _wrename(filename1.c_str(), filename2.c_str());
 | 
					    return ::_wrename(filename1.c_str(), filename2.c_str());
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    return std::rename(filename1.c_str(), filename2.c_str());
 | 
					    return std::rename(filename1.c_str(), filename2.c_str());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Return true if file exists
 | 
					// Return true if path exists (file or directory)
 | 
				
			||||||
SPDLOG_INLINE bool file_exists(const filename_t &filename) SPDLOG_NOEXCEPT
 | 
					SPDLOG_INLINE bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
#ifdef SPDLOG_WCHAR_FILENAMES
 | 
					#ifdef SPDLOG_WCHAR_FILENAMES
 | 
				
			||||||
    auto attribs = GetFileAttributesW(filename.c_str());
 | 
					    auto attribs = ::GetFileAttributesW(filename.c_str());
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    auto attribs = GetFileAttributesA(filename.c_str());
 | 
					    auto attribs = ::GetFileAttributesA(filename.c_str());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    return (attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY));
 | 
					    return attribs != INVALID_FILE_ATTRIBUTES;
 | 
				
			||||||
#else // common linux/unix all have the stat system call
 | 
					#else // common linux/unix all have the stat system call
 | 
				
			||||||
    struct stat buffer;
 | 
					    struct stat buffer;
 | 
				
			||||||
    return (::stat(filename.c_str(), &buffer) == 0);
 | 
					    return (::stat(filename.c_str(), &buffer) == 0);
 | 
				
			||||||
@@ -211,16 +214,16 @@ SPDLOG_INLINE size_t filesize(FILE *f)
 | 
				
			|||||||
        SPDLOG_THROW(spdlog_ex("Failed getting file size. fd is null"));
 | 
					        SPDLOG_THROW(spdlog_ex("Failed getting file size. fd is null"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
 | 
					#if defined(_WIN32) && !defined(__CYGWIN__)
 | 
				
			||||||
    int fd = _fileno(f);
 | 
					    int fd = ::_fileno(f);
 | 
				
			||||||
#if _WIN64 // 64 bits
 | 
					#if _WIN64 // 64 bits
 | 
				
			||||||
    __int64 ret = _filelengthi64(fd);
 | 
					    __int64 ret = ::_filelengthi64(fd);
 | 
				
			||||||
    if (ret >= 0)
 | 
					    if (ret >= 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return static_cast<size_t>(ret);
 | 
					        return static_cast<size_t>(ret);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else // windows 32 bits
 | 
					#else // windows 32 bits
 | 
				
			||||||
    long ret = _filelength(fd);
 | 
					    long ret = ::_filelength(fd);
 | 
				
			||||||
    if (ret >= 0)
 | 
					    if (ret >= 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return static_cast<size_t>(ret);
 | 
					        return static_cast<size_t>(ret);
 | 
				
			||||||
@@ -228,7 +231,7 @@ SPDLOG_INLINE size_t filesize(FILE *f)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else // unix
 | 
					#else // unix
 | 
				
			||||||
    int fd = fileno(f);
 | 
					    int fd = ::fileno(f);
 | 
				
			||||||
// 64 bits(but not in osx or cygwin, where fstat64 is deprecated)
 | 
					// 64 bits(but not in osx or cygwin, where fstat64 is deprecated)
 | 
				
			||||||
#if (defined(__linux__) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64))
 | 
					#if (defined(__linux__) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64))
 | 
				
			||||||
    struct stat64 st;
 | 
					    struct stat64 st;
 | 
				
			||||||
@@ -255,10 +258,10 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm)
 | 
				
			|||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
#if _WIN32_WINNT < _WIN32_WINNT_WS08
 | 
					#if _WIN32_WINNT < _WIN32_WINNT_WS08
 | 
				
			||||||
    TIME_ZONE_INFORMATION tzinfo;
 | 
					    TIME_ZONE_INFORMATION tzinfo;
 | 
				
			||||||
    auto rv = GetTimeZoneInformation(&tzinfo);
 | 
					    auto rv = ::GetTimeZoneInformation(&tzinfo);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
 | 
					    DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
 | 
				
			||||||
    auto rv = GetDynamicTimeZoneInformation(&tzinfo);
 | 
					    auto rv = ::GetDynamicTimeZoneInformation(&tzinfo);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    if (rv == TIME_ZONE_ID_INVALID)
 | 
					    if (rv == TIME_ZONE_ID_INVALID)
 | 
				
			||||||
        SPDLOG_THROW(spdlog::spdlog_ex("Failed getting timezone info. ", errno));
 | 
					        SPDLOG_THROW(spdlog::spdlog_ex("Failed getting timezone info. ", errno));
 | 
				
			||||||
@@ -324,15 +327,15 @@ SPDLOG_INLINE size_t _thread_id() SPDLOG_NOEXCEPT
 | 
				
			|||||||
#if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
 | 
					#if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
 | 
				
			||||||
#define SYS_gettid __NR_gettid
 | 
					#define SYS_gettid __NR_gettid
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    return static_cast<size_t>(syscall(SYS_gettid));
 | 
					    return static_cast<size_t>(::syscall(SYS_gettid));
 | 
				
			||||||
#elif defined(_AIX) || defined(__DragonFly__) || defined(__FreeBSD__)
 | 
					#elif defined(_AIX) || defined(__DragonFly__) || defined(__FreeBSD__)
 | 
				
			||||||
    return static_cast<size_t>(pthread_getthreadid_np());
 | 
					    return static_cast<size_t>(::pthread_getthreadid_np());
 | 
				
			||||||
#elif defined(__NetBSD__)
 | 
					#elif defined(__NetBSD__)
 | 
				
			||||||
    return static_cast<size_t>(_lwp_self());
 | 
					    return static_cast<size_t>(::_lwp_self());
 | 
				
			||||||
#elif defined(__OpenBSD__)
 | 
					#elif defined(__OpenBSD__)
 | 
				
			||||||
    return static_cast<size_t>(getthrid());
 | 
					    return static_cast<size_t>(::getthrid());
 | 
				
			||||||
#elif defined(__sun)
 | 
					#elif defined(__sun)
 | 
				
			||||||
    return static_cast<size_t>(thr_self());
 | 
					    return static_cast<size_t>(::thr_self());
 | 
				
			||||||
#elif __APPLE__
 | 
					#elif __APPLE__
 | 
				
			||||||
    uint64_t tid;
 | 
					    uint64_t tid;
 | 
				
			||||||
    pthread_threadid_np(nullptr, &tid);
 | 
					    pthread_threadid_np(nullptr, &tid);
 | 
				
			||||||
@@ -417,9 +420,9 @@ SPDLOG_INLINE bool in_terminal(FILE *file) SPDLOG_NOEXCEPT
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
    return _isatty(_fileno(file)) != 0;
 | 
					    return ::_isatty(_fileno(file)) != 0;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    return isatty(fileno(file)) != 0;
 | 
					    return ::isatty(fileno(file)) != 0;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -460,6 +463,77 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
 | 
					#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// return true on success
 | 
				
			||||||
 | 
					SPDLOG_INLINE bool mkdir_(const filename_t &path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#ifdef SPDLOG_WCHAR_FILENAMES
 | 
				
			||||||
 | 
					    return ::_wmkdir(path.c_str()) == 0;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    return ::_mkdir(path.c_str()) == 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    return ::mkdir(path.c_str(), mode_t(0755)) == 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// create the given directory - and all directories leading to it
 | 
				
			||||||
 | 
					// return true on success or if the directory already exists
 | 
				
			||||||
 | 
					SPDLOG_INLINE bool create_dir(filename_t path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (path_exists(path))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(path.empty())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					    // support forward slash in windows
 | 
				
			||||||
 | 
					    std::replace(path.begin(), path.end(), '/', folder_sep);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t search_offset = 0;
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fmt::string_view t;
 | 
				
			||||||
 | 
					        auto token_pos = path.find(folder_sep, search_offset);
 | 
				
			||||||
 | 
					        // treat the entire path as a folder if no folder separator not found
 | 
				
			||||||
 | 
					        if (token_pos == filename_t::npos)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            token_pos = path.size();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto subdir = path.substr(0, token_pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!subdir.empty() && !path_exists(subdir) && !mkdir_(subdir))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return false; // return error if failed creating dir
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        search_offset = token_pos + 1;
 | 
				
			||||||
 | 
					    } while (search_offset < path.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Return directory name from given path or empty string
 | 
				
			||||||
 | 
					// "abc/file" => "abc"
 | 
				
			||||||
 | 
					// "abc/" => "abc"
 | 
				
			||||||
 | 
					// "abc" => ""
 | 
				
			||||||
 | 
					// "abc///" => "abc//"
 | 
				
			||||||
 | 
					SPDLOG_INLINE filename_t dir_name(filename_t path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					    // support forward slash in windows
 | 
				
			||||||
 | 
					    std::replace(path.begin(), path.end(), '/', folder_sep);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    auto pos = path.find_last_of(folder_sep);
 | 
				
			||||||
 | 
					    return pos != filename_t::npos ? path.substr(0, pos) : filename_t{};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace os
 | 
					} // namespace os
 | 
				
			||||||
} // namespace details
 | 
					} // namespace details
 | 
				
			||||||
} // namespace spdlog
 | 
					} // namespace spdlog
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ SPDLOG_CONSTEXPR static const char *default_eol = SPDLOG_EOL;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// folder separator
 | 
					// folder separator
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
const char folder_sep = '\\';
 | 
					static const char folder_sep = '\\';
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
SPDLOG_CONSTEXPR static const char folder_sep = '/';
 | 
					SPDLOG_CONSTEXPR static const char folder_sep = '/';
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -53,7 +53,7 @@ int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
 | 
				
			|||||||
int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT;
 | 
					int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Return if file exists.
 | 
					// Return if file exists.
 | 
				
			||||||
bool file_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
 | 
					bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Return file size according to open FILE* object
 | 
					// Return file size according to open FILE* object
 | 
				
			||||||
size_t filesize(FILE *f);
 | 
					size_t filesize(FILE *f);
 | 
				
			||||||
@@ -89,6 +89,17 @@ bool in_terminal(FILE *file) SPDLOG_NOEXCEPT;
 | 
				
			|||||||
void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
 | 
					void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Return directory name from given path or empty string
 | 
				
			||||||
 | 
					// "abc/file" => "abc"
 | 
				
			||||||
 | 
					// "abc/" => "abc"
 | 
				
			||||||
 | 
					// "abc" => ""
 | 
				
			||||||
 | 
					// "abc///" => "abc//"
 | 
				
			||||||
 | 
					filename_t dir_name(filename_t path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a dir from the given path.
 | 
				
			||||||
 | 
					// Return true if succeeded or if this dir already exists.
 | 
				
			||||||
 | 
					bool create_dir(filename_t path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace os
 | 
					} // namespace os
 | 
				
			||||||
} // namespace details
 | 
					} // namespace details
 | 
				
			||||||
} // namespace spdlog
 | 
					} // namespace spdlog
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,11 +88,12 @@ template<typename Mutex>
 | 
				
			|||||||
SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_()
 | 
					SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using details::os::filename_to_str;
 | 
					    using details::os::filename_to_str;
 | 
				
			||||||
 | 
					    using details::os::path_exists;
 | 
				
			||||||
    file_helper_.close();
 | 
					    file_helper_.close();
 | 
				
			||||||
    for (auto i = max_files_; i > 0; --i)
 | 
					    for (auto i = max_files_; i > 0; --i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        filename_t src = calc_filename(base_filename_, i - 1);
 | 
					        filename_t src = calc_filename(base_filename_, i - 1);
 | 
				
			||||||
        if (!details::file_helper::file_exists(src))
 | 
					        if (!path_exists(src))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,8 @@ set(SPDLOG_UTESTS_SOURCES
 | 
				
			|||||||
    test_fmt_helper.cpp
 | 
					    test_fmt_helper.cpp
 | 
				
			||||||
  	test_stdout_api.cpp
 | 
					  	test_stdout_api.cpp
 | 
				
			||||||
    test_dup_filter.cpp
 | 
					    test_dup_filter.cpp
 | 
				
			||||||
	test_backtrace.cpp)
 | 
						test_backtrace.cpp
 | 
				
			||||||
 | 
						test_create_dir.cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(NOT SPDLOG_NO_EXCEPTIONS)
 | 
					if(NOT SPDLOG_NO_EXCEPTIONS)
 | 
				
			||||||
	list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp)
 | 
						list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp)
 | 
				
			||||||
@@ -35,7 +36,6 @@ if(systemd_FOUND)
 | 
				
			|||||||
	list(APPEND SPDLOG_UTESTS_SOURCES test_systemd.cpp)
 | 
						list(APPEND SPDLOG_UTESTS_SOURCES test_systemd.cpp)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")
 | 
					 | 
				
			||||||
enable_testing()
 | 
					enable_testing()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function(spdlog_prepare_test test_target spdlog_lib)
 | 
					function(spdlog_prepare_test test_target spdlog_lib)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,6 @@ if systemd_dep.found()
 | 
				
			|||||||
  global_test_deps += systemd_dep
 | 
					  global_test_deps += systemd_dep
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
run_command('mkdir', 'logs')
 | 
					 | 
				
			||||||
# --------------------------------------
 | 
					# --------------------------------------
 | 
				
			||||||
# ---   Build the test executables   ---
 | 
					# ---   Build the test executables   ---
 | 
				
			||||||
# --------------------------------------
 | 
					# --------------------------------------
 | 
				
			||||||
@@ -49,5 +48,3 @@ foreach i : test_matrix
 | 
				
			|||||||
  test_exe = executable(i[0], test_sources, dependencies: global_test_deps + [i[1]])
 | 
					  test_exe = executable(i[0], test_sources, dependencies: global_test_deps + [i[1]])
 | 
				
			||||||
  test('test_' + i[0], test_exe)
 | 
					  test('test_' + i[0], test_exe)
 | 
				
			||||||
endforeach
 | 
					endforeach
 | 
				
			||||||
 | 
					 | 
				
			||||||
run_command(find_program('mkdir'), meson.current_build_dir() + '/logs')
 | 
					 | 
				
			||||||
@@ -157,7 +157,7 @@ TEST_CASE("to_file", "[async]")
 | 
				
			|||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    size_t messages = 1024;
 | 
					    size_t messages = 1024;
 | 
				
			||||||
    size_t tp_threads = 1;
 | 
					    size_t tp_threads = 1;
 | 
				
			||||||
    std::string filename = "logs/async_test.log";
 | 
					    std::string filename = "test_logs/async_test.log";
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
 | 
					        auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
 | 
				
			||||||
        auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
 | 
					        auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
 | 
				
			||||||
@@ -179,7 +179,7 @@ TEST_CASE("to_file multi-workers", "[async]")
 | 
				
			|||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    size_t messages = 1024 * 10;
 | 
					    size_t messages = 1024 * 10;
 | 
				
			||||||
    size_t tp_threads = 10;
 | 
					    size_t tp_threads = 10;
 | 
				
			||||||
    std::string filename = "logs/async_test.log";
 | 
					    std::string filename = "test_logs/async_test.log";
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
 | 
					        auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
 | 
				
			||||||
        auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
 | 
					        auto tp = std::make_shared<spdlog::details::thread_pool>(messages, tp_threads);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										80
									
								
								tests/test_create_dir.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								tests/test_create_dir.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "includes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using spdlog::details::os::create_dir;
 | 
				
			||||||
 | 
					using spdlog::details::os::path_exists;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool try_create_dir(const char *path, const char *normalized_path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    auto rv = create_dir(path);
 | 
				
			||||||
 | 
					    REQUIRE(rv == true);
 | 
				
			||||||
 | 
					    return path_exists(normalized_path);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_CASE("create_dir", "[create_dir]")
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    prepare_logdir();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("test_logs/dir1/dir1", "test_logs/dir1/dir1"));
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("test_logs/dir1/dir1", "test_logs/dir1/dir1")); // test existing
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("test_logs/dir1///dir2//", "test_logs/dir1/dir2"));
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("./test_logs/dir1/dir3", "test_logs/dir1/dir3"));
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("test_logs/../test_logs/dir1/dir4", "test_logs/dir1/dir4"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
					    // test backslash folder separator
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("test_logs\\dir1\\dir222", "test_logs\\dir1\\dir222"));
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("test_logs\\dir1\\dir223\\", "test_logs\\dir1\\dir223\\"));
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir(".\\test_logs\\dir1\\dir2\\dir99\\..\\dir23", "test_logs\\dir1\\dir2\\dir23"));
 | 
				
			||||||
 | 
					    REQUIRE(try_create_dir("test_logs\\..\\test_logs\\dir1\\dir5", "test_logs\\dir1\\dir5"));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_CASE("create_invalid_dir", "[create_dir]")
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUIRE(create_dir("") == false);
 | 
				
			||||||
 | 
					    REQUIRE(create_dir(spdlog::filename_t{}) == false);
 | 
				
			||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
					    REQUIRE(create_dir("/proc/spdlog-utest") == false);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_CASE("dir_name", "[create_dir]")
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    using spdlog::details::os::dir_name;
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("").empty());
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("dir").empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir\)") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir\\\)") == R"(dir\\)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir\file)") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir/file)") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir\file.txt)") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir/file)") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir\file.txt\)") == R"(dir\file.txt)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(dir/file.txt/)") == R"(dir\file.txt)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(\dir\file.txt)") == R"(\dir)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(/dir/file.txt)") == R"(\dir)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(\\dir\file.txt)") == R"(\\dir)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(//dir/file.txt)") == R"(\\dir)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(..\file.txt)") == "..");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(../file.txt)") == "..");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(.\file.txt)") == ".");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(./file.txt)") == ".");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(c:\\a\b\c\d\file.txt)") == R"(c:\\a\b\c\d)");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name(R"(c://a/b/c/d/file.txt)") == R"(c:\\a\b\c\d)");
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("dir/") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("dir///") == "dir//");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("dir/file") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("dir/file.txt") == "dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("dir/file.txt/") == "dir/file.txt");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("/dir/file.txt") == "/dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("//dir/file.txt") == "//dir");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("../file.txt") == "..");
 | 
				
			||||||
 | 
					    REQUIRE(dir_name("./file.txt") == ".");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -10,7 +10,7 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]")
 | 
				
			|||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // calculate filename (time based)
 | 
					    // calculate filename (time based)
 | 
				
			||||||
    std::string basename = "logs/daily_dateonly";
 | 
					    std::string basename = "test_logs/daily_dateonly";
 | 
				
			||||||
    std::tm tm = spdlog::details::os::localtime();
 | 
					    std::tm tm = spdlog::details::os::localtime();
 | 
				
			||||||
    spdlog::memory_buf_t w;
 | 
					    spdlog::memory_buf_t w;
 | 
				
			||||||
    fmt::format_to(w, "{}_{:04d}-{:02d}-{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
 | 
					    fmt::format_to(w, "{}_{:04d}-{:02d}-{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
 | 
				
			||||||
@@ -44,7 +44,7 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]")
 | 
				
			|||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // calculate filename (time based)
 | 
					    // calculate filename (time based)
 | 
				
			||||||
    std::string basename = "logs/daily_dateonly";
 | 
					    std::string basename = "test_logs/daily_dateonly";
 | 
				
			||||||
    std::tm tm = spdlog::details::os::localtime();
 | 
					    std::tm tm = spdlog::details::os::localtime();
 | 
				
			||||||
    spdlog::memory_buf_t w;
 | 
					    spdlog::memory_buf_t w;
 | 
				
			||||||
    fmt::format_to(w, "{}{:04d}{:02d}{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
 | 
					    fmt::format_to(w, "{}{:04d}{:02d}{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
 | 
				
			||||||
@@ -119,7 +119,7 @@ static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string basename = "logs/daily_rotate.txt";
 | 
					    std::string basename = "test_logs/daily_rotate.txt";
 | 
				
			||||||
    daily_file_sink_st sink{basename, 2, 30, true, max_days};
 | 
					    daily_file_sink_st sink{basename, 2, 30, true, max_days};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // simulate messages with 24 intervals
 | 
					    // simulate messages with 24 intervals
 | 
				
			||||||
@@ -130,7 +130,7 @@ static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_
 | 
				
			|||||||
        sink.log(create_msg(offset));
 | 
					        sink.log(create_msg(offset));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    REQUIRE(count_files("logs") == static_cast<size_t>(expected_n_files));
 | 
					    REQUIRE(count_files("test_logs") == static_cast<size_t>(expected_n_files));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_CASE("daily_logger rotate", "[daily_file_sink]")
 | 
					TEST_CASE("daily_logger rotate", "[daily_file_sink]")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ protected:
 | 
				
			|||||||
TEST_CASE("default_error_handler", "[errors]]")
 | 
					TEST_CASE("default_error_handler", "[errors]]")
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    std::string filename = "logs/simple_log.txt";
 | 
					    std::string filename = "test_logs/simple_log.txt";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("test-error", filename, true);
 | 
					    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("test-error", filename, true);
 | 
				
			||||||
    logger->set_pattern("%v");
 | 
					    logger->set_pattern("%v");
 | 
				
			||||||
@@ -43,7 +43,7 @@ struct custom_ex
 | 
				
			|||||||
TEST_CASE("custom_error_handler", "[errors]]")
 | 
					TEST_CASE("custom_error_handler", "[errors]]")
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    std::string filename = "logs/simple_log.txt";
 | 
					    std::string filename = "test_logs/simple_log.txt";
 | 
				
			||||||
    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
 | 
					    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
 | 
				
			||||||
    logger->flush_on(spdlog::level::info);
 | 
					    logger->flush_on(spdlog::level::info);
 | 
				
			||||||
    logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
 | 
					    logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
 | 
				
			||||||
@@ -75,15 +75,15 @@ TEST_CASE("async_error_handler", "[errors]]")
 | 
				
			|||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    std::string err_msg("log failed with some msg");
 | 
					    std::string err_msg("log failed with some msg");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string filename = "logs/simple_async_log.txt";
 | 
					    std::string filename = "test_logs/simple_async_log.txt";
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        spdlog::init_thread_pool(128, 1);
 | 
					        spdlog::init_thread_pool(128, 1);
 | 
				
			||||||
        auto logger = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
 | 
					        auto logger = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
 | 
				
			||||||
        logger->set_error_handler([=](const std::string &) {
 | 
					        logger->set_error_handler([=](const std::string &) {
 | 
				
			||||||
            std::ofstream ofs("logs/custom_err.txt");
 | 
					            std::ofstream ofs("test_logs/custom_err.txt");
 | 
				
			||||||
            if (!ofs)
 | 
					            if (!ofs)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw std::runtime_error("Failed open logs/custom_err.txt");
 | 
					                throw std::runtime_error("Failed open test_logs/custom_err.txt");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ofs << err_msg;
 | 
					            ofs << err_msg;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@@ -94,7 +94,7 @@ TEST_CASE("async_error_handler", "[errors]]")
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    spdlog::init_thread_pool(128, 1);
 | 
					    spdlog::init_thread_pool(128, 1);
 | 
				
			||||||
    REQUIRE(count_lines(filename) == 2);
 | 
					    REQUIRE(count_lines(filename) == 2);
 | 
				
			||||||
    REQUIRE(file_contents("logs/custom_err.txt") == err_msg);
 | 
					    REQUIRE(file_contents("test_logs/custom_err.txt") == err_msg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Make sure async error handler is executed
 | 
					// Make sure async error handler is executed
 | 
				
			||||||
@@ -103,12 +103,13 @@ TEST_CASE("async_error_handler2", "[errors]]")
 | 
				
			|||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    std::string err_msg("This is async handler error message");
 | 
					    std::string err_msg("This is async handler error message");
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        spdlog::details::os::create_dir("test_logs");
 | 
				
			||||||
        spdlog::init_thread_pool(128, 1);
 | 
					        spdlog::init_thread_pool(128, 1);
 | 
				
			||||||
        auto logger = spdlog::create_async<failing_sink>("failed_logger");
 | 
					        auto logger = spdlog::create_async<failing_sink>("failed_logger");
 | 
				
			||||||
        logger->set_error_handler([=](const std::string &) {
 | 
					        logger->set_error_handler([=](const std::string &) {
 | 
				
			||||||
            std::ofstream ofs("logs/custom_err2.txt");
 | 
					            std::ofstream ofs("test_logs/custom_err2.txt");
 | 
				
			||||||
            if (!ofs)
 | 
					            if (!ofs)
 | 
				
			||||||
                throw std::runtime_error("Failed open logs/custom_err2.txt");
 | 
					                throw std::runtime_error("Failed open test_logs/custom_err2.txt");
 | 
				
			||||||
            ofs << err_msg;
 | 
					            ofs << err_msg;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        logger->info("Hello failure");
 | 
					        logger->info("Hello failure");
 | 
				
			||||||
@@ -116,5 +117,5 @@ TEST_CASE("async_error_handler2", "[errors]]")
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    spdlog::init_thread_pool(128, 1);
 | 
					    spdlog::init_thread_pool(128, 1);
 | 
				
			||||||
    REQUIRE(file_contents("logs/custom_err2.txt") == err_msg);
 | 
					    REQUIRE(file_contents("test_logs/custom_err2.txt") == err_msg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
using spdlog::details::file_helper;
 | 
					using spdlog::details::file_helper;
 | 
				
			||||||
using spdlog::details::log_msg;
 | 
					using spdlog::details::log_msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const std::string target_filename = "logs/file_helper_test.txt";
 | 
					static const std::string target_filename = "test_logs/file_helper_test.txt";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void write_with_helper(file_helper &helper, size_t howmany)
 | 
					static void write_with_helper(file_helper &helper, size_t howmany)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -38,15 +38,6 @@ TEST_CASE("file_helper_size", "[file_helper::size()]]")
 | 
				
			|||||||
    REQUIRE(get_filesize(target_filename) == expected_size);
 | 
					    REQUIRE(get_filesize(target_filename) == expected_size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_CASE("file_helper_exists", "[file_helper::file_exists()]]")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    prepare_logdir();
 | 
					 | 
				
			||||||
    REQUIRE(!file_helper::file_exists(target_filename));
 | 
					 | 
				
			||||||
    file_helper helper;
 | 
					 | 
				
			||||||
    helper.open(target_filename);
 | 
					 | 
				
			||||||
    REQUIRE(file_helper::file_exists(target_filename));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]")
 | 
					TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]")
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
TEST_CASE("simple_file_logger", "[simple_logger]]")
 | 
					TEST_CASE("simple_file_logger", "[simple_logger]]")
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    std::string filename = "logs/simple_log";
 | 
					    std::string filename = "test_logs/simple_log";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
 | 
					    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
 | 
				
			||||||
    logger->set_pattern("%v");
 | 
					    logger->set_pattern("%v");
 | 
				
			||||||
@@ -22,7 +22,7 @@ TEST_CASE("simple_file_logger", "[simple_logger]]")
 | 
				
			|||||||
TEST_CASE("flush_on", "[flush_on]]")
 | 
					TEST_CASE("flush_on", "[flush_on]]")
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    std::string filename = "logs/simple_log";
 | 
					    std::string filename = "test_logs/simple_log";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
 | 
					    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
 | 
				
			||||||
    logger->set_pattern("%v");
 | 
					    logger->set_pattern("%v");
 | 
				
			||||||
@@ -42,7 +42,7 @@ TEST_CASE("rotating_file_logger1", "[rotating_logger]]")
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    size_t max_size = 1024 * 10;
 | 
					    size_t max_size = 1024 * 10;
 | 
				
			||||||
    std::string basename = "logs/rotating_log";
 | 
					    std::string basename = "test_logs/rotating_log";
 | 
				
			||||||
    auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 0);
 | 
					    auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int i = 0; i < 10; ++i)
 | 
					    for (int i = 0; i < 10; ++i)
 | 
				
			||||||
@@ -59,7 +59,7 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]]")
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    size_t max_size = 1024 * 10;
 | 
					    size_t max_size = 1024 * 10;
 | 
				
			||||||
    std::string basename = "logs/rotating_log";
 | 
					    std::string basename = "test_logs/rotating_log";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // make an initial logger to create the first output file
 | 
					        // make an initial logger to create the first output file
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ TEST_CASE("debug and trace w/o format string", "[macros]]")
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    prepare_logdir();
 | 
					    prepare_logdir();
 | 
				
			||||||
    std::string filename = "logs/simple_log";
 | 
					    std::string filename = "test_logs/simple_log";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
 | 
					    auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename);
 | 
				
			||||||
    logger->set_pattern("%v");
 | 
					    logger->set_pattern("%v");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,18 +9,12 @@ void prepare_logdir()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    spdlog::drop_all();
 | 
					    spdlog::drop_all();
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
    system("if not exist logs mkdir logs");
 | 
					    system("rmdir /S /Q test_logs");
 | 
				
			||||||
    system("del /F /Q logs\\*");
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    auto rv = system("mkdir -p logs");
 | 
					    auto rv = system("rm -rf test_logs");
 | 
				
			||||||
    if (rv != 0)
 | 
					    if (rv != 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        throw std::runtime_error("Failed to mkdir -p logs");
 | 
					        throw std::runtime_error("Failed to rm -rf test_logs");
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    rv = system("rm -f logs/*");
 | 
					 | 
				
			||||||
    if (rv != 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        throw std::runtime_error("Failed to rm -f logs/*");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user