diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b2d2fb8f8..f8c5a42f51 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -318,6 +318,7 @@ set(MAIN_SRCS digest.cc net_util.cc util.cc + util-types.cc module_util.cc zeek-affinity.cc zeek-setup.cc diff --git a/src/util-types.cc b/src/util-types.cc new file mode 100644 index 0000000000..f67e4a9c4b --- /dev/null +++ b/src/util-types.cc @@ -0,0 +1,78 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/util-types.h" + +#include "zeek/Reporter.h" + +#include "zeek/3rdparty/doctest.h" + +namespace zeek::util { + +namespace detail { + +void SafePathOp::CheckValid(const char* op_result, const char* path, bool error_aborts) { + if ( op_result ) { + result = op_result; + error = false; + } + else { + if ( error_aborts ) + reporter->InternalError("Path operation failed on %s: %s", path ? path : "", strerror(errno)); + else + error = true; + } +} + + +TEST_CASE("util path ops") { +#ifdef _MSC_VER +// TODO: adapt these tests to Windows paths +#else + SUBCASE("SafeDirname") { + SafeDirname d("/this/is/a/path", false); + CHECK(d.result == "/this/is/a"); + + SafeDirname d2("invalid", false); + CHECK(d2.result == "."); + + SafeDirname d3("./filename", false); + CHECK(d2.result == "."); + } + + SUBCASE("SafeBasename") { + SafeBasename b("/this/is/a/path", false); + CHECK(b.result == "path"); + CHECK(! b.error); + + SafeBasename b2("justafile", false); + CHECK(b2.result == "justafile"); + CHECK(! b2.error); + } +#endif +} + +} // namespace detail + +SafeDirname::SafeDirname(const char* path, bool error_aborts) : SafePathOp() { DoFunc(path ? path : "", error_aborts); } + +SafeDirname::SafeDirname(const std::string& path, bool error_aborts) : SafePathOp() { DoFunc(path, error_aborts); } + +void SafeDirname::DoFunc(const std::string& path, bool error_aborts) { + char* tmp = copy_string(path.c_str()); + CheckValid(dirname(tmp), tmp, error_aborts); + delete[] tmp; +} + +SafeBasename::SafeBasename(const char* path, bool error_aborts) : SafePathOp() { + DoFunc(path ? path : "", error_aborts); +} + +SafeBasename::SafeBasename(const std::string& path, bool error_aborts) : SafePathOp() { DoFunc(path, error_aborts); } + +void SafeBasename::DoFunc(const std::string& path, bool error_aborts) { + char* tmp = copy_string(path.c_str()); + CheckValid(basename(tmp), tmp, error_aborts); + delete[] tmp; +} + +} // namespace zeek::util diff --git a/src/util-types.h b/src/util-types.h new file mode 100644 index 0000000000..da66c2fb3c --- /dev/null +++ b/src/util-types.h @@ -0,0 +1,66 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +#include "zeek/3rdparty/nonstd/expected.hpp" +#include "zeek/Span.h" + +// These two types are not namespaced intentionally. +using zeek_int_t = int64_t; +using zeek_uint_t = uint64_t; + +namespace zeek { + +// Type aliases for nonstd::expected/nonstd::unexpected. These should be switched to use +// the std:: versions once we switch to C++20. +template +using expected = nonstd::expected; + +template +using unexpected = nonstd::unexpected; + +// Byte buffer types used by serialization code in storage and cluster. +using byte_buffer = std::vector; +using byte_buffer_span = Span; + +namespace util { +namespace detail { + +/** + * Wrapper class for functions like dirname(3) or basename(3) that won't + * modify the path argument and may optionally abort execution on error. + */ +class SafePathOp { +public: + std::string result; + bool error = false; + +protected: + void CheckValid(const char* result, const char* path, bool error_aborts); +}; + +} // namespace detail + +class SafeDirname : public detail::SafePathOp { +public: + explicit SafeDirname(const char* path, bool error_aborts = true); + explicit SafeDirname(const std::string& path, bool error_aborts = true); + +private: + void DoFunc(const std::string& path, bool error_aborts = true); +}; + +class SafeBasename : public detail::SafePathOp { +public: + explicit SafeBasename(const char* path, bool error_aborts = true); + explicit SafeBasename(const std::string& path, bool error_aborts = true); + +private: + void DoFunc(const std::string& path, bool error_aborts = true); +}; + +} // namespace util +} // namespace zeek diff --git a/src/util.cc b/src/util.cc index 19551b6d60..2a59ea8a2a 100644 --- a/src/util.cc +++ b/src/util.cc @@ -531,19 +531,6 @@ FILE* open_package(string& path, const string& mode) { return nullptr; } -void SafePathOp::CheckValid(const char* op_result, const char* path, bool error_aborts) { - if ( op_result ) { - result = op_result; - error = false; - } - else { - if ( error_aborts ) - reporter->InternalError("Path operation failed on %s: %s", path ? path : "", strerror(errno)); - else - error = true; - } -} - TEST_CASE("util flatten_script_name") { CHECK(flatten_script_name("script", "some/path") == "some.path.script"); #ifndef _MSC_VER @@ -1647,55 +1634,6 @@ FILE* open_file(const string& path, const string& mode) { return rval; } -TEST_CASE("util path ops") { -#ifdef _MSC_VER -// TODO: adapt these tests to Windows paths -#else - SUBCASE("SafeDirname") { - SafeDirname d("/this/is/a/path", false); - CHECK(d.result == "/this/is/a"); - - SafeDirname d2("invalid", false); - CHECK(d2.result == "."); - - SafeDirname d3("./filename", false); - CHECK(d2.result == "."); - } - - SUBCASE("SafeBasename") { - SafeBasename b("/this/is/a/path", false); - CHECK(b.result == "path"); - CHECK(! b.error); - - SafeBasename b2("justafile", false); - CHECK(b2.result == "justafile"); - CHECK(! b2.error); - } -#endif -} - -SafeDirname::SafeDirname(const char* path, bool error_aborts) : SafePathOp() { DoFunc(path ? path : "", error_aborts); } - -SafeDirname::SafeDirname(const string& path, bool error_aborts) : SafePathOp() { DoFunc(path, error_aborts); } - -void SafeDirname::DoFunc(const string& path, bool error_aborts) { - char* tmp = copy_string(path.c_str()); - CheckValid(dirname(tmp), tmp, error_aborts); - delete[] tmp; -} - -SafeBasename::SafeBasename(const char* path, bool error_aborts) : SafePathOp() { - DoFunc(path ? path : "", error_aborts); -} - -SafeBasename::SafeBasename(const string& path, bool error_aborts) : SafePathOp() { DoFunc(path, error_aborts); } - -void SafeBasename::DoFunc(const string& path, bool error_aborts) { - char* tmp = copy_string(path.c_str()); - CheckValid(basename(tmp), tmp, error_aborts); - delete[] tmp; -} - TEST_CASE("util implode_string_vector") { std::vector v = {"a", "b", "c"}; CHECK(implode_string_vector(v, ",") == "a,b,c"); diff --git a/src/util.h b/src/util.h index 4f50d3474c..314f99bf37 100644 --- a/src/util.h +++ b/src/util.h @@ -92,19 +92,7 @@ namespace filesystem = ghc::filesystem; inline constexpr std::string_view path_list_separator = ":"; #endif -#include "zeek/3rdparty/nonstd/expected.hpp" -namespace zeek { -template -using expected = nonstd::expected; - -template -using unexpected = nonstd::unexpected; -} // namespace zeek - -#include "zeek/Span.h" - -using zeek_int_t = int64_t; -using zeek_uint_t = uint64_t; +#include "zeek/util-types.h" #ifndef HAVE_STRCASESTR extern char* strcasestr(const char* s, const char* find); @@ -118,10 +106,6 @@ namespace zeek { class ODesc; class RecordVal; -// Byte buffer types used by serialization code in storage and cluster. -using byte_buffer = std::vector; -using byte_buffer_span = Span; - namespace util { namespace detail { @@ -220,21 +204,6 @@ bool is_package_loader(const std::string& path); extern void add_to_zeek_path(const std::string& dir); -/** - * Wrapper class for functions like dirname(3) or basename(3) that won't - * modify the path argument and may optionally abort execution on error. - */ -class SafePathOp { -public: - std::string result; - bool error; - -protected: - SafePathOp() : result(), error() {} - - void CheckValid(const char* result, const char* path, bool error_aborts); -}; - /** * Flatten a script name by replacing '/' path separators with '.'. * @param file A path to a Zeek script. If it is a __load__.zeek, that part @@ -398,24 +367,6 @@ extern const char* zeek_plugin_path(); extern const char* zeek_plugin_activate(); extern std::string zeek_prefixes(); -class SafeDirname : public detail::SafePathOp { -public: - explicit SafeDirname(const char* path, bool error_aborts = true); - explicit SafeDirname(const std::string& path, bool error_aborts = true); - -private: - void DoFunc(const std::string& path, bool error_aborts = true); -}; - -class SafeBasename : public detail::SafePathOp { -public: - explicit SafeBasename(const char* path, bool error_aborts = true); - explicit SafeBasename(const std::string& path, bool error_aborts = true); - -private: - void DoFunc(const std::string& path, bool error_aborts = true); -}; - std::string implode_string_vector(const std::vector& v, const std::string& delim = "\n"); /**