From de566d441d3373b74f62d9bb672ad1f2e8f57b4d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 21 Aug 2018 01:13:18 +0200 Subject: [PATCH] move common code to VILLAScommon submodule --- fpga/.gitmodules | 3 + fpga/CMakeLists.txt | 12 +- fpga/common | 1 + fpga/include/villas/common.h | 36 - fpga/include/villas/directed_graph.hpp | 355 - fpga/include/villas/log.hpp | 55 - fpga/include/villas/memory.hpp | 309 - fpga/include/villas/memory_manager.hpp | 273 - fpga/include/villas/plugin.hpp | 113 - fpga/include/villas/utils.hpp | 46 - fpga/lib/CMakeLists.txt | 3 +- fpga/lib/common/CMakeLists.txt | 37 - fpga/lib/common/memory.cpp | 300 - fpga/lib/common/memory_manager.cpp | 256 - fpga/lib/common/plugin.cpp | 160 - fpga/lib/common/utils.cpp | 57 - fpga/tests/CMakeLists.txt | 1 - fpga/tests/graph.cpp | 159 - fpga/thirdparty/spdlog/.gitignore | 67 - fpga/thirdparty/spdlog/.travis.yml | 91 - fpga/thirdparty/spdlog/CMakeLists.txt | 116 - fpga/thirdparty/spdlog/INSTALL | 13 - fpga/thirdparty/spdlog/LICENSE | 22 - fpga/thirdparty/spdlog/README.md | 221 - fpga/thirdparty/spdlog/appveyor.yml | 32 - fpga/thirdparty/spdlog/astyle.sh | 5 - fpga/thirdparty/spdlog/bench/Makefile | 62 - fpga/thirdparty/spdlog/bench/Makefile.mingw | 57 - .../spdlog/bench/boost-bench-mt.cpp | 84 - fpga/thirdparty/spdlog/bench/boost-bench.cpp | 47 - fpga/thirdparty/spdlog/bench/easyl.conf | 10 - .../spdlog/bench/easylogging-bench-mt.cpp | 52 - .../spdlog/bench/easylogging-bench.cpp | 22 - fpga/thirdparty/spdlog/bench/g2log-async.cpp | 62 - .../thirdparty/spdlog/bench/glog-bench-mt.cpp | 50 - fpga/thirdparty/spdlog/bench/glog-bench.cpp | 21 - fpga/thirdparty/spdlog/bench/latency/Makefile | 32 - .../spdlog/bench/latency/compare.sh | 13 - .../spdlog/bench/latency/g3log-crush.cpp | 37 - .../spdlog/bench/latency/g3log-latency.cpp | 129 - .../spdlog/bench/latency/spdlog-latency.cpp | 128 - fpga/thirdparty/spdlog/bench/latency/utils.h | 35 - fpga/thirdparty/spdlog/bench/logs/.gitignore | 4 - fpga/thirdparty/spdlog/bench/spdlog-async.cpp | 62 - .../spdlog/bench/spdlog-bench-mt.cpp | 55 - fpga/thirdparty/spdlog/bench/spdlog-bench.cpp | 20 - .../spdlog/bench/spdlog-null-async.cpp | 112 - fpga/thirdparty/spdlog/bench/utils.h | 35 - fpga/thirdparty/spdlog/cmake/Config.cmake.in | 24 - fpga/thirdparty/spdlog/cmake/spdlog.pc.in | 6 - fpga/thirdparty/spdlog/example/CMakeLists.txt | 49 - fpga/thirdparty/spdlog/example/Makefile | 29 - fpga/thirdparty/spdlog/example/Makefile.clang | 32 - fpga/thirdparty/spdlog/example/Makefile.mingw | 32 - fpga/thirdparty/spdlog/example/bench.cpp | 144 - fpga/thirdparty/spdlog/example/example.cpp | 167 - fpga/thirdparty/spdlog/example/example.sln | 26 - .../thirdparty/spdlog/example/example.vcxproj | 126 - fpga/thirdparty/spdlog/example/jni/Android.mk | 15 - .../spdlog/example/jni/Application.mk | 2 - .../thirdparty/spdlog/example/jni/example.cpp | 1 - .../thirdparty/spdlog/example/logs/.gitignore | 1 - fpga/thirdparty/spdlog/example/multisink.cpp | 47 - fpga/thirdparty/spdlog/example/utils.h | 35 - .../spdlog/include/spdlog/async_logger.h | 82 - .../thirdparty/spdlog/include/spdlog/common.h | 161 - .../include/spdlog/details/async_log_helper.h | 399 - .../spdlog/details/async_logger_impl.h | 107 - .../include/spdlog/details/file_helper.h | 145 - .../spdlog/include/spdlog/details/log_msg.h | 50 - .../include/spdlog/details/logger_impl.h | 373 - .../include/spdlog/details/mpmc_bounded_q.h | 176 - .../include/spdlog/details/null_mutex.h | 45 - .../spdlog/include/spdlog/details/os.h | 479 - .../spdlog/details/pattern_formatter_impl.h | 699 -- .../spdlog/include/spdlog/details/registry.h | 225 - .../include/spdlog/details/spdlog_impl.h | 268 - .../include/spdlog/fmt/bundled/LICENSE.rst | 23 - .../include/spdlog/fmt/bundled/format.cc | 535 - .../include/spdlog/fmt/bundled/format.h | 4659 -------- .../include/spdlog/fmt/bundled/ostream.cc | 35 - .../include/spdlog/fmt/bundled/ostream.h | 114 - .../include/spdlog/fmt/bundled/posix.cc | 241 - .../spdlog/include/spdlog/fmt/bundled/posix.h | 424 - .../include/spdlog/fmt/bundled/printf.cc | 32 - .../include/spdlog/fmt/bundled/printf.h | 712 -- .../spdlog/include/spdlog/fmt/bundled/time.h | 183 - .../spdlog/include/spdlog/fmt/fmt.h | 34 - .../spdlog/include/spdlog/fmt/ostr.h | 17 - .../spdlog/include/spdlog/formatter.h | 47 - .../thirdparty/spdlog/include/spdlog/logger.h | 110 - .../include/spdlog/sinks/android_sink.h | 90 - .../include/spdlog/sinks/ansicolor_sink.h | 133 - .../spdlog/include/spdlog/sinks/base_sink.h | 51 - .../spdlog/include/spdlog/sinks/dist_sink.h | 72 - .../spdlog/include/spdlog/sinks/file_sinks.h | 253 - .../spdlog/include/spdlog/sinks/msvc_sink.h | 51 - .../spdlog/include/spdlog/sinks/null_sink.h | 34 - .../include/spdlog/sinks/ostream_sink.h | 47 - .../spdlog/include/spdlog/sinks/sink.h | 53 - .../include/spdlog/sinks/stdout_sinks.h | 77 - .../spdlog/include/spdlog/sinks/syslog_sink.h | 81 - .../include/spdlog/sinks/wincolor_sink.h | 121 - .../include/spdlog/sinks/windebug_sink.h | 29 - .../thirdparty/spdlog/include/spdlog/spdlog.h | 192 - .../spdlog/include/spdlog/tweakme.h | 160 - fpga/thirdparty/spdlog/tests/CMakeLists.txt | 19 - fpga/thirdparty/spdlog/tests/Makefile | 28 - fpga/thirdparty/spdlog/tests/catch.hpp | 9427 ----------------- fpga/thirdparty/spdlog/tests/catch.license | 23 - fpga/thirdparty/spdlog/tests/errors.cpp | 126 - fpga/thirdparty/spdlog/tests/file_helper.cpp | 118 - fpga/thirdparty/spdlog/tests/file_log.cpp | 248 - fpga/thirdparty/spdlog/tests/format.cpp | 56 - fpga/thirdparty/spdlog/tests/includes.h | 18 - .../thirdparty/spdlog/tests/install_libcxx.sh | 12 - fpga/thirdparty/spdlog/tests/main.cpp | 2 - fpga/thirdparty/spdlog/tests/registry.cpp | 84 - fpga/thirdparty/spdlog/tests/test_macros.cpp | 50 - fpga/thirdparty/spdlog/tests/tests.sln | 28 - fpga/thirdparty/spdlog/tests/tests.vcxproj | 145 - .../spdlog/tests/tests.vcxproj.filters | 54 - fpga/thirdparty/spdlog/tests/utils.cpp | 56 - fpga/thirdparty/spdlog/tests/utils.h | 16 - 124 files changed, 11 insertions(+), 26926 deletions(-) create mode 160000 fpga/common delete mode 100644 fpga/include/villas/common.h delete mode 100644 fpga/include/villas/directed_graph.hpp delete mode 100644 fpga/include/villas/log.hpp delete mode 100644 fpga/include/villas/memory.hpp delete mode 100644 fpga/include/villas/memory_manager.hpp delete mode 100644 fpga/include/villas/plugin.hpp delete mode 100644 fpga/include/villas/utils.hpp delete mode 100644 fpga/lib/common/CMakeLists.txt delete mode 100644 fpga/lib/common/memory.cpp delete mode 100644 fpga/lib/common/memory_manager.cpp delete mode 100644 fpga/lib/common/plugin.cpp delete mode 100644 fpga/lib/common/utils.cpp delete mode 100644 fpga/tests/graph.cpp delete mode 100644 fpga/thirdparty/spdlog/.gitignore delete mode 100644 fpga/thirdparty/spdlog/.travis.yml delete mode 100644 fpga/thirdparty/spdlog/CMakeLists.txt delete mode 100644 fpga/thirdparty/spdlog/INSTALL delete mode 100644 fpga/thirdparty/spdlog/LICENSE delete mode 100644 fpga/thirdparty/spdlog/README.md delete mode 100644 fpga/thirdparty/spdlog/appveyor.yml delete mode 100755 fpga/thirdparty/spdlog/astyle.sh delete mode 100644 fpga/thirdparty/spdlog/bench/Makefile delete mode 100644 fpga/thirdparty/spdlog/bench/Makefile.mingw delete mode 100644 fpga/thirdparty/spdlog/bench/boost-bench-mt.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/boost-bench.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/easyl.conf delete mode 100644 fpga/thirdparty/spdlog/bench/easylogging-bench-mt.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/easylogging-bench.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/g2log-async.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/glog-bench-mt.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/glog-bench.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/latency/Makefile delete mode 100755 fpga/thirdparty/spdlog/bench/latency/compare.sh delete mode 100644 fpga/thirdparty/spdlog/bench/latency/g3log-crush.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/latency/g3log-latency.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/latency/spdlog-latency.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/latency/utils.h delete mode 100644 fpga/thirdparty/spdlog/bench/logs/.gitignore delete mode 100644 fpga/thirdparty/spdlog/bench/spdlog-async.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/spdlog-bench-mt.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/spdlog-bench.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/spdlog-null-async.cpp delete mode 100644 fpga/thirdparty/spdlog/bench/utils.h delete mode 100644 fpga/thirdparty/spdlog/cmake/Config.cmake.in delete mode 100644 fpga/thirdparty/spdlog/cmake/spdlog.pc.in delete mode 100644 fpga/thirdparty/spdlog/example/CMakeLists.txt delete mode 100644 fpga/thirdparty/spdlog/example/Makefile delete mode 100644 fpga/thirdparty/spdlog/example/Makefile.clang delete mode 100644 fpga/thirdparty/spdlog/example/Makefile.mingw delete mode 100644 fpga/thirdparty/spdlog/example/bench.cpp delete mode 100644 fpga/thirdparty/spdlog/example/example.cpp delete mode 100644 fpga/thirdparty/spdlog/example/example.sln delete mode 100644 fpga/thirdparty/spdlog/example/example.vcxproj delete mode 100644 fpga/thirdparty/spdlog/example/jni/Android.mk delete mode 100644 fpga/thirdparty/spdlog/example/jni/Application.mk delete mode 120000 fpga/thirdparty/spdlog/example/jni/example.cpp delete mode 100644 fpga/thirdparty/spdlog/example/logs/.gitignore delete mode 100644 fpga/thirdparty/spdlog/example/multisink.cpp delete mode 100644 fpga/thirdparty/spdlog/example/utils.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/async_logger.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/common.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/async_log_helper.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/async_logger_impl.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/file_helper.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/log_msg.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/logger_impl.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/mpmc_bounded_q.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/null_mutex.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/os.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/pattern_formatter_impl.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/registry.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/details/spdlog_impl.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/LICENSE.rst delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.cc delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.cc delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.cc delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.cc delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/time.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/fmt.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/fmt/ostr.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/formatter.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/logger.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/android_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/ansicolor_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/base_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/dist_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/file_sinks.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/msvc_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/null_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/ostream_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/stdout_sinks.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/syslog_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/wincolor_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/sinks/windebug_sink.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/spdlog.h delete mode 100644 fpga/thirdparty/spdlog/include/spdlog/tweakme.h delete mode 100644 fpga/thirdparty/spdlog/tests/CMakeLists.txt delete mode 100644 fpga/thirdparty/spdlog/tests/Makefile delete mode 100644 fpga/thirdparty/spdlog/tests/catch.hpp delete mode 100644 fpga/thirdparty/spdlog/tests/catch.license delete mode 100644 fpga/thirdparty/spdlog/tests/errors.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/file_helper.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/file_log.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/format.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/includes.h delete mode 100755 fpga/thirdparty/spdlog/tests/install_libcxx.sh delete mode 100644 fpga/thirdparty/spdlog/tests/main.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/registry.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/test_macros.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/tests.sln delete mode 100644 fpga/thirdparty/spdlog/tests/tests.vcxproj delete mode 100644 fpga/thirdparty/spdlog/tests/tests.vcxproj.filters delete mode 100644 fpga/thirdparty/spdlog/tests/utils.cpp delete mode 100644 fpga/thirdparty/spdlog/tests/utils.h diff --git a/fpga/.gitmodules b/fpga/.gitmodules index 08e93f915..5635c297e 100644 --- a/fpga/.gitmodules +++ b/fpga/.gitmodules @@ -13,3 +13,6 @@ [submodule "hardware"] path = hardware url = ../VILLASfpga-hardware.git +[submodule "common"] + path = common + url = git@git.rwth-aachen.de:acs/public/villas/VILLAScommon.git diff --git a/fpga/CMakeLists.txt b/fpga/CMakeLists.txt index b7d88750b..9a7b0bf6b 100644 --- a/fpga/CMakeLists.txt +++ b/fpga/CMakeLists.txt @@ -26,13 +26,13 @@ project(VILLASfpga C CXX) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) -set (CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") -include_directories(thirdparty/spdlog/include) include_directories(thirdparty/CLI11) include_directories(thirdparty/rang) +add_subdirectory(common) add_subdirectory(lib) add_subdirectory(src) add_subdirectory(tests) @@ -52,10 +52,10 @@ configure_file("libvillas-fpga.pc.in" "libvillas-fpga.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libvillas-fpga.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig") # CPack -SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION}) -SET(CPACK_PACKAGE_VENDOR ${PROJECT_VENDOR}) -SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") -SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.md") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION}) +set(CPACK_PACKAGE_VENDOR ${PROJECT_VENDOR}) +set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.md") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_PACKAGE_NAME "villas-fpga") diff --git a/fpga/common b/fpga/common new file mode 160000 index 000000000..5cae8b6b0 --- /dev/null +++ b/fpga/common @@ -0,0 +1 @@ +Subproject commit 5cae8b6b0ff8531d0ceadb07519813c9e6f4cc38 diff --git a/fpga/include/villas/common.h b/fpga/include/villas/common.h deleted file mode 100644 index 180479af9..000000000 --- a/fpga/include/villas/common.h +++ /dev/null @@ -1,36 +0,0 @@ -/** Some common defines, enums and datastructures. - * - * @file - * @author Steffen Vogel - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#pragma once - -/* Common states for most objects in VILLASfpga (paths, nodes, hooks, plugins) */ -enum state { - STATE_DESTROYED = 0, - STATE_INITIALIZED = 1, - STATE_PARSED = 2, - STATE_CHECKED = 3, - STATE_STARTED = 4, - STATE_LOADED = 4, /* alias for STATE_STARTED used by plugins */ - STATE_STOPPED = 5, - STATE_UNLOADED = 5 /* alias for STATE_STARTED used by plugins */ -}; diff --git a/fpga/include/villas/directed_graph.hpp b/fpga/include/villas/directed_graph.hpp deleted file mode 100644 index 18f58a9cc..000000000 --- a/fpga/include/villas/directed_graph.hpp +++ /dev/null @@ -1,355 +0,0 @@ -/** A directed graph. - * - * @file - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -namespace villas { -namespace graph { - -// use vector indices as identifiers - -// forward declarations -class Edge; -class Vertex; - - -class Vertex { - template - friend class DirectedGraph; - -public: - using Identifier = std::size_t; - - const Identifier& - getIdentifier() const - { return id; } - - friend std::ostream& - operator<< (std::ostream& stream, const Vertex& vertex) - { return stream << vertex.id; } - - bool - operator==(const Vertex& other) - { return this->id == other.id; } - -private: - Identifier id; - // HACK: how to resolve this circular type dependency? - std::list edges; -}; - - -class Edge { - template - friend class DirectedGraph; - -public: - using Identifier = std::size_t; - - friend std::ostream& - operator<< (std::ostream& stream, const Edge& edge) - { return stream << edge.id; } - - bool - operator==(const Edge& other) - { return this->id == other.id; } - - Vertex::Identifier getVertexTo() const - { return to; } - - Vertex::Identifier getVertexFrom() const - { return from; } - -private: - Identifier id; - Vertex::Identifier from; - Vertex::Identifier to; -}; - - -template -class DirectedGraph { -public: - - using VertexIdentifier = Vertex::Identifier; - using EdgeIdentifier = Edge::Identifier; - using Path = std::list; - - DirectedGraph(const std::string& name = "DirectedGraph") : - lastVertexId(0), lastEdgeId(0) - { - logger = loggerGetOrCreate(name); - } - - std::shared_ptr getVertex(VertexIdentifier vertexId) const - { - if(vertexId >= lastVertexId) - throw std::invalid_argument("vertex doesn't exist"); - - // cannot use [] operator, because creates non-existing elements - // at() will throw std::out_of_range if element does not exist - return vertices.at(vertexId); - } - - template - VertexIdentifier findVertex(UnaryPredicate p) - { - for(auto& v : vertices) { - auto& vertexId = v.first; - auto& vertex = v.second; - - if(p(vertex)) { - return vertexId; - } - } - - throw std::out_of_range("vertex not found"); - } - - std::shared_ptr getEdge(EdgeIdentifier edgeId) const - { - if(edgeId >= lastEdgeId) - throw std::invalid_argument("edge doesn't exist"); - - // cannot use [] operator, because creates non-existing elements - // at() will throw std::out_of_range if element does not exist - return edges.at(edgeId); - } - - std::size_t getEdgeCount() const - { return edges.size(); } - - std::size_t getVertexCount() const - { return vertices.size(); } - - VertexIdentifier addVertex(std::shared_ptr vertex) - { - vertex->id = lastVertexId++; - - logger->debug("New vertex: {}", *vertex); - vertices[vertex->id] = vertex; - - return vertex->id; - } - - EdgeIdentifier addEdge(std::shared_ptr edge, - VertexIdentifier fromVertexId, - VertexIdentifier toVertexId) - { - // allocate edge id - edge->id = lastEdgeId++; - - // connect it - edge->from = fromVertexId; - edge->to = toVertexId; - - logger->debug("New edge {}: {} -> {}", *edge, edge->from, edge->to); - - // this is a directed graph, so only push edge to starting vertex - getVertex(edge->from)->edges.push_back(edge->id); - - // add new edge to graph - edges[edge->id] = edge; - - return edge->id; - } - - - EdgeIdentifier addDefaultEdge(VertexIdentifier fromVertexId, - VertexIdentifier toVertexId) - { - // create a new edge - std::shared_ptr edge(new EdgeType); - - return addEdge(edge, fromVertexId, toVertexId); - } - - void removeEdge(EdgeIdentifier edgeId) - { - auto edge = getEdge(edgeId); - auto startVertex = getVertex(edge->from); - - // remove edge only from starting vertex (this is a directed graph) - logger->debug("Remove edge {} from vertex {}", edgeId, edge->from); - startVertex->edges.remove(edgeId); - - logger->debug("Remove edge {}", edgeId); - edges.erase(edgeId); - } - - void removeVertex(VertexIdentifier vertexId) - { - // delete every edge that start or ends at this vertex - auto it = edges.begin(); - while(it != edges.end()) { - auto& edgeId = it->first; - auto& edge = it->second; - - bool removeEdge = false; - - if(edge->to == vertexId) { - logger->debug("Remove edge {} from vertex {}'s edge list", - edgeId, edge->from); - - removeEdge = true; - - auto startVertex = getVertex(edge->from); - startVertex->edges.remove(edge->id); - } - - if((edge->from == vertexId) or removeEdge) { - logger->debug("Remove edge {}", edgeId); - // remove edge from global edge list - it = edges.erase(it); - } else { - ++it; - } - } - - logger->debug("Remove vertex {}", vertexId); - vertices.erase(vertexId); - } - - const std::list& - vertexGetEdges(VertexIdentifier vertexId) const - { return getVertex(vertexId)->edges; } - - - using check_path_fn = std::function; - - static bool - checkPath(const Path&) - { return true; } - - bool getPath(VertexIdentifier fromVertexId, - VertexIdentifier toVertexId, - Path& path, - check_path_fn pathCheckFunc = checkPath) - { - if(fromVertexId == toVertexId) { - // arrived at the destination - return true; - } else { - auto fromVertex = getVertex(fromVertexId); - - for(auto& edgeId : fromVertex->edges) { - auto edgeOfFromVertex = getEdge(edgeId); - - // loop detection - bool loop = false; - for(auto& edgeIdInPath : path) { - auto edgeInPath = getEdge(edgeIdInPath); - if(edgeInPath->from == edgeOfFromVertex->to) { - loop = true; - break; - } - } - - if(loop) { - logger->debug("Loop detected via edge {}", edgeId); - continue; - } - - // remember the path we're investigating to detect loops - path.push_back(edgeId); - - // recursive, depth-first search - if(getPath(edgeOfFromVertex->to, toVertexId, path, pathCheckFunc) and - pathCheckFunc(path)) { - // path found, we're done - return true; - } else { - // tear down path that didn't lead to the destination - path.pop_back(); - } - } - } - - return false; - } - - void dump(const std::string& fileName = "") - { - logger->info("Vertices:"); - for(auto& v : vertices) { - auto& vertex = v.second; - - // format connected vertices into a list - std::stringstream ssEdges; - for(auto& edge : vertex->edges) { - ssEdges << getEdge(edge)->to << " "; - } - - logger->info(" {} connected to: {}", *vertex, ssEdges.str()); - } - - std::fstream s(fileName, s.out | s.trunc); - if(s.is_open()) { - s << "digraph memgraph {" << std::endl; - } - - logger->info("Edges:"); - for(auto& e : edges) { - auto& edge = e.second; - - logger->info(" {}: {} -> {}", *edge, edge->from, edge->to); - if(s.is_open()) { - auto from = getVertex(edge->from); - auto to = getVertex(edge->to); - - s << std::dec; - s << " \"" << *from << "\" -> \"" << *to << "\"" - << " [label=\"" << *edge << "\"];" << std::endl; - } - } - - if(s.is_open()) { - s << "}" << std::endl; - s.close(); - } - } - -protected: - VertexIdentifier lastVertexId; - EdgeIdentifier lastEdgeId; - - std::map> vertices; - std::map> edges; - - SpdLogger logger; -}; - -} // namespacae graph -} // namespace villas diff --git a/fpga/include/villas/log.hpp b/fpga/include/villas/log.hpp deleted file mode 100644 index e814412b6..000000000 --- a/fpga/include/villas/log.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/** Logging. - * - * @file - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#pragma once - -#include - -#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info ", "warn ", "error", "crit ", "off " } -#define SPDLOG_NAME_WIDTH 17 - -#include -#include - -#define _ESCAPE "\x1b" -#define TXT_RESET_ALL _ESCAPE "[0m" - -#define TXT_RESET_BOLD _ESCAPE "[21m" -#define TXT_BOLD(s) _ESCAPE "[1m" + std::string(s) + TXT_RESET_BOLD - -#define TXT_RESET_COLOR _ESCAPE "[39m" -#define TXT_RED(s) _ESCAPE "[31m" + std::string(s) + TXT_RESET_COLOR -#define TXT_GREEN(s) _ESCAPE "[32m" + std::string(s) + TXT_RESET_COLOR -#define TXT_YELLOW(s) _ESCAPE "[33m" + std::string(s) + TXT_RESET_COLOR -#define TXT_BLUE(s) _ESCAPE "[34m" + std::string(s) + TXT_RESET_COLOR - -using SpdLogger = std::shared_ptr; - -inline SpdLogger loggerGetOrCreate(const std::string& logger_name) -{ - auto logger = spdlog::get(logger_name); - if(not logger) { - logger = spdlog::stdout_color_mt(logger_name); - } - return logger; -} diff --git a/fpga/include/villas/memory.hpp b/fpga/include/villas/memory.hpp deleted file mode 100644 index 75311fb2f..000000000 --- a/fpga/include/villas/memory.hpp +++ /dev/null @@ -1,309 +0,0 @@ -/** Memory management. - * - * @file - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#pragma once - -#include -#include - -#include -#include - -namespace villas { - -/** - * @brief Basic memory block backed by an address space in the memory graph - * - * This is a generic representation of a chunk of memory in the system. It can - * reside anywhere and represent different types of memory. - */ -class MemoryBlock { -public: - using deallocator_fn = std::function; - - MemoryBlock(size_t offset, size_t size, MemoryManager::AddressSpaceId addrSpaceId) : - offset(offset), size(size), addrSpaceId(addrSpaceId) {} - - MemoryManager::AddressSpaceId getAddrSpaceId() const - { return addrSpaceId; } - - size_t getSize() const - { return size; } - - size_t getOffset() const - { return offset; } - -protected: - size_t offset; ///< Offset (or address) inside address space - size_t size; ///< Size in bytes of this block - MemoryManager::AddressSpaceId addrSpaceId; ///< Identifier in memory graph -}; - - -/** - * @brief Wrapper for a MemoryBlock to access the underlying memory directly - * - * The underlying memory block has to be accessible for the current process, - * that means it has to be mapped accordingly and registered to the global - * memory graph. - * Furthermore, this wrapper can be owning the memory block when initialized - * with a moved unique pointer. Otherwise, it just stores a reference to the - * memory block and it's the users responsibility to take care that the memory - * block is valid. - */ -template -class MemoryAccessor { -public: - using Type = T; - - // take ownership of the MemoryBlock - MemoryAccessor(std::unique_ptr mem) : - translation(MemoryManager::get().getTranslationFromProcess(mem->getAddrSpaceId())), - memoryBlock(std::move(mem)) {} - - // just act as an accessor, do not take ownership of MemoryBlock - MemoryAccessor(const MemoryBlock& mem) : - translation(MemoryManager::get().getTranslationFromProcess(mem.getAddrSpaceId())) {} - - - T& operator*() const { - return *reinterpret_cast(translation.getLocalAddr(0)); - } - - T& operator[](size_t idx) const { - const size_t offset = sizeof(T) * idx; - return *reinterpret_cast(translation.getLocalAddr(offset)); - } - - T* operator&() const { - return reinterpret_cast(translation.getLocalAddr(0)); - } - - T* operator->() const { - return reinterpret_cast(translation.getLocalAddr(0)); - } - - const MemoryBlock& - getMemoryBlock() const - { if(not memoryBlock) throw std::bad_alloc(); else return *memoryBlock; } - -private: - /// cached memory translation for fast access - MemoryTranslation translation; - - /// take the unique pointer in case user wants this class to have ownership - std::unique_ptr memoryBlock; -}; - - -/** - * @brief Base memory allocator - * - * Note the usage of CRTP idiom here to access methods of derived allocators. - * The concept is explained here at [1]. - * - * [1] https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern - */ -template -class BaseAllocator { -public: - /// memoryAddrSpaceId: memory that is managed by this allocator - BaseAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId) : - memoryAddrSpaceId(memoryAddrSpaceId) - { - // CRTP - derivedAlloc = static_cast(this); - logger = loggerGetOrCreate(derivedAlloc->getName()); - - // default deallocation callback - free = [&](MemoryBlock* mem) { - logger->warn("no free callback defined for addr space {}, not freeing", - mem->getAddrSpaceId()); - - removeMemoryBlock(*mem); - }; - } - - virtual std::unique_ptr - allocateBlock(size_t size) = 0; - - template - MemoryAccessor - allocate(size_t num) - { - const size_t size = num * sizeof(T); - auto mem = allocateBlock(size); - - // Check if the allocated memory is really accessible by writing to the - // allocated memory and reading back. Exponentially increase offset to - // speed up testing. - MemoryAccessor byteAccessor(*mem); - size_t idx = 0; - for(int i = 0; idx < mem->getSize(); i++, idx = (1 << i)) { - auto val = static_cast(i); - byteAccessor[idx] = val; - if(byteAccessor[idx] != val) { - logger->error("Cannot access allocated memory"); - throw std::bad_alloc(); - } - } - - return MemoryAccessor(std::move(mem)); - } - -protected: - void insertMemoryBlock(const MemoryBlock& mem) - { - auto& mm = MemoryManager::get(); - mm.createMapping(mem.getOffset(), 0, mem.getSize(), - derivedAlloc->getName(), - memoryAddrSpaceId, - mem.getAddrSpaceId()); - } - - void removeMemoryBlock(const MemoryBlock& mem) - { - // this will also remove any mapping to and from the memory block - auto& mm = MemoryManager::get(); - mm.removeAddressSpace(mem.getAddrSpaceId()); - } - - MemoryManager::AddressSpaceId getAddrSpaceId() const - { return memoryAddrSpaceId; } - -protected: - MemoryBlock::deallocator_fn free; - SpdLogger logger; - -private: - MemoryManager::AddressSpaceId memoryAddrSpaceId; - DerivedAllocator* derivedAlloc; -}; - - -/** - * @brief Linear memory allocator - * - * This is the simplest kind of allocator. The idea is to keep a pointer at the - * first memory address of your memory chunk and move it every time an - * allocation is done. Due to its simplicity, this allocator doesn't allow - * specific positions of memory to be freed. Usually, all memory is freed - * together. - */ -class LinearAllocator : public BaseAllocator { -public: - LinearAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId, - size_t memorySize, - size_t internalOffset = 0); - - size_t getAvailableMemory() const - { return memorySize - nextFreeAddress; } - - size_t getSize() const - { return memorySize; } - - std::string getName() const; - - std::unique_ptr - allocateBlock(size_t size); - -private: - static constexpr size_t alignBytes = sizeof(uintptr_t); - static constexpr size_t alignMask = alignBytes - 1; - - size_t getAlignmentPadding(uintptr_t addr) const - { return (alignBytes - (addr & alignMask)) & alignMask; } - -private: - size_t nextFreeAddress; ///< next chunk will be allocated here - size_t memorySize; ///< total size of managed memory - size_t internalOffset; ///< offset in address space (usually 0) - size_t allocationCount; ///< Number of individual allocations present -}; - - -/** - * @brief Wrapper around mmap() to create villas memory blocks - * - * This class simply wraps around mmap() and munmap() to allocate memory in the - * host memory via the OS. - */ -class HostRam { -public: - class HostRamAllocator : public BaseAllocator { - public: - HostRamAllocator(); - - std::string getName() const - { return "HostRamAlloc"; } - - std::unique_ptr - allocateBlock(size_t size); - }; - - static HostRamAllocator& - getAllocator() - { return allocator; } - -private: - static HostRamAllocator allocator; -}; - - -class HostDmaRam { -private: - - static std::string - getUdmaBufName(int num); - - static std::string - getUdmaBufBasePath(int num); - - static size_t - getUdmaBufBufSize(int num); - - static uintptr_t - getUdmaBufPhysAddr(int num); - -public: - class HostDmaRamAllocator : public LinearAllocator { - public: - HostDmaRamAllocator(int num); - - virtual ~HostDmaRamAllocator(); - - std::string getName() const - { return getUdmaBufName(num); } - - private: - int num; - }; - - static HostDmaRamAllocator& - getAllocator(int num = 0); - -private: - static std::map> allocators; -}; - -} // namespace villas diff --git a/fpga/include/villas/memory_manager.hpp b/fpga/include/villas/memory_manager.hpp deleted file mode 100644 index bd023b5ab..000000000 --- a/fpga/include/villas/memory_manager.hpp +++ /dev/null @@ -1,273 +0,0 @@ -/** Memory manager. - * - * @file - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include - -#include -#include - -namespace villas { - -/** - * @brief Translation between a local (master) to a foreign (slave) address space - * - * Memory translations can be chained together using the `+=` operator which is - * used internally by the MemoryManager to compute a translation through - * multiple hops (memory mappings). - */ -class MemoryTranslation { -public: - - /** - * @brief MemoryTranslation - * @param src Base address of local address space - * @param dst Base address of foreign address space - * @param size Size of "memory window" - */ - MemoryTranslation(uintptr_t src, uintptr_t dst, size_t size) : - src(src), dst(dst), size(size) {} - - uintptr_t - getLocalAddr(uintptr_t addrInForeignAddrSpace) const; - - uintptr_t - getForeignAddr(uintptr_t addrInLocalAddrSpace) const; - - size_t - getSize() const - { return size; } - - friend std::ostream& - operator<< (std::ostream& stream, const MemoryTranslation& translation) - { - return stream << std::hex - << "(src=0x" << translation.src - << ", dst=0x" << translation.dst - << ", size=0x" << translation.size - << ")"; - } - - /// Merge two MemoryTranslations together - MemoryTranslation& operator+=(const MemoryTranslation& other); - -private: - uintptr_t src; ///< Base address of local address space - uintptr_t dst; ///< Base address of foreign address space - size_t size; ///< Size of "memory window" -}; - - -/** - * @brief Global memory manager to resolve addresses across address spaces - * - * Every entity in the system has to register its (master) address space and - * create mappings to other (slave) address spaces that it can access. A - * directed graph is then constructed which allows to traverse addresses spaces - * through multiple mappings and resolve addresses through this "tunnel" of - * memory mappings. - */ -class MemoryManager { -private: - // This is a singleton, so private constructor ... - MemoryManager() : - memoryGraph("MemoryGraph"), - logger(loggerGetOrCreate("MemoryManager")) - { - pathCheckFunc = [&](const MemoryGraph::Path& path) { - return this->pathCheck(path); - }; - } - - // ... and no copying or assigning - MemoryManager(const MemoryManager&) = delete; - MemoryManager& operator=(const MemoryManager&) = delete; - - /** - * @brief Custom edge in memory graph representing a memory mapping - * - * A memory mapping maps from one address space into another and can only be - * traversed in the forward direction which reflects the nature of real - * memory mappings. - * - * Implementation Notes: - * The member #src is the address in the "from" address space, where the - * destination address space is mapped. The member #dest is the address in - * the destination address space, where the mapping points to. Often, #dest - * will be zero for mappings to hardware, but consider the example when - * mapping FPGA to application memory: - * The application allocates a block 1kB at address 0x843001000 in its - * address space. The mapping would then have a #dest address of 0x843001000 - * and a #size of 1024. - */ - class Mapping : public graph::Edge { - public: - std::string name; ///< Human-readable name - uintptr_t src; ///< Base address in "from" address space - uintptr_t dest; ///< Base address in "to" address space - size_t size; ///< Size of the mapping - - friend std::ostream& - operator<< (std::ostream& stream, const Mapping& mapping) - { - return stream << static_cast(mapping) << " = " - << mapping.name - << std::hex - << " (src=0x" << mapping.src - << ", dest=0x" << mapping.dest - << ", size=0x" << mapping.size - << ")"; - } - - }; - - - /** - * @brief Custom vertex in memory graph representing an address space - * - * Since most information in the memory graph is stored in the edges (memory - * mappings), this is just a small extension to the default vertex. It only - * associates an additional string #name for human-readability. - */ - class AddressSpace : public graph::Vertex { - public: - std::string name; ///< Human-readable name - - friend std::ostream& - operator<< (std::ostream& stream, const AddressSpace& addrSpace) - { - return stream << static_cast(addrSpace) << " = " - << addrSpace.name; - } - }; - - /// Memory graph with custom edges and vertices for address resolution - using MemoryGraph = graph::DirectedGraph; - -public: - using AddressSpaceId = MemoryGraph::VertexIdentifier; - using MappingId = MemoryGraph::EdgeIdentifier; - - struct InvalidTranslation : public std::exception {}; - - /// Get singleton instance - static MemoryManager& - get(); - - AddressSpaceId - getProcessAddressSpace() - { return getOrCreateAddressSpace("villas-fpga"); } - - AddressSpaceId - getPciAddressSpace() - { return getOrCreateAddressSpace("PCIe"); } - - AddressSpaceId - getProcessAddressSpaceMemoryBlock(const std::string& memoryBlock) - { return getOrCreateAddressSpace(getSlaveAddrSpaceName("villas-fpga", memoryBlock)); } - - - AddressSpaceId - getOrCreateAddressSpace(std::string name); - - void - removeAddressSpace(AddressSpaceId addrSpaceId) - { memoryGraph.removeVertex(addrSpaceId); } - - /// Create a default mapping - MappingId - createMapping(uintptr_t src, uintptr_t dest, size_t size, - const std::string& name, - AddressSpaceId fromAddrSpace, - AddressSpaceId toAddrSpace); - - /// Add a mapping - /// - /// Can be used to derive from Mapping in order to implement custom - /// constructor/destructor. - MappingId - addMapping(std::shared_ptr mapping, - AddressSpaceId fromAddrSpace, - AddressSpaceId toAddrSpace); - - - AddressSpaceId - findAddressSpace(const std::string& name); - - std::list - findPath(AddressSpaceId fromAddrSpaceId, AddressSpaceId toAddrSpaceId); - - MemoryTranslation - getTranslation(AddressSpaceId fromAddrSpaceId, AddressSpaceId toAddrSpaceId); - - MemoryTranslation - getTranslationFromProcess(AddressSpaceId foreignAddrSpaceId) - { return getTranslation(getProcessAddressSpace(), foreignAddrSpaceId); } - - static std::string - getSlaveAddrSpaceName(const std::string& ipInstance, const std::string& memoryBlock) - { return ipInstance + "/" + memoryBlock; } - - static std::string - getMasterAddrSpaceName(const std::string& ipInstance, const std::string& busInterface) - { return ipInstance + ":" + busInterface; } - - void - dump() - { memoryGraph.dump(); } - - void - dumpToFile(const std::string& fileName) - { memoryGraph.dump(fileName); } - -private: - /// Convert a Mapping to MemoryTranslation for calculations - static MemoryTranslation - getTranslationFromMapping(const Mapping& mapping) - { return MemoryTranslation(mapping.src, mapping.dest, mapping.size); } - - bool - pathCheck(const MemoryGraph::Path& path); - -private: - /// Directed graph that stores address spaces and memory mappings - MemoryGraph memoryGraph; - - /// Cache mapping of names to address space ids for fast lookup - std::map addrSpaceLookup; - - /// Logger for universal access in this class - SpdLogger logger; - - MemoryGraph::check_path_fn pathCheckFunc; - - /// Static pointer to global instance, because this is a singleton - static MemoryManager* instance; -}; - -} // namespace villas diff --git a/fpga/include/villas/plugin.hpp b/fpga/include/villas/plugin.hpp deleted file mode 100644 index 52d149d27..000000000 --- a/fpga/include/villas/plugin.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/** Loadable / plugin support. - * - * @file - * @author Steffen Vogel - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#pragma once - -#include -#include -#include - -#include -#include - -namespace villas { - -class Plugin { -public: - - enum class Type { - Unknown, - FpgaIp, - FpgaCard, - Gpu - }; - - Plugin(Type type, const std::string& name); - virtual ~Plugin(); - - // copying a plugin doesn't make sense, so explicitly deny it - Plugin(Plugin const&) = delete; - void operator=(Plugin const&) = delete; - - int load(); - int unload(); - - virtual int parse(json_t *cfg); - virtual void dump(); - - static void - dumpList(); - - /// Find plugin by type and (optional if empty) by name. If more match, it - /// is not defined which one will be returned. - static Plugin * - lookup(Type type, std::string name); - - /// Get all plugins of a given type. - static std::list - lookup(Type type); - - // TODO: check if this makes sense! (no intermediate plugins) - bool - operator==(const Plugin& other) const; - - Type pluginType; - std::string name; - std::string description; - std::string path; - void *handle; - enum state state; - -protected: - static SpdLogger - getStaticLogger() - { return loggerGetOrCreate("plugin"); } - -private: - /* Just using a standard std::list<> to hold plugins is problematic, because - we want to push Plugins to the list from within each Plugin's constructor - that is executed during static initialization. Since the order of static - initialization is undefined in C++, it may happen that a Plugin - constructor is executed before the list could be initialized. Therefore, - we use the Nifty Counter Idiom [1] to initialize the list ourself before - the first usage. - - In short: - - allocate a buffer for the list - - initialize list before first usage - - (complicatedly) declaring a buffer is neccessary in order to avoid - that the constructor of the static list is executed again - - [1] https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter - */ - - using PluginList = std::list; - using PluginListBuffer = typename std::aligned_storage::type; - - static PluginListBuffer pluginListBuffer; ///< buffer to hold a PluginList - static PluginList& pluginList; ///< reference to pluginListBuffer - static int pluginListNiftyCounter; ///< track if pluginList has been initialized -}; - -} // namespace villas diff --git a/fpga/include/villas/utils.hpp b/fpga/include/villas/utils.hpp deleted file mode 100644 index 11e044d98..000000000 --- a/fpga/include/villas/utils.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/** Utilities. - * - * @file - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#pragma once - -#include -#include - -namespace villas { -namespace utils { - -std::vector -tokenize(std::string s, std::string delimiter); - - -template -void -assertExcept(bool condition, const T& exception) -{ - if(not condition) - throw exception; -} - -} // namespace utils -} // namespace villas - diff --git a/fpga/lib/CMakeLists.txt b/fpga/lib/CMakeLists.txt index 09e08c272..c461f536a 100644 --- a/fpga/lib/CMakeLists.txt +++ b/fpga/lib/CMakeLists.txt @@ -20,8 +20,6 @@ # along with this program. If not, see . ############################################################################## -add_subdirectory(common) - set(SOURCES vlnv.cpp card.cpp @@ -87,6 +85,7 @@ target_link_libraries(villas-fpga PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} m + villas-common ) include(GNUInstallDirs) diff --git a/fpga/lib/common/CMakeLists.txt b/fpga/lib/common/CMakeLists.txt deleted file mode 100644 index e1981c6e8..000000000 --- a/fpga/lib/common/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -## CMakeLists.txt -# -# @author Daniel Krebs -# @copyright 2018, RWTH Institute for Automation of Complex Power Systems (ACS) -# @license GNU General Public License (version 3) -# -# VILLASfpga -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -############################################################################## - -cmake_minimum_required(VERSION 3.7) - -project(villas-common) - -add_library(villas-common SHARED - plugin.cpp - utils.cpp - memory.cpp - memory_manager.cpp) - -target_include_directories(villas-common - PUBLIC - ${CMAKE_CURRENT_LIST_DIR}/../../include/villas - ${CMAKE_CURRENT_LIST_DIR}/../../include - ${CMAKE_CURRENT_LIST_DIR}/../../thirdparty/spdlog/include) diff --git a/fpga/lib/common/memory.cpp b/fpga/lib/common/memory.cpp deleted file mode 100644 index c7305956c..000000000 --- a/fpga/lib/common/memory.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/** Memory managment. - * - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#include -#include - -#include -#include - -#include "memory.hpp" - -namespace villas { - -std::unique_ptr -HostRam::HostRamAllocator::allocateBlock(size_t size) -{ - /* Align to next bigger page size chunk */ - if (size & size_t(0xFFF)) { - size += size_t(0x1000); - size &= size_t(~0xFFF); - } - - const int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT; - const int mmap_protection = PROT_READ | PROT_WRITE; - - const void* addr = mmap(nullptr, size, mmap_protection, mmap_flags, 0, 0); - if(addr == nullptr) { - throw std::bad_alloc(); - } - - auto& mm = MemoryManager::get(); - - // assemble name for this block - std::stringstream name; - name << std::showbase << std::hex << reinterpret_cast(addr); - - auto blockAddrSpaceId = mm.getProcessAddressSpaceMemoryBlock(name.str()); - - const auto localAddr = reinterpret_cast(addr); - std::unique_ptr - mem(new MemoryBlock(localAddr, size, blockAddrSpaceId), this->free); - - insertMemoryBlock(*mem); - - return mem; -} - - -LinearAllocator::LinearAllocator(MemoryManager::AddressSpaceId memoryAddrSpaceId, - size_t memorySize, - size_t internalOffset) : - BaseAllocator(memoryAddrSpaceId), - nextFreeAddress(0), - memorySize(memorySize), - internalOffset(internalOffset), - allocationCount(0) -{ - // make sure to start at aligned offset, reduce size in case we need padding - if(const size_t paddingBytes = getAlignmentPadding(internalOffset)) { - assert(paddingBytes < memorySize); - - internalOffset += paddingBytes; - memorySize -= paddingBytes; - } - - // deallocation callback - free = [&](MemoryBlock* mem) { - logger->debug("Deallocating memory block at local addr {:#x} (addr space {})", - mem->getOffset(), mem->getAddrSpaceId()); - - removeMemoryBlock(*mem); - - allocationCount--; - if(allocationCount == 0) { - logger->debug("All allocations are deallocated now, freeing memory"); - - // all allocations have been deallocated, free all memory - nextFreeAddress = 0; - } - - logger->debug("Available memory: {:#x} bytes", getAvailableMemory()); - }; -} - - -std::string -LinearAllocator::getName() const -{ - std::stringstream name; - name << "LinearAlloc" << getAddrSpaceId(); - if(internalOffset != 0) { - name << "@0x" << std::hex << internalOffset; - } - - return name.str(); -} - - -std::unique_ptr -LinearAllocator::allocateBlock(size_t size) -{ - if(size > getAvailableMemory()) { - throw std::bad_alloc(); - } - - // assign address - const uintptr_t localAddr = nextFreeAddress + internalOffset; - - // reserve memory - nextFreeAddress += size; - - // make sure it is aligned - if(const size_t paddingBytes = getAlignmentPadding(nextFreeAddress)) { - nextFreeAddress += paddingBytes; - - // if next free address is outside this block due to padding, cap it - nextFreeAddress = std::min(nextFreeAddress, memorySize); - } - - - auto& mm = MemoryManager::get(); - - // assemble name for this block - std::stringstream blockName; - blockName << std::showbase << std::hex << localAddr; - - // create address space - auto addrSpaceName = mm.getSlaveAddrSpaceName(getName(), blockName.str()); - auto addrSpaceId = mm.getOrCreateAddressSpace(addrSpaceName); - - logger->debug("Allocated {:#x} bytes for {}, {:#x} bytes remaining", - size, addrSpaceId, getAvailableMemory()); - - std::unique_ptr - mem(new MemoryBlock(localAddr, size, addrSpaceId), this->free); - - // mount block into the memory graph - insertMemoryBlock(*mem); - - // increase the allocation count - allocationCount++; - - return mem; -} - - -HostRam::HostRamAllocator -HostRam::allocator; - -HostRam::HostRamAllocator::HostRamAllocator() : - BaseAllocator(MemoryManager::get().getProcessAddressSpace()) -{ - free = [&](MemoryBlock* mem) { - if(::munmap(reinterpret_cast(mem->getOffset()), mem->getSize()) != 0) { - logger->warn("munmap() failed for {:#x} of size {:#x}", - mem->getOffset(), mem->getSize()); - } - - removeMemoryBlock(*mem); - }; -} - - -std::map> -HostDmaRam::allocators; - -HostDmaRam::HostDmaRamAllocator::HostDmaRamAllocator(int num) : - LinearAllocator(MemoryManager::get().getOrCreateAddressSpace(getUdmaBufName(num)), getUdmaBufBufSize(num)), - num(num) -{ - auto& mm = MemoryManager::get(); - logger = loggerGetOrCreate(getName()); - - if(getSize() == 0) { - logger->error("Zero-sized DMA buffer not supported, is the kernel module loaded?"); - throw std::bad_alloc(); - } - - const uintptr_t base = getUdmaBufPhysAddr(num); - - mm.createMapping(base, 0, getSize(), getName() + "-PCI", - mm.getPciAddressSpace(), getAddrSpaceId()); - - const auto bufPath = std::string("/dev/") + getUdmaBufName(num); - const int bufFd = open(bufPath.c_str(), O_RDWR | O_SYNC); - if(bufFd != -1) { - void* buf = mmap(nullptr, getSize(), PROT_READ|PROT_WRITE, MAP_SHARED, bufFd, 0); - close(bufFd); - - if(buf != MAP_FAILED) { - mm.createMapping(reinterpret_cast(buf), 0, getSize(), - getName() + "-VA", - mm.getProcessAddressSpace(), getAddrSpaceId()); - } else { - logger->warn("Cannot map {}", bufPath); - } - } else { - logger->warn("Cannot open {}", bufPath); - } - - logger->info("Mapped {} of size {} bytes", bufPath, getSize()); -} - -HostDmaRam::HostDmaRamAllocator::~HostDmaRamAllocator() -{ - auto& mm = MemoryManager::get(); - - void* baseVirt; - try { - auto translation = mm.getTranslationFromProcess(getAddrSpaceId()); - baseVirt = reinterpret_cast(translation.getLocalAddr(0)); - } catch(const std::out_of_range&) { - // not mapped, nothing to do - return; - } - - logger->debug("Unmapping {}", getName()); - - // try to unmap it - if(::munmap(baseVirt, getSize()) != 0) { - logger->warn("munmap() failed for {:p} of size {:#x}", - baseVirt, getSize()); - } -} - -std::string -HostDmaRam::getUdmaBufName(int num) -{ - std::stringstream name; - name << "udmabuf" << num; - - return name.str(); -} - -std::string -HostDmaRam::getUdmaBufBasePath(int num) -{ - std::stringstream path; - path << "/sys/class/udmabuf/udmabuf" << num << "/"; - return path.str(); -} - -size_t -HostDmaRam::getUdmaBufBufSize(int num) -{ - std::fstream s(getUdmaBufBasePath(num) + "size", s.in); - if(s.is_open()) { - std::string line; - if(std::getline(s, line)) { - return std::strtoul(line.c_str(), nullptr, 10); - } - } - - return 0; -} - -uintptr_t -HostDmaRam::getUdmaBufPhysAddr(int num) -{ - std::fstream s(getUdmaBufBasePath(num) + "phys_addr", s.in); - if(s.is_open()) { - std::string line; - if(std::getline(s, line)) { - return std::strtoul(line.c_str(), nullptr, 16); - } - } - - return UINTPTR_MAX; -} - -HostDmaRam::HostDmaRamAllocator&HostDmaRam::getAllocator(int num) -{ - auto& allocator = allocators[num]; - if(not allocator) { - allocator = std::make_unique(num); - } - - return *allocator; -} - -} // namespace villas diff --git a/fpga/lib/common/memory_manager.cpp b/fpga/lib/common/memory_manager.cpp deleted file mode 100644 index 915ee8649..000000000 --- a/fpga/lib/common/memory_manager.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/** Memory managment. - * - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#include -#include -#include - -#include -#include - -using namespace villas::utils; - -namespace villas { - -MemoryManager* -MemoryManager::instance = nullptr; - -MemoryManager& -MemoryManager::get() -{ - if(instance == nullptr) { - instance = new MemoryManager; - } - - return *instance; -} - -MemoryManager::AddressSpaceId -MemoryManager::getOrCreateAddressSpace(std::string name) -{ - try { - // try fast lookup - return addrSpaceLookup.at(name); - } catch (const std::out_of_range&) { - // does not yet exist, create - std::shared_ptr addrSpace(new AddressSpace); - addrSpace->name = name; - - // cache it for the next access - addrSpaceLookup[name] = memoryGraph.addVertex(addrSpace); - - return addrSpaceLookup[name]; - } -} - -MemoryManager::MappingId -MemoryManager::createMapping(uintptr_t src, uintptr_t dest, size_t size, - const std::string& name, - MemoryManager::AddressSpaceId fromAddrSpace, - MemoryManager::AddressSpaceId toAddrSpace) -{ - std::shared_ptr mapping(new Mapping); - - mapping->name = name; - mapping->src = src; - mapping->dest = dest; - mapping->size = size; - - return addMapping(mapping, fromAddrSpace, toAddrSpace); -} - -MemoryManager::MappingId -MemoryManager::addMapping(std::shared_ptr mapping, - MemoryManager::AddressSpaceId fromAddrSpace, - MemoryManager::AddressSpaceId toAddrSpace) -{ - return memoryGraph.addEdge(mapping, fromAddrSpace, toAddrSpace); -} - -MemoryManager::AddressSpaceId -MemoryManager::findAddressSpace(const std::string& name) -{ - return memoryGraph.findVertex( - [&](const std::shared_ptr& v) { - return v->name == name; - }); -} - -std::list -MemoryManager::findPath(MemoryManager::AddressSpaceId fromAddrSpaceId, - MemoryManager::AddressSpaceId toAddrSpaceId) -{ - std::list path; - - auto fromAddrSpace = memoryGraph.getVertex(fromAddrSpaceId); - auto toAddrSpace = memoryGraph.getVertex(toAddrSpaceId); - - // find a path through the memory graph - MemoryGraph::Path pathGraph; - if(not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, pathGraph, pathCheckFunc)) { - - logger->debug("No translation found from ({}) to ({})", - *fromAddrSpace, *toAddrSpace); - - throw std::out_of_range("no translation found"); - } - - for(auto& mappingId : pathGraph) { - auto mapping = memoryGraph.getEdge(mappingId); - path.push_back(mapping->getVertexTo()); - } - - return path; -} - -MemoryTranslation -MemoryManager::getTranslation(MemoryManager::AddressSpaceId fromAddrSpaceId, - MemoryManager::AddressSpaceId toAddrSpaceId) -{ - // find a path through the memory graph - MemoryGraph::Path path; - if(not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, path, pathCheckFunc)) { - - auto fromAddrSpace = memoryGraph.getVertex(fromAddrSpaceId); - auto toAddrSpace = memoryGraph.getVertex(toAddrSpaceId); - logger->debug("No translation found from ({}) to ({})", - *fromAddrSpace, *toAddrSpace); - - throw std::out_of_range("no translation found"); - } - - // start with an identity mapping - MemoryTranslation translation(0, 0, SIZE_MAX); - - // iterate through path and merge all mappings into a single translation - for(auto& mappingId : path) { - auto mapping = memoryGraph.getEdge(mappingId); - translation += getTranslationFromMapping(*mapping); - } - - return translation; -} - -bool -MemoryManager::pathCheck(const MemoryGraph::Path& path) -{ - // start with an identity mapping - MemoryTranslation translation(0, 0, SIZE_MAX); - - // Try to add all mappings together to a common translation. If this fails - // there is a non-overlapping window - for(auto& mappingId : path) { - auto mapping = memoryGraph.getEdge(mappingId); - try { - translation += getTranslationFromMapping(*mapping); - } catch(const InvalidTranslation&) { - return false; - } - } - - return true; -} - -uintptr_t -MemoryTranslation::getLocalAddr(uintptr_t addrInForeignAddrSpace) const -{ - assert(addrInForeignAddrSpace >= dst); - assert(addrInForeignAddrSpace < (dst + size)); - return src + addrInForeignAddrSpace - dst; -} - -uintptr_t -MemoryTranslation::getForeignAddr(uintptr_t addrInLocalAddrSpace) const -{ - assert(addrInLocalAddrSpace >= src); - assert(addrInLocalAddrSpace < (src + size)); - return dst + addrInLocalAddrSpace - src; -} - -MemoryTranslation& -MemoryTranslation::operator+=(const MemoryTranslation& other) -{ - auto logger = loggerGetOrCreate("MemoryTranslation"); - // set level to debug to enable debug output - logger->set_level(spdlog::level::info); - - const uintptr_t this_dst_high = this->dst + this->size; - const uintptr_t other_src_high = other.src + other.size; - - logger->debug("this->src: {:#x}", this->src); - logger->debug("this->dst: {:#x}", this->dst); - logger->debug("this->size: {:#x}", this->size); - logger->debug("other.src: {:#x}", other.src); - logger->debug("other.dst: {:#x}", other.dst); - logger->debug("other.size: {:#x}", other.size); - logger->debug("this_dst_high: {:#x}", this_dst_high); - logger->debug("other_src_high: {:#x}", other_src_high); - - // make sure there is a common memory area - assertExcept(other.src < this_dst_high, MemoryManager::InvalidTranslation()); - assertExcept(this->dst < other_src_high, MemoryManager::InvalidTranslation()); - - const uintptr_t hi = std::max(this_dst_high, other_src_high); - const uintptr_t lo = std::min(this->dst, other.src); - - const uintptr_t diff_hi = (this_dst_high > other_src_high) - ? (this_dst_high - other_src_high) - : (other_src_high - this_dst_high); - - const bool otherSrcIsSmaller = this->dst > other.src; - const uintptr_t diff_lo = (otherSrcIsSmaller) - ? (this->dst - other.src) - : (other.src - this->dst); - - logger->debug("hi: {:#x}", hi); - logger->debug("lo: {:#x}", lo); - logger->debug("diff_hi: {:#x}", diff_hi); - logger->debug("diff_lo: {:#x}", diff_lo); - - // new size of aperture, can only stay or shrink - this->size = (hi - lo) - diff_hi - diff_lo; - - // new translation will come out other's destination (by default) - this->dst = other.dst; - - // the source stays the same and can only increase with merged translations - this->src = this->src; - - if(otherSrcIsSmaller) { - // other mapping starts at lower addresses, so we actually arrive at - // higher addresses - this->dst += diff_lo; - } else { - // other mapping starts at higher addresses than this, so we have to - // increase the start - // NOTE: for addresses equality, this just adds 0 - this->src += diff_lo; - } - - logger->debug("result src: {:#x}", this->src); - logger->debug("result dst: {:#x}", this->dst); - logger->debug("result size: {:#x}", this->size); - - return *this; -} - -} // namespace villas diff --git a/fpga/lib/common/plugin.cpp b/fpga/lib/common/plugin.cpp deleted file mode 100644 index 508747de2..000000000 --- a/fpga/lib/common/plugin.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/** Loadable / plugin support. - * - * @author Steffen Vogel - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#include -#include -#include -#include -#include - -#include - -namespace villas { - -// list of all registered plugins -Plugin::PluginList& -Plugin::pluginList = reinterpret_cast(Plugin::pluginListBuffer); - -Plugin::PluginListBuffer -Plugin::pluginListBuffer; - -// relies on zero initialization -int Plugin::pluginListNiftyCounter; - - -Plugin::Plugin(Type type, const std::string& name) : - pluginType(type), - name(name), - description(""), - path(""), - state(STATE_INITIALIZED) -{ - // see comment in plugin.hpp on why we need to do this (Nifty Counter Idiom) - if(pluginListNiftyCounter++ == 0) - new (&pluginList) PluginList; - - // push to global plugin list - pluginList.push_back(this); -} - -Plugin::~Plugin() -{ - // clean from global plugin list - pluginList.remove(this); -} - - -int -Plugin::parse(json_t *cfg) -{ - const char *path; - - path = json_string_value(cfg); - if (!path) - return -1; - - this->path = std::string(path); - this->state = STATE_PARSED; - - return 0; -} - -int -Plugin::load() -{ - assert(this->state == STATE_PARSED); - assert(not this->path.empty()); - - this->handle = dlopen(this->path.c_str(), RTLD_NOW); - - if (this->handle == nullptr) - return -1; - - this->state = STATE_LOADED; - - return 0; -} - -int -Plugin::unload() -{ - int ret; - - assert(this->state == STATE_LOADED); - - ret = dlclose(this->handle); - if (ret != 0) - return -1; - - this->state = STATE_UNLOADED; - - return 0; -} - -void -Plugin::dump() -{ - auto logger = getStaticLogger(); - logger->info("Name: '{}' Description: '{}'", name, description); -} - -void -Plugin::dumpList() -{ - auto logger = getStaticLogger(); - - logger->info("Registered plugins:"); - for(auto& p : pluginList) { - logger->info(" - {}", p->name); - } -} - -Plugin* -Plugin::lookup(Plugin::Type type, std::string name) -{ - for(auto& p : pluginList) { - if(p->pluginType == type and (name.empty() or p->name == name)) - return p; - } - - return nullptr; -} - -std::list -Plugin::lookup(Plugin::Type type) -{ - std::list list; - for(auto& p : pluginList) { - if(p->pluginType == type) - list.push_back(p); - } - - return list; -} - -bool -Plugin::operator==(const Plugin &other) const -{ - return (this->pluginType == other.pluginType) and (this->name == other.name); -} - -} // namespace villas diff --git a/fpga/lib/common/utils.cpp b/fpga/lib/common/utils.cpp deleted file mode 100644 index 0795c1017..000000000 --- a/fpga/lib/common/utils.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/** Utilities. - * - * @author Daniel Krebs - * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#include -#include - -#include - -namespace villas { -namespace utils { - -std::vector -tokenize(std::string s, std::string delimiter) -{ - std::vector tokens; - - size_t lastPos = 0; - size_t curentPos; - - while((curentPos = s.find(delimiter, lastPos)) != std::string::npos) { - const size_t tokenLength = curentPos - lastPos; - tokens.push_back(s.substr(lastPos, tokenLength)); - - // advance in string - lastPos = curentPos + delimiter.length(); - } - - // check if there's a last token behind the last delimiter - if(lastPos != s.length()) { - const size_t lastTokenLength = s.length() - lastPos; - tokens.push_back(s.substr(lastPos, lastTokenLength)); - } - - return tokens; -} - -} // namespace utils -} // namespace villas diff --git a/fpga/tests/CMakeLists.txt b/fpga/tests/CMakeLists.txt index 2447335a4..5db87d33f 100644 --- a/fpga/tests/CMakeLists.txt +++ b/fpga/tests/CMakeLists.txt @@ -28,7 +28,6 @@ set(SOURCES fifo.cpp rtds.cpp timer.cpp - graph.cpp ) if(CMAKE_CUDA_COMPILER) diff --git a/fpga/tests/graph.cpp b/fpga/tests/graph.cpp deleted file mode 100644 index aedc33c13..000000000 --- a/fpga/tests/graph.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/** Graph unit test. - * - * @author Steffen Vogel - * @copyright 2017-2018, Steffen Vogel - * @license GNU General Public License (version 3) - * - * VILLASfpga - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -#include - -#include -#include -#include -#include - -static void init_graph() -{ - spdlog::set_pattern("[%T] [%l] [%n] %v"); - spdlog::set_level(spdlog::level::debug); -} - -TestSuite(graph, - .description = "Graph library", - .init = init_graph -); - -Test(graph, basic, .description = "DirectedGraph") -{ - auto logger = loggerGetOrCreate("test:graph:basic"); - villas::graph::DirectedGraph<> g("test:graph:basic"); - - logger->info("Testing basic graph construction and modification"); - - std::shared_ptr v1(new villas::graph::Vertex); - std::shared_ptr v2(new villas::graph::Vertex); - std::shared_ptr v3(new villas::graph::Vertex); - - auto v1id = g.addVertex(v1); - auto v2id = g.addVertex(v2); - auto v3id = g.addVertex(v3); - cr_assert(g.getVertexCount() == 3); - - g.addDefaultEdge(v1id, v2id); - g.addDefaultEdge(v3id, v2id); - g.addDefaultEdge(v1id, v3id); - g.addDefaultEdge(v2id, v1id); - cr_assert(g.getEdgeCount() == 4); - cr_assert(g.vertexGetEdges(v1id).size() == 2); - cr_assert(g.vertexGetEdges(v2id).size() == 1); - cr_assert(g.vertexGetEdges(v3id).size() == 1); - - g.removeVertex(v1id); - g.dump(); - cr_assert(g.getVertexCount() == 2); - cr_assert(g.vertexGetEdges(v2id).size() == 0); - - logger->info(TXT_GREEN("Passed")); -} - -Test(graph, path, .description = "Find path") -{ - auto logger = loggerGetOrCreate("test:graph:path"); - logger->info("Testing path finding algorithm"); - - using Graph = villas::graph::DirectedGraph<>; - Graph g("test:graph:path"); - - std::shared_ptr v1(new villas::graph::Vertex); - std::shared_ptr v2(new villas::graph::Vertex); - std::shared_ptr v3(new villas::graph::Vertex); - std::shared_ptr v4(new villas::graph::Vertex); - std::shared_ptr v5(new villas::graph::Vertex); - std::shared_ptr v6(new villas::graph::Vertex); - - auto v1id = g.addVertex(v1); - auto v2id = g.addVertex(v2); - auto v3id = g.addVertex(v3); - - auto v4id = g.addVertex(v4); - auto v5id = g.addVertex(v5); - auto v6id = g.addVertex(v6); - - g.addDefaultEdge(v1id, v2id); - g.addDefaultEdge(v2id, v3id); - - // create circular subgraph - g.addDefaultEdge(v4id, v5id); - g.addDefaultEdge(v5id, v4id); - g.addDefaultEdge(v5id, v6id); - - g.dump(); - - logger->info("Find simple path via two edges"); - std::list path1; - cr_assert(g.getPath(v1id, v3id, path1)); - - logger->info(" Path from {} to {} via:", v1id, v3id); - for(auto& edge : path1) { - logger->info(" -> edge {}", edge); - } - - logger->info("Find path between two unconnected sub-graphs"); - std::list path2; - cr_assert(not g.getPath(v1id, v4id, path2)); - logger->info(" no path found -> ok"); - - - logger->info("Find non-existing path in circular sub-graph"); - std::list path3; - cr_assert(not g.getPath(v4id, v2id, path3)); - logger->info(" no path found -> ok"); - - - logger->info("Find path in circular graph"); - std::list path4; - cr_assert(g.getPath(v4id, v6id, path4)); - - logger->info(" Path from {} to {} via:", v4id, v6id); - for(auto& edge : path4) { - logger->info(" -> edge {}", edge); - } - - logger->info(TXT_GREEN("Passed")); -} - -Test(graph, memory_manager, .description = "Global Memory Manager") -{ - auto logger = loggerGetOrCreate("test:graph:mm"); - auto& mm = villas::MemoryManager::get(); - - logger->info("Create address spaces"); - auto dmaRegs = mm.getOrCreateAddressSpace("DMA Registers"); - auto pcieBridge = mm.getOrCreateAddressSpace("PCIe Bridge"); - - logger->info("Create a mapping"); - mm.createMapping(0x1000, 0, 0x1000, "Testmapping", dmaRegs, pcieBridge); - - logger->info("Find address space by name"); - auto vertex = mm.findAddressSpace("PCIe Bridge"); - logger->info(" found: {}", vertex); - - mm.dump(); - - logger->info(TXT_GREEN("Passed")); -} diff --git a/fpga/thirdparty/spdlog/.gitignore b/fpga/thirdparty/spdlog/.gitignore deleted file mode 100644 index 2f3cb33de..000000000 --- a/fpga/thirdparty/spdlog/.gitignore +++ /dev/null @@ -1,67 +0,0 @@ -# Auto generated files -*.slo -*.lo -*.o -*.obj -*.suo -*.tlog -*.ilk -*.log -*.pdb -*.idb -*.iobj -*.ipdb -*.opensdf -*.sdf - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Codelite -.codelite - -# .orig files -*.orig - -# example files -example/* -!example/example.cpp -!example/bench.cpp -!example/utils.h -!example/Makefile* -!example/example.sln -!example/example.vcxproj -!example/CMakeLists.txt -!example/multisink.cpp -!example/jni - -# generated files -generated - -# Cmake -CMakeCache.txt -CMakeFiles -CMakeScripts -Makefile -cmake_install.cmake -install_manifest.txt -/tests/tests.VC.VC.opendb -/tests/tests.VC.db -/tests/tests -/tests/logs/* - -# idea -.idea/ \ No newline at end of file diff --git a/fpga/thirdparty/spdlog/.travis.yml b/fpga/thirdparty/spdlog/.travis.yml deleted file mode 100644 index 852738442..000000000 --- a/fpga/thirdparty/spdlog/.travis.yml +++ /dev/null @@ -1,91 +0,0 @@ -# Adapted from various sources, including: -# - Louis Dionne's Hana: https://github.com/ldionne/hana -# - Paul Fultz II's FIT: https://github.com/pfultz2/Fit -# - Eric Niebler's range-v3: https://github.com/ericniebler/range-v3 -language: cpp - -# Test matrix: -# - Build matrix per compiler: C++11/C++14 + Debug/Release -# - Optionally: AddressSanitizer (ASAN) -# - Valgrind: all release builds are also tested with valgrind -# - clang 3.4, 3.5, 3.6, trunk -# - Note: 3.4 and trunk are tested with/without ASAN, -# the rest is only tested with ASAN=On. -# - gcc 4.9, 5.0 -# -matrix: - include: - -# Test gcc-4.8: C++11, Build=Debug/Release, ASAN=Off - - env: GCC_VERSION=4.8 BUILD_TYPE=Debug CPP=11 ASAN=Off LIBCXX=Off - os: linux - addons: &gcc48 - apt: - packages: - - g++-4.8 - - valgrind - sources: - - ubuntu-toolchain-r-test - - - env: GCC_VERSION=4.8 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=Off - os: linux - addons: *gcc48 - - # Test gcc-4.9: C++11, Build=Debug/Release, ASAN=Off - - env: GCC_VERSION=4.9 BUILD_TYPE=Debug CPP=11 ASAN=Off LIBCXX=Off - os: linux - addons: &gcc49 - apt: - packages: - - g++-4.9 - - valgrind - sources: - - ubuntu-toolchain-r-test - - - env: GCC_VERSION=4.9 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=Off - os: linux - addons: *gcc49 - -# Install dependencies -before_install: - - export CHECKOUT_PATH=`pwd`; - - if [ -n "$GCC_VERSION" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi - - if [ -n "$CLANG_VERSION" ]; then export CXX="clang++-${CLANG_VERSION}" CC="clang-${CLANG_VERSION}"; fi - - if [ "$CLANG_VERSION" == "3.4" ]; then export CXX="/usr/local/clang-3.4/bin/clang++" CC="/usr/local/clang-3.4/bin/clang"; fi - - which $CXX - - which $CC - - which valgrind - - if [ -n "$CLANG_VERSION" ]; then sudo CXX=$CXX CC=$CC ./tests/install_libcxx.sh; fi - -install: - - cd $CHECKOUT_PATH - - # Workaround for valgrind bug: https://bugs.kde.org/show_bug.cgi?id=326469. - # It is fixed in valgrind 3.10 so this won't be necessary if someone - # replaces the current valgrind (3.7) with valgrind-3.10 - - sed -i 's/march=native/msse4.2/' example/Makefile - - - if [ ! -d build ]; then mkdir build; fi - - export CXX_FLAGS="-I${CHECKOUT_PATH}/include" - - export CXX_LINKER_FLAGS="" - - if [ -z "$BUILD_TYPE" ]; then export BUILD_TYPE=Release; fi - - if [ "$ASAN" == "On"]; then export CXX_FLAGS="${CXX_FLAGS} -fsanitize=address,undefined,integer -fno-omit-frame-pointer -fno-sanitize=unsigned-integer-overflow"; fi - - if [ -n "$CLANG_VERSION" ]; then CXX_FLAGS="${CXX_FLAGS} -D__extern_always_inline=inline"; fi - - if [ "$LIBCXX" == "On" ]; then CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -I/usr/include/c++/v1/"; fi - - if [ "$LIBCXX" == "On" ]; then CXX_LINKER_FLAGS="${CXX_FLAGS} -L/usr/lib/ -lc++"; fi - - CXX_FLAGS="${CXX_FLAGS} -std=c++${CPP}" - - # Build examples - - cd example - - if [ "$BUILD_TYPE" == "Release" ]; then make rebuild CXXFLAGS="${CXX_FLAGS} ${CXX_LINKER_FLAGS}" VERBOSE=1; export BIN=example; fi - - if [ "$BUILD_TYPE" == "Debug" ]; then make rebuild debug CXXFLAGS="${CXX_FLAGS} ${CXX_LINKER_FLAGS}" VERBOSE=1; export BIN=example-debug; fi - - -script: - - ./"${BIN}" - - valgrind --trace-children=yes --leak-check=full ./"${BIN}" - - cd $CHECKOUT_PATH/tests; make rebuild; ./tests - - cd $CHECKOUT_PATH/tests; STYLE=printf make rebuild; ./tests - -notifications: - email: false diff --git a/fpga/thirdparty/spdlog/CMakeLists.txt b/fpga/thirdparty/spdlog/CMakeLists.txt deleted file mode 100644 index 52d29531e..000000000 --- a/fpga/thirdparty/spdlog/CMakeLists.txt +++ /dev/null @@ -1,116 +0,0 @@ -# -# Copyright(c) 2015 Ruslan Baratov. -# Distributed under the MIT License (http://opensource.org/licenses/MIT) -# - -cmake_minimum_required(VERSION 3.1) -project(spdlog VERSION 0.16.2) -include(CTest) -include(CMakeDependentOption) -include(GNUInstallDirs) - -#--------------------------------------------------------------------------------------- -# compiler config -#--------------------------------------------------------------------------------------- -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}") -endif() - -#--------------------------------------------------------------------------------------- -# spdlog target -#--------------------------------------------------------------------------------------- -add_library(spdlog INTERFACE) - -option(SPDLOG_BUILD_EXAMPLES "Build examples" OFF) -cmake_dependent_option(SPDLOG_BUILD_TESTING - "Build spdlog tests" ON - "BUILD_TESTING" OFF -) - -target_include_directories( - spdlog - INTERFACE - "$" - "$" -) - -set(HEADER_BASE "${CMAKE_CURRENT_SOURCE_DIR}/include") - -if(SPDLOG_BUILD_EXAMPLES) - add_subdirectory(example) -endif() - -if(SPDLOG_BUILD_TESTING) - add_subdirectory(tests) -endif() - -#--------------------------------------------------------------------------------------- -# Install/export targets and files -#--------------------------------------------------------------------------------------- -# set files and directories -set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") -set(include_install_dir "${CMAKE_INSTALL_INCLUDEDIR}") -set(pkgconfig_install_dir "${CMAKE_INSTALL_LIBDIR}/pkgconfig") -set(version_config "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake") -set(project_config "${PROJECT_NAME}Config.cmake") -set(pkg_config "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc") -set(targets_export_name "${PROJECT_NAME}Targets") -set(namespace "${PROJECT_NAME}::") - -# generate package version file -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - "${version_config}" COMPATIBILITY SameMajorVersion -) - -# configure pkg config file -configure_file("cmake/spdlog.pc.in" "${pkg_config}" @ONLY) - -# install targets -install( - TARGETS spdlog - EXPORT "${targets_export_name}" - INCLUDES DESTINATION "${include_install_dir}" -) - -# install headers -install( - DIRECTORY "${HEADER_BASE}/${PROJECT_NAME}" - DESTINATION "${include_install_dir}" -) - -# install project version file -install( - FILES "${version_config}" - DESTINATION "${config_install_dir}" -) - -# install pkg config file -install( - FILES "${pkg_config}" - DESTINATION "${pkgconfig_install_dir}" -) - -# install project config file -install( - EXPORT "${targets_export_name}" - NAMESPACE "${namespace}" - DESTINATION "${config_install_dir}" - FILE ${project_config} -) - -# export build directory config file -export( - EXPORT ${targets_export_name} - NAMESPACE "${namespace}" - FILE ${project_config} -) - -# register project in CMake user registry -export(PACKAGE ${PROJECT_NAME}) - -file(GLOB_RECURSE spdlog_include_SRCS "${HEADER_BASE}/*.h") -add_custom_target(spdlog_headers_for_ide SOURCES ${spdlog_include_SRCS}) diff --git a/fpga/thirdparty/spdlog/INSTALL b/fpga/thirdparty/spdlog/INSTALL deleted file mode 100644 index 664509d2c..000000000 --- a/fpga/thirdparty/spdlog/INSTALL +++ /dev/null @@ -1,13 +0,0 @@ -spdlog is header only library. -Just copy the files to your build tree and use a C++11 compiler - -Tested on: -gcc 4.8.1 and above -clang 3.5 -Visual Studio 2013 - -gcc 4.8 flags: --std==c++11 -pthread -O3 -flto -Wl,--no-as-needed -gcc 4.9 flags: --std=c++11 -pthread -O3 -flto - - -see the makefile in the example folder diff --git a/fpga/thirdparty/spdlog/LICENSE b/fpga/thirdparty/spdlog/LICENSE deleted file mode 100644 index 4b43e0640..000000000 --- a/fpga/thirdparty/spdlog/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Gabi Melman. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/fpga/thirdparty/spdlog/README.md b/fpga/thirdparty/spdlog/README.md deleted file mode 100644 index 733471390..000000000 --- a/fpga/thirdparty/spdlog/README.md +++ /dev/null @@ -1,221 +0,0 @@ -# spdlog - -Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.org/gabime/spdlog.svg?branch=master)](https://travis-ci.org/gabime/spdlog)  [![Build status](https://ci.appveyor.com/api/projects/status/d2jnxclg20vd0o50?svg=true)](https://ci.appveyor.com/project/gabime/spdlog) - - -## Install -#### Just copy the headers: - -* Copy the source [folder](https://github.com/gabime/spdlog/tree/master/include/spdlog) to your build tree and use a C++11 compiler. - -#### Or use your favorite package manager: - -* Ubuntu: `apt-get install libspdlog-dev` -* Homebrew: `brew install spdlog` -* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean` -* Fedora: `yum install spdlog` -* Gentoo: `emerge dev-libs/spdlog` -* Arch Linux: `yaourt -S spdlog-git` -* vcpkg: `vcpkg install spdlog` - - -## Platforms - * Linux, FreeBSD, Solaris - * Windows (vc 2013+, cygwin) - * Mac OSX (clang 3.5+) - * Android - -## Features -* Very fast - performance is the primary goal (see [benchmarks](#benchmarks) below). -* Headers only, just copy and use. -* Feature rich [call style](#usage-example) using the excellent [fmt](https://github.com/fmtlib/fmt) library. -* Optional printf syntax support. -* Extremely fast asynchronous mode (optional) - using lockfree queues and other tricks to reach millions of calls/sec. -* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting. -* Conditional Logging -* Multi/Single threaded loggers. -* Various log targets: - * Rotating log files. - * Daily log files. - * Console logging (colors supported). - * syslog. - * Windows debugger (```OutputDebugString(..)```) - * Easily extendable with custom log targets (just implement a single function in the [sink](include/spdlog/sinks/sink.h) interface). -* Severity based filtering - threshold levels can be modified in runtime as well as in compile time. - - - -## Benchmarks - -Below are some [benchmarks](bench) comparing popular log libraries under Ubuntu 64 bit, Intel i7-4770 CPU @ 3.40GHz - -#### Synchronous mode -Time needed to log 1,000,000 lines in synchronous mode (in seconds, the best of 3 runs): - -|threads|boost log 1.54|glog |easylogging |spdlog| -|-------|:-------:|:-----:|----------:|------:| -|1| 4.169s |1.066s |0.975s |0.302s| -|10| 6.180s |3.032s |2.857s |0.968s| -|100| 5.981s |1.139s |4.512s |0.497s| - - -#### Asynchronous mode -Time needed to log 1,000,000 lines in asynchronous mode, i.e. the time it takes to put them in the async queue (in seconds, the best of 3 runs): - -|threads|g2log async logger |spdlog async mode| -|:-------|:-----:|-------------------------:| -|1| 1.850s |0.216s | -|10| 0.943s |0.173s| -|100| 0.959s |0.202s| - - - - -## Usage Example -```c++ - -#include "spdlog/spdlog.h" - -#include -#include - -void async_example(); -void syslog_example(); -void user_defined_example(); -void err_handler_example(); - -namespace spd = spdlog; -int main(int, char*[]) -{ - try - { - // Console logger with color - auto console = spd::stdout_color_mt("console"); - console->info("Welcome to spdlog!"); - console->error("Some error message with arg{}..", 1); - - // Formatting examples - console->warn("Easy padding in numbers like {:08d}", 12); - console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); - console->info("Support for floats {:03.2f}", 1.23456); - console->info("Positional args are {1} {0}..", "too", "supported"); - console->info("{:<30}", "left aligned"); - - // Use global registry to retrieve loggers - spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); - - // Create basic file logger (not rotated) - auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt"); - my_logger->info("Some log message"); - - // Create a file rotating logger with 5mb size max and 3 rotated files - auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile.txt", 1048576 * 5, 3); - for (int i = 0; i < 10; ++i) - rotating_logger->info("{} * {} equals {:>10}", i, i, i*i); - - // Create a daily logger - a new file is created every day on 2:30am - auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); - // trigger flush if the log severity is error or higher - daily_logger->flush_on(spd::level::err); - daily_logger->info(123.44); - - // Customize msg format for all messages - spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); - rotating_logger->info("This is another message with custom format"); - - - // Runtime log levels - spd::set_level(spd::level::info); //Set global log level to info - console->debug("This message should not be displayed!"); - console->set_level(spd::level::debug); // Set specific logger's log level - console->debug("This message should be displayed.."); - - // Compile time log levels - // define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON - SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); - SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23); - - // Asynchronous logging is very fast.. - // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous.. - async_example(); - - // syslog example. linux/osx only - syslog_example(); - - // android example. compile with NDK - android_example(); - - // Log user-defined types example - user_defined_example(); - - // Change default log error handler - err_handler_example(); - - // Apply a function on all registered loggers - spd::apply_all([&](std::shared_ptr l) - { - l->info("End of example."); - }); - - // Release and close all loggers - spd::drop_all(); - } - // Exceptions will only be thrown upon failed logger or sink construction (not during logging) - catch (const spd::spdlog_ex& ex) - { - std::cout << "Log init failed: " << ex.what() << std::endl; - return 1; - } -} - -void async_example() -{ - size_t q_size = 4096; //queue size must be power of 2 - spd::set_async_mode(q_size); - auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt"); - for (int i = 0; i < 100; ++i) - async_file->info("Async message #{}", i); -} - -//syslog example -void syslog_example() -{ -#ifdef SPDLOG_ENABLE_SYSLOG - std::string ident = "spdlog-example"; - auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID); - syslog_logger->warn("This is warning that will end up in syslog.."); -#endif -} - -// user defined types logging by implementing operator<< -struct my_type -{ - int i; - template - friend OStream& operator<<(OStream& os, const my_type &c) - { - return os << "[my_type i="< // must be included -void user_defined_example() -{ - spd::get("console")->info("user defined type: {}", my_type { 14 }); -} - -// -//custom error handler -// -void err_handler_example() -{ - spd::set_error_handler([](const std::string& msg) { - std::cerr << "my err handler: " << msg << std::endl; - }); - // (or logger->set_error_handler(..) to set for specific logger) -} - -``` - -## Documentation -Documentation can be found in the [wiki](https://github.com/gabime/spdlog/wiki/1.-QuickStart) pages. diff --git a/fpga/thirdparty/spdlog/appveyor.yml b/fpga/thirdparty/spdlog/appveyor.yml deleted file mode 100644 index 2a176c1be..000000000 --- a/fpga/thirdparty/spdlog/appveyor.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: 1.0.{build} -image: Visual Studio 2015 -environment: - matrix: - - GENERATOR: '"MinGW Makefiles"' - BUILD_TYPE: Debug - - GENERATOR: '"MinGW Makefiles"' - BUILD_TYPE: Release - - GENERATOR: '"Visual Studio 14 2015"' - BUILD_TYPE: Debug - - GENERATOR: '"Visual Studio 14 2015"' - BUILD_TYPE: Release - - GENERATOR: '"Visual Studio 14 2015 Win64"' - BUILD_TYPE: Debug - - GENERATOR: '"Visual Studio 14 2015 Win64"' - BUILD_TYPE: Release -build_script: -- cmd: >- - set - - mkdir build - - cd build - - set PATH=%PATH:C:\Program Files\Git\usr\bin;=% - - set PATH=C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH% - - cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% - - cmake --build . --config %BUILD_TYPE% -test: off diff --git a/fpga/thirdparty/spdlog/astyle.sh b/fpga/thirdparty/spdlog/astyle.sh deleted file mode 100755 index a7a90510b..000000000 --- a/fpga/thirdparty/spdlog/astyle.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -find . -name "*\.h" -o -name "*\.cpp"|xargs dos2unix -find . -name "*\.h" -o -name "*\.cpp"|xargs astyle -n -c -A1 - - diff --git a/fpga/thirdparty/spdlog/bench/Makefile b/fpga/thirdparty/spdlog/bench/Makefile deleted file mode 100644 index 418a5285f..000000000 --- a/fpga/thirdparty/spdlog/bench/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -CXX ?= g++ -CXXFLAGS = -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -I../include -CXX_RELEASE_FLAGS = -O3 -flto -DNDEBUG - - -binaries=spdlog-bench spdlog-bench-mt spdlog-async spdlog-null-async boost-bench boost-bench-mt glog-bench glog-bench-mt g2log-async easylogging-bench easylogging-bench-mt - -all: $(binaries) - -spdlog-bench: spdlog-bench.cpp - $(CXX) spdlog-bench.cpp -o spdlog-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - -spdlog-bench-mt: spdlog-bench-mt.cpp - $(CXX) spdlog-bench-mt.cpp -o spdlog-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - -spdlog-async: spdlog-async.cpp - $(CXX) spdlog-async.cpp -o spdlog-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - - -spdlog-null-async: spdlog-null-async.cpp - $(CXX) spdlog-null-async.cpp -o spdlog-null-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - - - -BOOST_FLAGS = -DBOOST_LOG_DYN_LINK -I/usr/include -lboost_log -lboost_log_setup -lboost_filesystem -lboost_system -lboost_thread -lboost_regex -lboost_date_time -lboost_chrono - -boost-bench: boost-bench.cpp - $(CXX) boost-bench.cpp -o boost-bench $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS) - -boost-bench-mt: boost-bench-mt.cpp - $(CXX) boost-bench-mt.cpp -o boost-bench-mt $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS) - - -GLOG_FLAGS = -lglog -glog-bench: glog-bench.cpp - $(CXX) glog-bench.cpp -o glog-bench $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS) - -glog-bench-mt: glog-bench-mt.cpp - $(CXX) glog-bench-mt.cpp -o glog-bench-mt $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS) - - -G2LOG_FLAGS = -I/home/gabi/devel/g2log/g2log/src -L/home/gabi/devel/g2log/g2log -llib_g2logger -g2log-async: g2log-async.cpp - $(CXX) g2log-async.cpp -o g2log-async $(CXXFLAGS) $(G2LOG_FLAGS) $(CXX_RELEASE_FLAGS) - - -EASYL_FLAGS = -I../../easylogging/src/ -easylogging-bench: easylogging-bench.cpp - $(CXX) easylogging-bench.cpp -o easylogging-bench $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS) -easylogging-bench-mt: easylogging-bench-mt.cpp - $(CXX) easylogging-bench-mt.cpp -o easylogging-bench-mt $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS) - -.PHONY: clean - -clean: - rm -f *.o logs/* $(binaries) - - -rebuild: clean all - - - diff --git a/fpga/thirdparty/spdlog/bench/Makefile.mingw b/fpga/thirdparty/spdlog/bench/Makefile.mingw deleted file mode 100644 index b4357be4a..000000000 --- a/fpga/thirdparty/spdlog/bench/Makefile.mingw +++ /dev/null @@ -1,57 +0,0 @@ -CXX ?= g++ -CXXFLAGS = -D_WIN32_WINNT=0x600 -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -Wl,--no-as-needed -I../include -CXX_RELEASE_FLAGS = -O3 -flto - - -binaries=spdlog-bench spdlog-bench-mt spdlog-async boost-bench boost-bench-mt glog-bench glog-bench-mt g2log-async easylogging-bench easylogging-bench-mt - -all: $(binaries) - -spdlog-bench: spdlog-bench.cpp - $(CXX) spdlog-bench.cpp -o spdlog-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - -spdlog-bench-mt: spdlog-bench-mt.cpp - $(CXX) spdlog-bench-mt.cpp -o spdlog-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - -spdlog-async: spdlog-async.cpp - $(CXX) spdlog-async.cpp -o spdlog-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - - -BOOST_FLAGS = -DBOOST_LOG_DYN_LINK -I/home/gabi/devel/boost_1_56_0/ -L/home/gabi/devel/boost_1_56_0/stage/lib -lboost_log -lboost_log_setup -lboost_filesystem -lboost_system -lboost_thread -lboost_regex -lboost_date_time -lboost_chrono - -boost-bench: boost-bench.cpp - $(CXX) boost-bench.cpp -o boost-bench $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS) - -boost-bench-mt: boost-bench-mt.cpp - $(CXX) boost-bench-mt.cpp -o boost-bench-mt $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS) - - -GLOG_FLAGS = -lglog -glog-bench: glog-bench.cpp - $(CXX) glog-bench.cpp -o glog-bench $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS) - -glog-bench-mt: glog-bench-mt.cpp - $(CXX) glog-bench-mt.cpp -o glog-bench-mt $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS) - - -G2LOG_FLAGS = -I/home/gabi/devel/g2log/g2log/src -L/home/gabi/devel/g2log/g2log -llib_g2logger -g2log-async: g2log-async.cpp - $(CXX) g2log-async.cpp -o g2log-async $(CXXFLAGS) $(G2LOG_FLAGS) $(CXX_RELEASE_FLAGS) - - -EASYL_FLAGS = -I../../easylogging/src/ -easylogging-bench: easylogging-bench.cpp - $(CXX) easylogging-bench.cpp -o easylogging-bench $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS) -easylogging-bench-mt: easylogging-bench-mt.cpp - $(CXX) easylogging-bench-mt.cpp -o easylogging-bench-mt $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS) - -.PHONY: clean - -clean: - rm -f *.o logs/* $(binaries) - - -rebuild: clean all - - - diff --git a/fpga/thirdparty/spdlog/bench/boost-bench-mt.cpp b/fpga/thirdparty/spdlog/bench/boost-bench-mt.cpp deleted file mode 100644 index d845fcecf..000000000 --- a/fpga/thirdparty/spdlog/bench/boost-bench-mt.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace logging = boost::log; -namespace src = boost::log::sources; -namespace sinks = boost::log::sinks; -namespace keywords = boost::log::keywords; - -void init() -{ - logging::add_file_log - ( - keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ - keywords::auto_flush = false, - keywords::format = "[%TimeStamp%]: %Message%" - ); - - logging::core::get()->set_filter - ( - logging::trivial::severity >= logging::trivial::info - ); -} - - - -using namespace std; - -int main(int argc, char* argv[]) -{ - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); - - int howmany = 1000000; - - - init(); - logging::add_common_attributes(); - - - using namespace logging::trivial; - - src::severity_logger_mt< severity_level > lg; - - std::atomic msg_counter {0}; - vector threads; - - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - BOOST_LOG_SEV(lg, info) << "boost message #" << counter << ": This is some text for your pleasure"; - } - })); - } - - - for(auto &t:threads) - { - t.join(); - }; - - - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/boost-bench.cpp b/fpga/thirdparty/spdlog/bench/boost-bench.cpp deleted file mode 100644 index 32c5b692a..000000000 --- a/fpga/thirdparty/spdlog/bench/boost-bench.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// -#include -#include -#include -#include -#include -#include -#include -#include - -namespace logging = boost::log; -namespace src = boost::log::sources; -namespace sinks = boost::log::sinks; -namespace keywords = boost::log::keywords; - -void init() -{ - logging::add_file_log - ( - keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ - keywords::auto_flush = false, - keywords::format = "[%TimeStamp%]: %Message%" - ); - - logging::core::get()->set_filter - ( - logging::trivial::severity >= logging::trivial::info - ); -} - - -int main(int argc, char* []) -{ - int howmany = 1000000; - init(); - logging::add_common_attributes(); - - using namespace logging::trivial; - src::severity_logger_mt< severity_level > lg; - for(int i = 0 ; i < howmany; ++i) - BOOST_LOG_SEV(lg, info) << "boost message #" << i << ": This is some text for your pleasure"; - - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/easyl.conf b/fpga/thirdparty/spdlog/bench/easyl.conf deleted file mode 100644 index 3bfb5440c..000000000 --- a/fpga/thirdparty/spdlog/bench/easyl.conf +++ /dev/null @@ -1,10 +0,0 @@ -* GLOBAL: - FORMAT = "[%datetime]: %msg" - FILENAME = ./logs/easylogging.log - ENABLED = true - TO_FILE = true - TO_STANDARD_OUTPUT = false - MILLISECONDS_WIDTH = 3 - PERFORMANCE_TRACKING = false - MAX_LOG_FILE_SIZE = 10485760 - Log_Flush_Threshold = 10485760 diff --git a/fpga/thirdparty/spdlog/bench/easylogging-bench-mt.cpp b/fpga/thirdparty/spdlog/bench/easylogging-bench-mt.cpp deleted file mode 100644 index 98d1ae35c..000000000 --- a/fpga/thirdparty/spdlog/bench/easylogging-bench-mt.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include -#include -#include - -#define _ELPP_THREAD_SAFE -#include "easylogging++.h" -_INITIALIZE_EASYLOGGINGPP - -using namespace std; - -int main(int argc, char* argv[]) -{ - - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); - - int howmany = 1000000; - - // Load configuration from file - el::Configurations conf("easyl.conf"); - el::Loggers::reconfigureLogger("default", conf); - - std::atomic msg_counter {0}; - vector threads; - - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - LOG(INFO) << "easylog message #" << counter << ": This is some text for your pleasure"; - } - })); - } - - - for(auto &t:threads) - { - t.join(); - }; - - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/easylogging-bench.cpp b/fpga/thirdparty/spdlog/bench/easylogging-bench.cpp deleted file mode 100644 index a952cbd53..000000000 --- a/fpga/thirdparty/spdlog/bench/easylogging-bench.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - - -#include "easylogging++.h" - -_INITIALIZE_EASYLOGGINGPP - -int main(int, char* []) -{ - int howmany = 1000000; - - // Load configuration from file - el::Configurations conf("easyl.conf"); - el::Loggers::reconfigureLogger("default", conf); - - for(int i = 0 ; i < howmany; ++i) - LOG(INFO) << "easylog message #" << i << ": This is some text for your pleasure"; - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/g2log-async.cpp b/fpga/thirdparty/spdlog/bench/g2log-async.cpp deleted file mode 100644 index 9f9eb71e9..000000000 --- a/fpga/thirdparty/spdlog/bench/g2log-async.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include -#include -#include -#include -#include - -#include "g2logworker.h" -#include "g2log.h" - -using namespace std; -template std::string format(const T& value); - -int main(int argc, char* argv[]) -{ - using namespace std::chrono; - using clock=steady_clock; - int thread_count = 10; - - if(argc > 1) - thread_count = atoi(argv[1]); - int howmany = 1000000; - - g2LogWorker g2log(argv[0], "logs"); - g2::initializeLogging(&g2log); - - - std::atomic msg_counter {0}; - vector threads; - auto start = clock::now(); - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - LOG(INFO) << "g2log message #" << counter << ": This is some text for your pleasure"; - } - })); - } - - - for(auto &t:threads) - { - t.join(); - }; - - duration delta = clock::now() - start; - float deltaf = delta.count(); - auto rate = howmany/deltaf; - - cout << "Total: " << howmany << std::endl; - cout << "Threads: " << thread_count << std::endl; - std::cout << "Delta = " << deltaf << " seconds" << std::endl; - std::cout << "Rate = " << rate << "/sec" << std::endl; -} diff --git a/fpga/thirdparty/spdlog/bench/glog-bench-mt.cpp b/fpga/thirdparty/spdlog/bench/glog-bench-mt.cpp deleted file mode 100644 index db193aeb6..000000000 --- a/fpga/thirdparty/spdlog/bench/glog-bench-mt.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include -#include -#include - -#include "glog/logging.h" - -using namespace std; - -int main(int argc, char* argv[]) -{ - - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); - - int howmany = 1000000; - - FLAGS_logtostderr = 0; - FLAGS_log_dir = "logs"; - google::InitGoogleLogging(argv[0]); - - std::atomic msg_counter {0}; - vector threads; - - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - LOG(INFO) << "glog message #" << counter << ": This is some text for your pleasure"; - } - })); - } - - - for(auto &t:threads) - { - t.join(); - }; - - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/glog-bench.cpp b/fpga/thirdparty/spdlog/bench/glog-bench.cpp deleted file mode 100644 index cf7e70a2d..000000000 --- a/fpga/thirdparty/spdlog/bench/glog-bench.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include "glog/logging.h" - - -int main(int, char* argv[]) -{ - int howmany = 1000000; - - - FLAGS_logtostderr = 0; - FLAGS_log_dir = "logs"; - google::InitGoogleLogging(argv[0]); - for(int i = 0 ; i < howmany; ++i) - LOG(INFO) << "glog message # " << i << ": This is some text for your pleasure"; - - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/latency/Makefile b/fpga/thirdparty/spdlog/bench/latency/Makefile deleted file mode 100644 index 99b479a4a..000000000 --- a/fpga/thirdparty/spdlog/bench/latency/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -CXX ?= g++ -CXXFLAGS = -march=native -Wall -std=c++11 -pthread -CXX_RELEASE_FLAGS = -O2 -DNDEBUG - - -binaries=spdlog-latency g3log-latency g3log-crush - -all: $(binaries) - -spdlog-latency: spdlog-latency.cpp - $(CXX) spdlog-latency.cpp -o spdlog-latency $(CXXFLAGS) $(CXX_RELEASE_FLAGS) -I../../include - - - -g3log-latency: g3log-latency.cpp - $(CXX) g3log-latency.cpp -o g3log-latency $(CXXFLAGS) $(CXX_RELEASE_FLAGS) -I../../../g3log/src -L. -lg3logger - - -g3log-crush: g3log-crush.cpp - $(CXX) g3log-crush.cpp -o g3log-crush $(CXXFLAGS) $(CXX_RELEASE_FLAGS) -I../../../g3log/src -L. -lg3logger - - -.PHONY: clean - -clean: - rm -f *.o *.log $(binaries) - - -rebuild: clean all - - - diff --git a/fpga/thirdparty/spdlog/bench/latency/compare.sh b/fpga/thirdparty/spdlog/bench/latency/compare.sh deleted file mode 100755 index 0f0e4c97f..000000000 --- a/fpga/thirdparty/spdlog/bench/latency/compare.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -echo "running spdlog and g3log tests 10 time with ${1:-10} threads each (total 1,000,000 entries).." -rm -f *.log -for i in {1..10} - -do - echo - sleep 0.5 - ./spdlog-latency ${1:-10} 2>/dev/null || exit - sleep 0.5 - ./g3log-latency ${1:-10} 2>/dev/null || exit - -done diff --git a/fpga/thirdparty/spdlog/bench/latency/g3log-crush.cpp b/fpga/thirdparty/spdlog/bench/latency/g3log-crush.cpp deleted file mode 100644 index 417b014ca..000000000 --- a/fpga/thirdparty/spdlog/bench/latency/g3log-crush.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include -#include - -void CrusherLoop() -{ - size_t counter = 0; - while (true) - { - LOGF(INFO, "Some text to crush you machine. thread:"); - if(++counter % 1000000 == 0) - { - std::cout << "Wrote " << counter << " entries" << std::endl; - } - } -} - - -int main(int argc, char** argv) -{ - std::cout << "WARNING: This test will exaust all your machine memory and will crush it!" << std::endl; - std::cout << "Are you sure you want to continue ? " << std::endl; - char c; - std::cin >> c; - if (toupper( c ) != 'Y') - return 0; - - auto worker = g3::LogWorker::createLogWorker(); - auto handle= worker->addDefaultLogger(argv[0], "g3log.txt"); - g3::initializeLogging(worker.get()); - CrusherLoop(); - - return 0; -} - - diff --git a/fpga/thirdparty/spdlog/bench/latency/g3log-latency.cpp b/fpga/thirdparty/spdlog/bench/latency/g3log-latency.cpp deleted file mode 100644 index e96e421b9..000000000 --- a/fpga/thirdparty/spdlog/bench/latency/g3log-latency.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "utils.h" -#include -#include - - -namespace -{ -const uint64_t g_iterations = 1000000; - - -std::atomic g_counter = {0}; - - -void MeasurePeakDuringLogWrites(const size_t id, std::vector& result) -{ - - while (true) - { - const size_t value_now = ++g_counter; - if (value_now > g_iterations) - { - return; - } - - auto start_time = std::chrono::high_resolution_clock::now(); - LOGF(INFO, "Some text to log for thread: %ld", id); - auto stop_time = std::chrono::high_resolution_clock::now(); - uint64_t time_us = std::chrono::duration_cast(stop_time - start_time).count(); - result.push_back(time_us); - } -} - - - -void PrintResults(const std::map>& threads_result, size_t total_us) -{ - - std::vector all_measurements; - all_measurements.reserve(g_iterations); - for (auto& t_result : threads_result) - { - all_measurements.insert(all_measurements.end(), t_result.second.begin(), t_result.second.end()); - } - - // calc worst latenct - auto worst = *std::max_element(all_measurements.begin(), all_measurements.end()); - - // calc avg - auto total = accumulate(begin(all_measurements), end(all_measurements), 0, std::plus()); - auto avg = double(total)/all_measurements.size(); - - std::cout << "[g3log] worst: " << std::setw(10) << std::right << worst << "\tAvg: " << avg << "\tTotal: " << utils::format(total_us) << " us" << std::endl; - -} -}// anonymous - - -// The purpose of this test is NOT to see how fast -// each thread can possibly write. It is to see what -// the worst latency is for writing a log entry -// -// In the test 1 million log entries will be written -// an atomic counter is used to give each thread what -// it is to write next. The overhead of atomic -// synchronization between the threads are not counted in the worst case latency -int main(int argc, char** argv) -{ - size_t number_of_threads {0}; - if (argc == 2) - { - number_of_threads = atoi(argv[1]); - } - if (argc != 2 || number_of_threads == 0) - { - std::cerr << "USAGE is: " << argv[0] << " number_threads" << std::endl; - return 1; - } - - - std::vector threads(number_of_threads); - std::map> threads_result; - - for (size_t idx = 0; idx < number_of_threads; ++idx) - { - // reserve to 1 million for all the result - // it's a test so let's not care about the wasted space - threads_result[idx].reserve(g_iterations); - } - - const std::string g_path = "./" ; - const std::string g_prefix_log_name = "g3log-performance-"; - const std::string g_measurement_dump = g_path + g_prefix_log_name + "_RESULT.txt"; - - auto worker = g3::LogWorker::createLogWorker(); - auto handle= worker->addDefaultLogger(argv[0], "g3log.txt"); - g3::initializeLogging(worker.get()); - - auto start_time_application_total = std::chrono::high_resolution_clock::now(); - for (uint64_t idx = 0; idx < number_of_threads; ++idx) - { - threads[idx] = std::thread(MeasurePeakDuringLogWrites, idx, std::ref(threads_result[idx])); - } - for (size_t idx = 0; idx < number_of_threads; ++idx) - { - threads[idx].join(); - } - auto stop_time_application_total = std::chrono::high_resolution_clock::now(); - - uint64_t total_time_in_us = std::chrono::duration_cast(stop_time_application_total - start_time_application_total).count(); - PrintResults(threads_result, total_time_in_us); - return 0; -} - - diff --git a/fpga/thirdparty/spdlog/bench/latency/spdlog-latency.cpp b/fpga/thirdparty/spdlog/bench/latency/spdlog-latency.cpp deleted file mode 100644 index ed4966cc4..000000000 --- a/fpga/thirdparty/spdlog/bench/latency/spdlog-latency.cpp +++ /dev/null @@ -1,128 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "utils.h" -#include - -#include "spdlog/spdlog.h" - -namespace spd = spdlog; - -namespace -{ -const uint64_t g_iterations = 1000000; - - -std::atomic g_counter = {0}; - - -void MeasurePeakDuringLogWrites(const size_t id, std::vector& result) -{ - auto logger = spd::get("file_logger"); - while (true) - { - const size_t value_now = ++g_counter; - if (value_now > g_iterations) - { - return; - } - - auto start_time = std::chrono::high_resolution_clock::now(); - logger->info("Some text to log for thread: [somemore text...............................] {}", id); - auto stop_time = std::chrono::high_resolution_clock::now(); - uint64_t time_us = std::chrono::duration_cast(stop_time - start_time).count(); - result.push_back(time_us); - } -} - - -void PrintResults(const std::map>& threads_result, size_t total_us) -{ - - std::vector all_measurements; - all_measurements.reserve(g_iterations); - for (auto& t_result : threads_result) - { - all_measurements.insert(all_measurements.end(), t_result.second.begin(), t_result.second.end()); - } - - // calc worst latenct - auto worst = *std::max_element(all_measurements.begin(), all_measurements.end()); - - // calc avg - auto total = accumulate(begin(all_measurements), end(all_measurements), 0, std::plus()); - auto avg = double(total)/all_measurements.size(); - - std::cout << "[spdlog] worst: " << std::setw(10) << std::right << worst << "\tAvg: " << avg << "\tTotal: " << utils::format(total_us) << " us" << std::endl; - -} -}// anonymous - - -// The purpose of this test is NOT to see how fast -// each thread can possibly write. It is to see what -// the worst latency is for writing a log entry -// -// In the test 1 million log entries will be written -// an atomic counter is used to give each thread what -// it is to write next. The overhead of atomic -// synchronization between the threads are not counted in the worst case latency -int main(int argc, char** argv) -{ - size_t number_of_threads {0}; - if (argc == 2) - { - number_of_threads = atoi(argv[1]); - } - if (argc != 2 || number_of_threads == 0) - { - std::cerr << "usage: " << argv[0] << " number_threads" << std::endl; - return 1; - } - - - std::vector threads(number_of_threads); - std::map> threads_result; - - for (size_t idx = 0; idx < number_of_threads; ++idx) - { - // reserve to 1 million for all the result - // it's a test so let's not care about the wasted space - threads_result[idx].reserve(g_iterations); - } - - int queue_size = 1048576; // 2 ^ 20 - spdlog::set_async_mode(queue_size); - auto logger = spdlog::create("file_logger", "spdlog.log", true); - - //force flush on every call to compare with g3log - auto s = (spd::sinks::simple_file_sink_mt*)logger->sinks()[0].get(); - s->set_force_flush(true); - - auto start_time_application_total = std::chrono::high_resolution_clock::now(); - for (uint64_t idx = 0; idx < number_of_threads; ++idx) - { - threads[idx] = std::thread(MeasurePeakDuringLogWrites, idx, std::ref(threads_result[idx])); - } - for (size_t idx = 0; idx < number_of_threads; ++idx) - { - threads[idx].join(); - } - auto stop_time_application_total = std::chrono::high_resolution_clock::now(); - - uint64_t total_time_in_us = std::chrono::duration_cast(stop_time_application_total - start_time_application_total).count(); - - PrintResults(threads_result, total_time_in_us); - return 0; -} - - diff --git a/fpga/thirdparty/spdlog/bench/latency/utils.h b/fpga/thirdparty/spdlog/bench/latency/utils.h deleted file mode 100644 index b260f7249..000000000 --- a/fpga/thirdparty/spdlog/bench/latency/utils.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include -#include -#include - -namespace utils -{ - -template -inline std::string format(const T& value) -{ - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << value; - return ss.str(); -} - -template<> -inline std::string format(const double & value) -{ - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << std::fixed << std::setprecision(1) << value; - return ss.str(); -} - -} diff --git a/fpga/thirdparty/spdlog/bench/logs/.gitignore b/fpga/thirdparty/spdlog/bench/logs/.gitignore deleted file mode 100644 index 40637012b..000000000 --- a/fpga/thirdparty/spdlog/bench/logs/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/fpga/thirdparty/spdlog/bench/spdlog-async.cpp b/fpga/thirdparty/spdlog/bench/spdlog-async.cpp deleted file mode 100644 index f788e4dfb..000000000 --- a/fpga/thirdparty/spdlog/bench/spdlog-async.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include -#include -#include -#include -#include -#include -#include "spdlog/spdlog.h" - -using namespace std; - -int main(int argc, char* argv[]) -{ - - using namespace std::chrono; - using clock=steady_clock; - namespace spd = spdlog; - - int thread_count = 10; - if(argc > 1) - thread_count = ::atoi(argv[1]); - int howmany = 1000000; - - spd::set_async_mode(1048576); - auto logger = spdlog::create("file_logger", "logs/spd-bench-async.txt", false); - logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); - - - std::atomic msg_counter {0}; - vector threads; - auto start = clock::now(); - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - logger->info("spdlog message #{}: This is some text for your pleasure", counter); - } - })); - } - - for(auto &t:threads) - { - t.join(); - }; - - duration delta = clock::now() - start; - float deltaf = delta.count(); - auto rate = howmany/deltaf; - - cout << "Total: " << howmany << std::endl; - cout << "Threads: " << thread_count << std::endl; - std::cout << "Delta = " << deltaf << " seconds" << std::endl; - std::cout << "Rate = " << rate << "/sec" << std::endl; -} diff --git a/fpga/thirdparty/spdlog/bench/spdlog-bench-mt.cpp b/fpga/thirdparty/spdlog/bench/spdlog-bench-mt.cpp deleted file mode 100644 index e28e7bb83..000000000 --- a/fpga/thirdparty/spdlog/bench/spdlog-bench-mt.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include -#include -#include -#include -#include "spdlog/spdlog.h" - - -using namespace std; - -int main(int argc, char* argv[]) -{ - - int thread_count = 10; - if(argc > 1) - thread_count = std::atoi(argv[1]); - - int howmany = 1000000; - - namespace spd = spdlog; - - auto logger = spdlog::create("file_logger", "logs/spd-bench-mt.txt", false); - - logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); - - std::atomic msg_counter {0}; - std::vector threads; - - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - logger->info("spdlog message #{}: This is some text for your pleasure", counter); - } - })); - } - - - for(auto &t:threads) - { - t.join(); - }; - - - - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/spdlog-bench.cpp b/fpga/thirdparty/spdlog/bench/spdlog-bench.cpp deleted file mode 100644 index 4ac95f6af..000000000 --- a/fpga/thirdparty/spdlog/bench/spdlog-bench.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#include "spdlog/spdlog.h" - - -int main(int, char* []) -{ - int howmany = 1000000; - namespace spd = spdlog; - ///Create a file rotating logger with 5mb size max and 3 rotated files - auto logger = spdlog::create("file_logger", "logs/spd-bench-st.txt", false); - - logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); - for(int i = 0 ; i < howmany; ++i) - logger->info("spdlog message #{} : This is some text for your pleasure", i); - return 0; -} diff --git a/fpga/thirdparty/spdlog/bench/spdlog-null-async.cpp b/fpga/thirdparty/spdlog/bench/spdlog-null-async.cpp deleted file mode 100644 index 3874371a7..000000000 --- a/fpga/thirdparty/spdlog/bench/spdlog-null-async.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -// -// bench.cpp : spdlog benchmarks -// -#include -#include // EXIT_FAILURE -#include -#include -#include -#include -#include "spdlog/spdlog.h" -#include "spdlog/async_logger.h" -#include "spdlog/sinks/null_sink.h" -#include "utils.h" - - -using namespace std; -using namespace std::chrono; -using namespace spdlog; -using namespace spdlog::sinks; -using namespace utils; - - - -size_t bench_as(int howmany, std::shared_ptr log, int thread_count); - -int main(int argc, char* argv[]) -{ - - int queue_size = 1048576; - int howmany = 1000000; - int threads = 10; - int iters = 10; - - try - { - - if(argc > 1) - howmany = atoi(argv[1]); - if (argc > 2) - threads = atoi(argv[2]); - if (argc > 3) - queue_size = atoi(argv[3]); - - - cout << "\n*******************************************************************************\n"; - cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " messages " << endl; - cout << "*******************************************************************************\n"; - - spdlog::set_async_mode(queue_size); - - size_t total_rate = 0; - - for(int i = 0; i < iters; ++i) - { - //auto as = spdlog::daily_logger_st("as", "logs/daily_async"); - auto as = spdlog::create("async(null-sink)"); - total_rate+= bench_as(howmany, as, threads); - spdlog::drop("async(null-sink)"); - } - std::cout << endl; - std::cout << "Avg rate: " << format(total_rate/iters) << "/sec" < log, int thread_count) -{ - cout << log->name() << "...\t\t" << flush; - std::atomic msg_counter {0}; - vector threads; - auto start = system_clock::now(); - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - for(;;) - { - int counter = ++msg_counter; - if (counter > howmany) break; - log->info("Hello logger: msg number {}", counter); - } - })); - } - - - for(auto &t:threads) - { - t.join(); - }; - - - auto delta = system_clock::now() - start; - auto delta_d = duration_cast> (delta).count(); - auto per_sec = size_t(howmany / delta_d); - cout << format(per_sec) << "/sec" << endl; - return per_sec; -} diff --git a/fpga/thirdparty/spdlog/bench/utils.h b/fpga/thirdparty/spdlog/bench/utils.h deleted file mode 100644 index b260f7249..000000000 --- a/fpga/thirdparty/spdlog/bench/utils.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include -#include -#include - -namespace utils -{ - -template -inline std::string format(const T& value) -{ - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << value; - return ss.str(); -} - -template<> -inline std::string format(const double & value) -{ - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << std::fixed << std::setprecision(1) << value; - return ss.str(); -} - -} diff --git a/fpga/thirdparty/spdlog/cmake/Config.cmake.in b/fpga/thirdparty/spdlog/cmake/Config.cmake.in deleted file mode 100644 index ba0b36f2b..000000000 --- a/fpga/thirdparty/spdlog/cmake/Config.cmake.in +++ /dev/null @@ -1,24 +0,0 @@ -# *************************************************************************/ -# * Copyright (c) 2015 Ruslan Baratov. */ -# * */ -# * Permission is hereby granted, free of charge, to any person obtaining */ -# * a copy of this software and associated documentation files (the */ -# * "Software"), to deal in the Software without restriction, including */ -# * without limitation the rights to use, copy, modify, merge, publish, */ -# * distribute, sublicense, and/or sell copies of the Software, and to */ -# * permit persons to whom the Software is furnished to do so, subject to */ -# * the following conditions: */ -# * */ -# * The above copyright notice and this permission notice shall be */ -# * included in all copies or substantial portions of the Software. */ -# * */ -# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -# * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -# * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -# * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -# * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -# * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -# * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -# *************************************************************************/ - -include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") diff --git a/fpga/thirdparty/spdlog/cmake/spdlog.pc.in b/fpga/thirdparty/spdlog/cmake/spdlog.pc.in deleted file mode 100644 index 262248a74..000000000 --- a/fpga/thirdparty/spdlog/cmake/spdlog.pc.in +++ /dev/null @@ -1,6 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -includedir=${prefix}/include - -Name: @PROJECT_NAME@ -Description: Super fast C++ logging library. -Version: @PROJECT_VERSION@ diff --git a/fpga/thirdparty/spdlog/example/CMakeLists.txt b/fpga/thirdparty/spdlog/example/CMakeLists.txt deleted file mode 100644 index 7859e4d58..000000000 --- a/fpga/thirdparty/spdlog/example/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# *************************************************************************/ -# * Copyright (c) 2015 Ruslan Baratov. */ -# * */ -# * Permission is hereby granted, free of charge, to any person obtaining */ -# * a copy of this software and associated documentation files (the */ -# * "Software"), to deal in the Software without restriction, including */ -# * without limitation the rights to use, copy, modify, merge, publish, */ -# * distribute, sublicense, and/or sell copies of the Software, and to */ -# * permit persons to whom the Software is furnished to do so, subject to */ -# * the following conditions: */ -# * */ -# * The above copyright notice and this permission notice shall be */ -# * included in all copies or substantial portions of the Software. */ -# * */ -# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -# * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -# * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -# * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -# * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -# * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -# * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -# *************************************************************************/ - -cmake_minimum_required(VERSION 3.0) -project(SpdlogExamples) - -if(TARGET spdlog) - # Part of the main project - add_library(spdlog::spdlog ALIAS spdlog) -else() - # Stand-alone build - find_package(spdlog CONFIG REQUIRED) -endif() - -find_package(Threads) - -add_executable(example example.cpp) -target_link_libraries(example spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) - -add_executable(benchmark bench.cpp) -target_link_libraries(benchmark spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) - -add_executable(multisink multisink.cpp) -target_link_libraries(multisink spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) - -enable_testing() -file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs") -add_test(NAME RunExample COMMAND example) -add_test(NAME RunBenchmark COMMAND benchmark) diff --git a/fpga/thirdparty/spdlog/example/Makefile b/fpga/thirdparty/spdlog/example/Makefile deleted file mode 100644 index 6d169e41c..000000000 --- a/fpga/thirdparty/spdlog/example/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -CXX ?= g++ -CXXFLAGS = -CXX_FLAGS = -Wall -Wshadow -Wextra -pedantic -std=c++11 -pthread -I../include -CXX_RELEASE_FLAGS = -O3 -march=native -CXX_DEBUG_FLAGS= -g - - -all: example bench -debug: example-debug bench-debug - -example: example.cpp - $(CXX) example.cpp -o example $(CXX_FLAGS) $(CXX_RELEASE_FLAGS) $(CXXFLAGS) - -bench: bench.cpp - $(CXX) bench.cpp -o bench $(CXX_FLAGS) $(CXX_RELEASE_FLAGS) $(CXXFLAGS) - - -example-debug: example.cpp - $(CXX) example.cpp -o example-debug $(CXX_FLAGS) $(CXX_DEBUG_FLAGS) $(CXXFLAGS) - -bench-debug: bench.cpp - $(CXX) bench.cpp -o bench-debug $(CXX_FLAGS) $(CXX_DEBUG_FLAGS) $(CXXFLAGS) - -clean: - rm -f *.o logs/*.txt example example-debug bench bench-debug - - -rebuild: clean all -rebuild-debug: clean debug diff --git a/fpga/thirdparty/spdlog/example/Makefile.clang b/fpga/thirdparty/spdlog/example/Makefile.clang deleted file mode 100644 index 0ed004d03..000000000 --- a/fpga/thirdparty/spdlog/example/Makefile.clang +++ /dev/null @@ -1,32 +0,0 @@ -CXX ?= clang++ -CXXFLAGS = -march=native -Wall -Wextra -Wshadow -pedantic -std=c++11 -pthread -I../include -CXX_RELEASE_FLAGS = -O2 -CXX_DEBUG_FLAGS= -g - - -all: example bench -debug: example-debug bench-debug - -example: example.cpp - $(CXX) example.cpp -o example-clang $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - -bench: bench.cpp - $(CXX) bench.cpp -o bench-clang $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - - -example-debug: example.cpp - $(CXX) example.cpp -o example-clang-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) - -bench-debug: bench.cpp - $(CXX) bench.cpp -o bench-clang-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) - - - -clean: - rm -f *.o logs/*.txt example-clang example-clang-debug bench-clang bench-clang-debug - - -rebuild: clean all -rebuild-debug: clean debug - - diff --git a/fpga/thirdparty/spdlog/example/Makefile.mingw b/fpga/thirdparty/spdlog/example/Makefile.mingw deleted file mode 100644 index 5ee5ab6fc..000000000 --- a/fpga/thirdparty/spdlog/example/Makefile.mingw +++ /dev/null @@ -1,32 +0,0 @@ -CXX ?= g++ -CXXFLAGS = -D_WIN32_WINNT=0x600 -march=native -Wall -Wextra -Wshadow -pedantic -std=gnu++0x -pthread -Wl,--no-as-needed -I../include -CXX_RELEASE_FLAGS = -O3 -CXX_DEBUG_FLAGS= -g - - -all: example bench -debug: example-debug bench-debug - -example: example.cpp - $(CXX) example.cpp -o example $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - -bench: bench.cpp - $(CXX) bench.cpp -o bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS) - - -example-debug: example.cpp - $(CXX) example.cpp -o example-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) - -bench-debug: bench.cpp - $(CXX) bench.cpp -o bench-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) - - - -clean: - rm -f *.o logs/*.txt example example-debug bench bench-debug - - -rebuild: clean all -rebuild-debug: clean debug - - diff --git a/fpga/thirdparty/spdlog/example/bench.cpp b/fpga/thirdparty/spdlog/example/bench.cpp deleted file mode 100644 index b21c44353..000000000 --- a/fpga/thirdparty/spdlog/example/bench.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -// -// bench.cpp : spdlog benchmarks -// -#include -#include // EXIT_FAILURE -#include -#include -#include -#include -#include "spdlog/spdlog.h" -#include "spdlog/async_logger.h" -#include "spdlog/sinks/file_sinks.h" -#include "spdlog/sinks/null_sink.h" -#include "utils.h" - - -using namespace std; -using namespace std::chrono; -using namespace spdlog; -using namespace spdlog::sinks; -using namespace utils; - - -void bench(int howmany, std::shared_ptr log); -void bench_mt(int howmany, std::shared_ptr log, int thread_count); - -int main(int argc, char* argv[]) -{ - - int queue_size = 1048576; - int howmany = 1000000; - int threads = 10; - int file_size = 30 * 1024 * 1024; - int rotating_files = 5; - - try - { - - if(argc > 1) - howmany = atoi(argv[1]); - if (argc > 2) - threads = atoi(argv[2]); - if (argc > 3) - queue_size = atoi(argv[3]); - - - cout << "*******************************************************************************\n"; - cout << "Single thread, " << format(howmany) << " iterations" << endl; - cout << "*******************************************************************************\n"; - - auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st", file_size, rotating_files); - bench(howmany, rotating_st); - auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st"); - bench(howmany, daily_st); - bench(howmany, spdlog::create("null_st")); - - cout << "\n*******************************************************************************\n"; - cout << threads << " threads sharing same logger, " << format(howmany) << " iterations" << endl; - cout << "*******************************************************************************\n"; - - auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt", file_size, rotating_files); - bench_mt(howmany, rotating_mt, threads); - - - auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt"); - bench_mt(howmany, daily_mt, threads); - bench(howmany, spdlog::create("null_mt")); - - cout << "\n*******************************************************************************\n"; - cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations " << endl; - cout << "*******************************************************************************\n"; - - - spdlog::set_async_mode(queue_size); - - for(int i = 0; i < 3; ++i) - { - auto as = spdlog::daily_logger_st("as", "logs/daily_async"); - bench_mt(howmany, as, threads); - spdlog::drop("as"); - } - } - catch (std::exception &ex) - { - std::cerr << "Error: " << ex.what() << std::endl; - perror("Last error"); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} - - -void bench(int howmany, std::shared_ptr log) -{ - cout << log->name() << "...\t\t" << flush; - auto start = system_clock::now(); - for (auto i = 0; i < howmany; ++i) - { - log->info("Hello logger: msg number {}", i); - } - - - auto delta = system_clock::now() - start; - auto delta_d = duration_cast> (delta).count(); - cout << format(int(howmany / delta_d)) << "/sec" << endl; -} - - -void bench_mt(int howmany, std::shared_ptr log, int thread_count) -{ - - cout << log->name() << "...\t\t" << flush; - std::atomic msg_counter {0}; - vector threads; - auto start = system_clock::now(); - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - for(;;) - { - int counter = ++msg_counter; - if (counter > howmany) break; - log->info("Hello logger: msg number {}", counter); - } - })); - } - - - for(auto &t:threads) - { - t.join(); - }; - - - auto delta = system_clock::now() - start; - auto delta_d = duration_cast> (delta).count(); - cout << format(int(howmany / delta_d)) << "/sec" << endl; -} diff --git a/fpga/thirdparty/spdlog/example/example.cpp b/fpga/thirdparty/spdlog/example/example.cpp deleted file mode 100644 index c9aee7ad7..000000000 --- a/fpga/thirdparty/spdlog/example/example.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// -// -// spdlog usage example -// -// - -#define SPDLOG_TRACE_ON -#define SPDLOG_DEBUG_ON - -#include "spdlog/spdlog.h" - -#include -#include - -void async_example(); -void syslog_example(); -void android_example(); -void user_defined_example(); -void err_handler_example(); - -namespace spd = spdlog; -int main(int, char*[]) -{ - try - { - // Console logger with color - auto console = spd::stdout_color_mt("console"); - console->info("Welcome to spdlog!"); - console->error("Some error message with arg{}..", 1); - - - // Formatting examples - console->warn("Easy padding in numbers like {:08d}", 12); - console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); - console->info("Support for floats {:03.2f}", 1.23456); - console->info("Positional args are {1} {0}..", "too", "supported"); - console->info("{:<30}", "left aligned"); - - spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); - - - // Create basic file logger (not rotated) - auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic-log.txt"); - my_logger->info("Some log message"); - - // Create a file rotating logger with 5mb size max and 3 rotated files - auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3); - for (int i = 0; i < 10; ++i) - rotating_logger->info("{} * {} equals {:>10}", i, i, i*i); - - // Create a daily logger - a new file is created every day on 2:30am - auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); - // trigger flush if the log severity is error or higher - daily_logger->flush_on(spd::level::err); - daily_logger->info(123.44); - - // Customize msg format for all messages - spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); - rotating_logger->info("This is another message with custom format"); - - - // Runtime log levels - spd::set_level(spd::level::info); //Set global log level to info - console->debug("This message shold not be displayed!"); - console->set_level(spd::level::debug); // Set specific logger's log level - console->debug("This message shold be displayed.."); - - // Compile time log levels - // define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON - SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); - SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23); - - - // Asynchronous logging is very fast.. - // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous.. - async_example(); - - // syslog example. linux/osx only - syslog_example(); - - // android example. compile with NDK - android_example(); - - // Log user-defined types example - user_defined_example(); - - // Change default log error handler - err_handler_example(); - - // Apply a function on all registered loggers - spd::apply_all([&](std::shared_ptr l) - { - l->info("End of example."); - }); - - // Release and close all loggers - spdlog::drop_all(); - } - // Exceptions will only be thrown upon failed logger or sink construction (not during logging) - catch (const spd::spdlog_ex& ex) - { - std::cout << "Log init failed: " << ex.what() << std::endl; - return 1; - } -} - -void async_example() -{ - size_t q_size = 4096; //queue size must be power of 2 - spdlog::set_async_mode(q_size); - auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt"); - for (int i = 0; i < 100; ++i) - async_file->info("Async message #{}", i); -} - -//syslog example (linux/osx/freebsd) -void syslog_example() -{ -#ifdef SPDLOG_ENABLE_SYSLOG - std::string ident = "spdlog-example"; - auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID); - syslog_logger->warn("This is warning that will end up in syslog."); -#endif -} - -// Android example -void android_example() -{ -#if defined(__ANDROID__) - std::string tag = "spdlog-android"; - auto android_logger = spd::android_logger("android", tag); - android_logger->critical("Use \"adb shell logcat\" to view this message."); -#endif -} - -// user defined types logging by implementing operator<< -struct my_type -{ - int i; - template - friend OStream& operator<<(OStream& os, const my_type &c) - { - return os << "[my_type i="<info("user defined type: {}", my_type { 14 }); -} - -// -//custom error handler -// -void err_handler_example() -{ - //can be set globaly or per logger(logger->set_error_handler(..)) - spdlog::set_error_handler([](const std::string& msg) - { - std::cerr << "my err handler: " << msg << std::endl; - }); - spd::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3); -} diff --git a/fpga/thirdparty/spdlog/example/example.sln b/fpga/thirdparty/spdlog/example/example.sln deleted file mode 100644 index 81f45629a..000000000 --- a/fpga/thirdparty/spdlog/example/example.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example.vcxproj", "{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Debug|Win32.ActiveCfg = Debug|Win32 - {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Debug|Win32.Build.0 = Debug|Win32 - {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Debug|x64.ActiveCfg = Debug|Win32 - {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Release|Win32.ActiveCfg = Release|Win32 - {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Release|Win32.Build.0 = Release|Win32 - {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/fpga/thirdparty/spdlog/example/example.vcxproj b/fpga/thirdparty/spdlog/example/example.vcxproj deleted file mode 100644 index 63db2b5dd..000000000 --- a/fpga/thirdparty/spdlog/example/example.vcxproj +++ /dev/null @@ -1,126 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2} - Win32Proj - . - 8.1 - - - - Application - true - v120 - Unicode - - - Application - false - v120 - true - Unicode - - - - - - - - - - - - - true - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - ..\include;%(AdditionalIncludeDirectories) - - - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - ..\include;%(AdditionalIncludeDirectories) - - - - - Console - true - true - true - %(AdditionalLibraryDirectories) - %(AdditionalDependencies) - - - - - - \ No newline at end of file diff --git a/fpga/thirdparty/spdlog/example/jni/Android.mk b/fpga/thirdparty/spdlog/example/jni/Android.mk deleted file mode 100644 index 7accbad31..000000000 --- a/fpga/thirdparty/spdlog/example/jni/Android.mk +++ /dev/null @@ -1,15 +0,0 @@ -# Setup a project -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := example -LOCAL_SRC_FILES := example.cpp -LOCAL_CPPFLAGS += -Wall -Wshadow -Wextra -pedantic -std=c++11 -fPIE -pie -LOCAL_LDFLAGS += -fPIE -pie - -# Add exception support and set path for spdlog's headers -LOCAL_CPPFLAGS += -fexceptions -I../include -# Use android's log library -LOCAL_LDFLAGS += -llog - -include $(BUILD_EXECUTABLE) diff --git a/fpga/thirdparty/spdlog/example/jni/Application.mk b/fpga/thirdparty/spdlog/example/jni/Application.mk deleted file mode 100644 index dccd2a5a3..000000000 --- a/fpga/thirdparty/spdlog/example/jni/Application.mk +++ /dev/null @@ -1,2 +0,0 @@ -# Exceptions are used in spdlog. Link to an exception-ready C++ runtime. -APP_STL = gnustl_static diff --git a/fpga/thirdparty/spdlog/example/jni/example.cpp b/fpga/thirdparty/spdlog/example/jni/example.cpp deleted file mode 120000 index 6170abce2..000000000 --- a/fpga/thirdparty/spdlog/example/jni/example.cpp +++ /dev/null @@ -1 +0,0 @@ -../example.cpp \ No newline at end of file diff --git a/fpga/thirdparty/spdlog/example/logs/.gitignore b/fpga/thirdparty/spdlog/example/logs/.gitignore deleted file mode 100644 index 203251351..000000000 --- a/fpga/thirdparty/spdlog/example/logs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.txt diff --git a/fpga/thirdparty/spdlog/example/multisink.cpp b/fpga/thirdparty/spdlog/example/multisink.cpp deleted file mode 100644 index fe6539b53..000000000 --- a/fpga/thirdparty/spdlog/example/multisink.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "spdlog/spdlog.h" - -#include -#include - -namespace spd = spdlog; -int main(int, char*[]) -{ - bool enable_debug = true; - try - { - // This other example use a single logger with multiple sinks. - // This means that the same log_msg is forwarded to multiple sinks; - // Each sink can have it's own log level and a message will be logged. - std::vector sinks; - sinks.push_back( std::make_shared() ); - sinks.push_back( std::make_shared("./log_regular_file.txt") ); - sinks.push_back( std::make_shared("./log_debug_file.txt") ); - - spdlog::logger console_multisink("multisink", sinks.begin(), sinks.end() ); - console_multisink.set_level( spdlog::level::warn); - - sinks[0]->set_level( spdlog::level::trace); // console. Allow everything. Default value - sinks[1]->set_level( spdlog::level::trace); // regular file. Allow everything. Default value - sinks[2]->set_level( spdlog::level::off); // regular file. Ignore everything. - - console_multisink.warn("warn: will print only on console and regular file"); - - if( enable_debug ) - { - console_multisink.set_level( spdlog::level::debug); // level of the logger - sinks[1]->set_level( spdlog::level::debug); // regular file - sinks[2]->set_level( spdlog::level::debug); // debug file - } - console_multisink.debug("Debug: you should see this on console and both files"); - - // Release and close all loggers - spdlog::drop_all(); - } - // Exceptions will only be thrown upon failed logger or sink construction (not during logging) - catch (const spd::spdlog_ex& ex) - { - std::cout << "Log init failed: " << ex.what() << std::endl; - return 1; - } -} - diff --git a/fpga/thirdparty/spdlog/example/utils.h b/fpga/thirdparty/spdlog/example/utils.h deleted file mode 100644 index b260f7249..000000000 --- a/fpga/thirdparty/spdlog/example/utils.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include -#include -#include - -namespace utils -{ - -template -inline std::string format(const T& value) -{ - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << value; - return ss.str(); -} - -template<> -inline std::string format(const double & value) -{ - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << std::fixed << std::setprecision(1) << value; - return ss.str(); -} - -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/async_logger.h b/fpga/thirdparty/spdlog/include/spdlog/async_logger.h deleted file mode 100644 index e9fcd5f40..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/async_logger.h +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// Very fast asynchronous logger (millions of logs per second on an average desktop) -// Uses pre allocated lockfree queue for maximum throughput even under large number of threads. -// Creates a single back thread to pop messages from the queue and log them. -// -// Upon each log write the logger: -// 1. Checks if its log level is enough to log the message -// 2. Push a new copy of the message to a queue (or block the caller until space is available in the queue) -// 3. will throw spdlog_ex upon log exceptions -// Upon destruction, logs all remaining messages in the queue before destructing.. - -#include "common.h" -#include "logger.h" - -#include -#include -#include -#include - -namespace spdlog -{ - -namespace details -{ -class async_log_helper; -} - -class async_logger SPDLOG_FINAL :public logger -{ -public: - template - async_logger(const std::string& name, - const It& begin, - const It& end, - size_t queue_size, - const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, - const std::function& worker_warmup_cb = nullptr, - const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), - const std::function& worker_teardown_cb = nullptr); - - async_logger(const std::string& logger_name, - sinks_init_list sinks, - size_t queue_size, - const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, - const std::function& worker_warmup_cb = nullptr, - const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), - const std::function& worker_teardown_cb = nullptr); - - async_logger(const std::string& logger_name, - sink_ptr single_sink, - size_t queue_size, - const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, - const std::function& worker_warmup_cb = nullptr, - const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), - const std::function& worker_teardown_cb = nullptr); - - //Wait for the queue to be empty, and flush synchronously - //Warning: this can potentially last forever as we wait it to complete - void flush() override; - - // Error handler - virtual void set_error_handler(log_err_handler) override; - virtual log_err_handler error_handler() override; - -protected: - void _sink_it(details::log_msg& msg) override; - void _set_formatter(spdlog::formatter_ptr msg_formatter) override; - void _set_pattern(const std::string& pattern, pattern_time_type pattern_time) override; - -private: - std::unique_ptr _async_log_helper; -}; -} - - -#include "details/async_logger_impl.h" diff --git a/fpga/thirdparty/spdlog/include/spdlog/common.h b/fpga/thirdparty/spdlog/include/spdlog/common.h deleted file mode 100644 index ea0b05670..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/common.h +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) -#include -#include -#endif - -#include "details/null_mutex.h" - -//visual studio upto 2013 does not support noexcept nor constexpr -#if defined(_MSC_VER) && (_MSC_VER < 1900) -#define SPDLOG_NOEXCEPT throw() -#define SPDLOG_CONSTEXPR -#else -#define SPDLOG_NOEXCEPT noexcept -#define SPDLOG_CONSTEXPR constexpr -#endif - -// final keyword support. On by default. See tweakme.h -#if defined(SPDLOG_NO_FINAL) -#define SPDLOG_FINAL -#else -#define SPDLOG_FINAL final -#endif - -#if defined(__GNUC__) || defined(__clang__) -#define SPDLOG_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define SPDLOG_DEPRECATED __declspec(deprecated) -#else -#define SPDLOG_DEPRECATED -#endif - -#include "fmt/fmt.h" - -namespace spdlog -{ - -class formatter; - -namespace sinks -{ -class sink; -} - -using log_clock = std::chrono::system_clock; -using sink_ptr = std::shared_ptr < sinks::sink >; -using sinks_init_list = std::initializer_list < sink_ptr >; -using formatter_ptr = std::shared_ptr; -#if defined(SPDLOG_NO_ATOMIC_LEVELS) -using level_t = details::null_atomic_int; -#else -using level_t = std::atomic; -#endif - -using log_err_handler = std::function; - -//Log level enum -namespace level -{ -typedef enum -{ - trace = 0, - debug = 1, - info = 2, - warn = 3, - err = 4, - critical = 5, - off = 6 -} level_enum; - -#if !defined(SPDLOG_LEVEL_NAMES) -#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "critical", "off" } -#endif -static const char* level_names[] SPDLOG_LEVEL_NAMES; - -static const char* short_level_names[] { "T", "D", "I", "W", "E", "C", "O" }; - -inline const char* to_str(spdlog::level::level_enum l) -{ - return level_names[l]; -} - -inline const char* to_short_str(spdlog::level::level_enum l) -{ - return short_level_names[l]; -} -} //level - - -// -// Async overflow policy - block by default. -// -enum class async_overflow_policy -{ - block_retry, // Block / yield / sleep until message can be enqueued - discard_log_msg // Discard the message it enqueue fails -}; - -// -// Pattern time - specific time getting to use for pattern_formatter. -// local time by default -// -enum class pattern_time_type -{ - local, // log localtime - utc // log utc -}; - -// -// Log exception -// -namespace details -{ -namespace os -{ -std::string errno_str(int err_num); -} -} -class spdlog_ex: public std::exception -{ -public: - spdlog_ex(const std::string& msg):_msg(msg) - {} - spdlog_ex(const std::string& msg, int last_errno) - { - _msg = msg + ": " + details::os::errno_str(last_errno); - } - const char* what() const SPDLOG_NOEXCEPT override - { - return _msg.c_str(); - } -private: - std::string _msg; - -}; - -// -// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined) -// -#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) -using filename_t = std::wstring; -#else -using filename_t = std::string; -#endif - - -} //spdlog diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/async_log_helper.h b/fpga/thirdparty/spdlog/include/spdlog/details/async_log_helper.h deleted file mode 100644 index 7c3dcf44f..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/async_log_helper.h +++ /dev/null @@ -1,399 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -// async log helper : -// Process logs asynchronously using a back thread. -// -// If the internal queue of log messages reaches its max size, -// then the client call will block until there is more room. -// - -#pragma once - -#include "../common.h" -#include "../sinks/sink.h" -#include "../details/mpmc_bounded_q.h" -#include "../details/log_msg.h" -#include "../details/os.h" -#include "../formatter.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace spdlog -{ -namespace details -{ - -class async_log_helper -{ - // Async msg to move to/from the queue - // Movable only. should never be copied - enum class async_msg_type - { - log, - flush, - terminate - }; - struct async_msg - { - std::string logger_name; - level::level_enum level; - log_clock::time_point time; - size_t thread_id; - std::string txt; - async_msg_type msg_type; - size_t msg_id; - - async_msg() = default; - ~async_msg() = default; - - -async_msg(async_msg&& other) SPDLOG_NOEXCEPT: - logger_name(std::move(other.logger_name)), - level(std::move(other.level)), - time(std::move(other.time)), - thread_id(other.thread_id), - txt(std::move(other.txt)), - msg_type(std::move(other.msg_type)), - msg_id(other.msg_id) - {} - - async_msg(async_msg_type m_type): - level(level::info), - thread_id(0), - msg_type(m_type), - msg_id(0) - {} - - async_msg& operator=(async_msg&& other) SPDLOG_NOEXCEPT - { - logger_name = std::move(other.logger_name); - level = other.level; - time = std::move(other.time); - thread_id = other.thread_id; - txt = std::move(other.txt); - msg_type = other.msg_type; - msg_id = other.msg_id; - return *this; - } - - // never copy or assign. should only be moved.. - async_msg(const async_msg&) = delete; - async_msg& operator=(const async_msg& other) = delete; - - // construct from log_msg - async_msg(const details::log_msg& m): - level(m.level), - time(m.time), - thread_id(m.thread_id), - txt(m.raw.data(), m.raw.size()), - msg_type(async_msg_type::log), - msg_id(m.msg_id) - { -#ifndef SPDLOG_NO_NAME - logger_name = *m.logger_name; -#endif - } - - - // copy into log_msg - void fill_log_msg(log_msg &msg) - { - msg.logger_name = &logger_name; - msg.level = level; - msg.time = time; - msg.thread_id = thread_id; - msg.raw << txt; - msg.msg_id = msg_id; - } - }; - -public: - - using item_type = async_msg; - using q_type = details::mpmc_bounded_queue; - - using clock = std::chrono::steady_clock; - - - async_log_helper(formatter_ptr formatter, - const std::vector& sinks, - size_t queue_size, - const log_err_handler err_handler, - const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, - const std::function& worker_warmup_cb = nullptr, - const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), - const std::function& worker_teardown_cb = nullptr); - - void log(const details::log_msg& msg); - - // stop logging and join the back thread - ~async_log_helper(); - - void set_formatter(formatter_ptr); - - void flush(bool wait_for_q); - - void set_error_handler(spdlog::log_err_handler err_handler); - -private: - formatter_ptr _formatter; - std::vector> _sinks; - - // queue of messages to log - q_type _q; - - log_err_handler _err_handler; - - bool _flush_requested; - - bool _terminate_requested; - - - // overflow policy - const async_overflow_policy _overflow_policy; - - // worker thread warmup callback - one can set thread priority, affinity, etc - const std::function _worker_warmup_cb; - - // auto periodic sink flush parameter - const std::chrono::milliseconds _flush_interval_ms; - - // worker thread teardown callback - const std::function _worker_teardown_cb; - - // worker thread - std::thread _worker_thread; - - void push_msg(async_msg&& new_msg); - - // worker thread main loop - void worker_loop(); - - // pop next message from the queue and process it. will set the last_pop to the pop time - // return false if termination of the queue is required - bool process_next_msg(log_clock::time_point& last_pop, log_clock::time_point& last_flush); - - void handle_flush_interval(log_clock::time_point& now, log_clock::time_point& last_flush); - - // sleep,yield or return immediately using the time passed since last message as a hint - static void sleep_or_yield(const spdlog::log_clock::time_point& now, const log_clock::time_point& last_op_time); - - // wait until the queue is empty - void wait_empty_q(); - -}; -} -} - -/////////////////////////////////////////////////////////////////////////////// -// async_sink class implementation -/////////////////////////////////////////////////////////////////////////////// -inline spdlog::details::async_log_helper::async_log_helper( - formatter_ptr formatter, - const std::vector& sinks, - size_t queue_size, - log_err_handler err_handler, - const async_overflow_policy overflow_policy, - const std::function& worker_warmup_cb, - const std::chrono::milliseconds& flush_interval_ms, - const std::function& worker_teardown_cb): - _formatter(formatter), - _sinks(sinks), - _q(queue_size), - _err_handler(err_handler), - _flush_requested(false), - _terminate_requested(false), - _overflow_policy(overflow_policy), - _worker_warmup_cb(worker_warmup_cb), - _flush_interval_ms(flush_interval_ms), - _worker_teardown_cb(worker_teardown_cb), - _worker_thread(&async_log_helper::worker_loop, this) -{} - -// Send to the worker thread termination message(level=off) -// and wait for it to finish gracefully -inline spdlog::details::async_log_helper::~async_log_helper() -{ - try - { - push_msg(async_msg(async_msg_type::terminate)); - _worker_thread.join(); - } - catch (...) // don't crash in destructor - { - } -} - - -//Try to push and block until succeeded (if the policy is not to discard when the queue is full) -inline void spdlog::details::async_log_helper::log(const details::log_msg& msg) -{ - push_msg(async_msg(msg)); -} - -inline void spdlog::details::async_log_helper::push_msg(details::async_log_helper::async_msg&& new_msg) -{ - if (!_q.enqueue(std::move(new_msg)) && _overflow_policy != async_overflow_policy::discard_log_msg) - { - auto last_op_time = details::os::now(); - auto now = last_op_time; - do - { - now = details::os::now(); - sleep_or_yield(now, last_op_time); - } - while (!_q.enqueue(std::move(new_msg))); - } -} - -// optionally wait for the queue be empty and request flush from the sinks -inline void spdlog::details::async_log_helper::flush(bool wait_for_q) -{ - push_msg(async_msg(async_msg_type::flush)); - if (wait_for_q) - wait_empty_q(); //return when queue is empty -} - -inline void spdlog::details::async_log_helper::worker_loop() -{ - if (_worker_warmup_cb) _worker_warmup_cb(); - auto last_pop = details::os::now(); - auto last_flush = last_pop; - auto active = true; - while (active) - { - try - { - active = process_next_msg(last_pop, last_flush); - } - catch (const std::exception &ex) - { - _err_handler(ex.what()); - } - catch(...) - { - _err_handler("Unknown exeption in async logger worker loop."); - } - } - if (_worker_teardown_cb) _worker_teardown_cb(); - - -} - -// process next message in the queue -// return true if this thread should still be active (while no terminate msg was received) -inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_point& last_pop, log_clock::time_point& last_flush) -{ - async_msg incoming_async_msg; - - if (_q.dequeue(incoming_async_msg)) - { - last_pop = details::os::now(); - switch (incoming_async_msg.msg_type) - { - case async_msg_type::flush: - _flush_requested = true; - break; - - case async_msg_type::terminate: - _flush_requested = true; - _terminate_requested = true; - break; - - default: - log_msg incoming_log_msg; - incoming_async_msg.fill_log_msg(incoming_log_msg); - _formatter->format(incoming_log_msg); - for (auto &s : _sinks) - { - if (s->should_log(incoming_log_msg.level)) - { - s->log(incoming_log_msg); - } - } - } - return true; - } - - // Handle empty queue.. - // This is the only place where the queue can terminate or flush to avoid losing messages already in the queue - else - { - auto now = details::os::now(); - handle_flush_interval(now, last_flush); - sleep_or_yield(now, last_pop); - return !_terminate_requested; - } -} - -// flush all sinks if _flush_interval_ms has expired -inline void spdlog::details::async_log_helper::handle_flush_interval(log_clock::time_point& now, log_clock::time_point& last_flush) -{ - auto should_flush = _flush_requested || (_flush_interval_ms != std::chrono::milliseconds::zero() && now - last_flush >= _flush_interval_ms); - if (should_flush) - { - for (auto &s : _sinks) - s->flush(); - now = last_flush = details::os::now(); - _flush_requested = false; - } -} - -inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_formatter) -{ - _formatter = msg_formatter; -} - - -// spin, yield or sleep. use the time passed since last message as a hint -inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_clock::time_point& now, const spdlog::log_clock::time_point& last_op_time) -{ - using namespace std::this_thread; - using std::chrono::milliseconds; - using std::chrono::microseconds; - - auto time_since_op = now - last_op_time; - - // spin upto 50 micros - if (time_since_op <= microseconds(50)) - return; - - // yield upto 150 micros - if (time_since_op <= microseconds(100)) - return std::this_thread::yield(); - - // sleep for 20 ms upto 200 ms - if (time_since_op <= milliseconds(200)) - return sleep_for(milliseconds(20)); - - // sleep for 500 ms - return sleep_for(milliseconds(500)); -} - -// wait for the queue to be empty -inline void spdlog::details::async_log_helper::wait_empty_q() -{ - auto last_op = details::os::now(); - while (!_q.is_empty()) - { - sleep_or_yield(details::os::now(), last_op); - } -} - -inline void spdlog::details::async_log_helper::set_error_handler(spdlog::log_err_handler err_handler) -{ - _err_handler = err_handler; -} - - - diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/async_logger_impl.h b/fpga/thirdparty/spdlog/include/spdlog/details/async_logger_impl.h deleted file mode 100644 index 837321176..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/async_logger_impl.h +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// Async Logger implementation -// Use an async_sink (queue per logger) to perform the logging in a worker thread - -#include "../details/async_log_helper.h" -#include "../async_logger.h" - -#include -#include -#include -#include - -template -inline spdlog::async_logger::async_logger(const std::string& logger_name, - const It& begin, - const It& end, - size_t queue_size, - const async_overflow_policy overflow_policy, - const std::function& worker_warmup_cb, - const std::chrono::milliseconds& flush_interval_ms, - const std::function& worker_teardown_cb) : - logger(logger_name, begin, end), - _async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size, _err_handler, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb)) -{ -} - -inline spdlog::async_logger::async_logger(const std::string& logger_name, - sinks_init_list sinks_list, - size_t queue_size, - const async_overflow_policy overflow_policy, - const std::function& worker_warmup_cb, - const std::chrono::milliseconds& flush_interval_ms, - const std::function& worker_teardown_cb) : - async_logger(logger_name, sinks_list.begin(), sinks_list.end(), queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb) {} - -inline spdlog::async_logger::async_logger(const std::string& logger_name, - sink_ptr single_sink, - size_t queue_size, - const async_overflow_policy overflow_policy, - const std::function& worker_warmup_cb, - const std::chrono::milliseconds& flush_interval_ms, - const std::function& worker_teardown_cb) : - async_logger(logger_name, -{ - single_sink -}, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb) {} - - -inline void spdlog::async_logger::flush() -{ - _async_log_helper->flush(true); -} - -// Error handler -inline void spdlog::async_logger::set_error_handler(spdlog::log_err_handler err_handler) -{ - _err_handler = err_handler; - _async_log_helper->set_error_handler(err_handler); - -} -inline spdlog::log_err_handler spdlog::async_logger::error_handler() -{ - return _err_handler; -} - - -inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter) -{ - _formatter = msg_formatter; - _async_log_helper->set_formatter(_formatter); -} - -inline void spdlog::async_logger::_set_pattern(const std::string& pattern, pattern_time_type pattern_time) -{ - _formatter = std::make_shared(pattern, pattern_time); - _async_log_helper->set_formatter(_formatter); -} - - -inline void spdlog::async_logger::_sink_it(details::log_msg& msg) -{ - try - { -#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER) - _incr_msg_counter(msg); -#endif - _async_log_helper->log(msg); - if (_should_flush_on(msg)) - _async_log_helper->flush(false); // do async flush - } - catch (const std::exception &ex) - { - _err_handler(ex.what()); - } - catch(...) - { - _err_handler("Unknown exception in logger " + _name); - throw; - } - -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/file_helper.h b/fpga/thirdparty/spdlog/include/spdlog/details/file_helper.h deleted file mode 100644 index 72fc09365..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/file_helper.h +++ /dev/null @@ -1,145 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// Helper class for file sink -// When failing to open a file, retry several times(5) with small delay between the tries(10 ms) -// Throw spdlog_ex exception on errors - -#include "../details/os.h" -#include "../details/log_msg.h" - -#include -#include -#include -#include -#include -#include - -namespace spdlog -{ -namespace details -{ - -class file_helper -{ - -public: - const int open_tries = 5; - const int open_interval = 10; - - explicit file_helper() : - _fd(nullptr) - {} - - file_helper(const file_helper&) = delete; - file_helper& operator=(const file_helper&) = delete; - - ~file_helper() - { - close(); - } - - - void open(const filename_t& fname, bool truncate = false) - { - - close(); - auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab"); - _filename = fname; - for (int tries = 0; tries < open_tries; ++tries) - { - if (!os::fopen_s(&_fd, fname, mode)) - return; - - std::this_thread::sleep_for(std::chrono::milliseconds(open_interval)); - } - - throw spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno); - } - - void reopen(bool truncate) - { - if (_filename.empty()) - throw spdlog_ex("Failed re opening file - was not opened before"); - open(_filename, truncate); - - } - - void flush() - { - std::fflush(_fd); - } - - void close() - { - if (_fd) - { - std::fclose(_fd); - _fd = nullptr; - } - } - - void write(const log_msg& msg) - { - size_t msg_size = msg.formatted.size(); - auto data = msg.formatted.data(); - if (std::fwrite(data, 1, msg_size, _fd) != msg_size) - throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno); - } - - size_t size() const - { - if (!_fd) - throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename)); - return os::filesize(_fd); - } - - const filename_t& filename() const - { - return _filename; - } - - static bool file_exists(const filename_t& fname) - { - return os::file_exists(fname); - } - - // - // return file path and its extension: - // - // "mylog.txt" => ("mylog", ".txt") - // "mylog" => ("mylog", "") - // "mylog." => ("mylog.", "") - // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt") - // - // the starting dot in filenames is ignored (hidden files): - // - // ".mylog" => (".mylog". "") - // "my_folder/.mylog" => ("my_folder/.mylog", "") - // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt") - static std::tuple split_by_extenstion(const spdlog::filename_t& fname) - { - auto ext_index = fname.rfind('.'); - - // no valid extension found - return whole path and empty string as extension - if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1) - return std::make_tuple(fname, spdlog::filename_t()); - - // treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile" - auto folder_index = fname.rfind(details::os::folder_sep); - if (folder_index != fname.npos && folder_index >= ext_index - 1) - return std::make_tuple(fname, spdlog::filename_t()); - - // finally - return a valid base and extension tuple - return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index)); - } -private: - FILE* _fd; - filename_t _filename; -}; -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/log_msg.h b/fpga/thirdparty/spdlog/include/spdlog/details/log_msg.h deleted file mode 100644 index a9fe92011..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/log_msg.h +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "../common.h" -#include "../details/os.h" - - -#include -#include - -namespace spdlog -{ -namespace details -{ -struct log_msg -{ - log_msg() = default; - log_msg(const std::string *loggers_name, level::level_enum lvl) : - logger_name(loggers_name), - level(lvl), - msg_id(0) - { -#ifndef SPDLOG_NO_DATETIME - time = os::now(); -#endif - -#ifndef SPDLOG_NO_THREAD_ID - thread_id = os::thread_id(); -#endif - } - - log_msg(const log_msg& other) = delete; - log_msg& operator=(log_msg&& other) = delete; - log_msg(log_msg&& other) = delete; - - - const std::string *logger_name; - level::level_enum level; - log_clock::time_point time; - size_t thread_id; - fmt::MemoryWriter raw; - fmt::MemoryWriter formatted; - size_t msg_id; -}; -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/logger_impl.h b/fpga/thirdparty/spdlog/include/spdlog/details/logger_impl.h deleted file mode 100644 index 880447471..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/logger_impl.h +++ /dev/null @@ -1,373 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "../logger.h" -#include "../sinks/stdout_sinks.h" - -#include -#include - -// create logger with given name, sinks and the default pattern formatter -// all other ctors will call this one -template -inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end): - _name(logger_name), - _sinks(begin, end), - _formatter(std::make_shared("%+")), - _level(level::info), - _flush_level(level::off), - _last_err_time(0), - _msg_counter(1) // message counter will start from 1. 0-message id will be reserved for controll messages -{ - _err_handler = [this](const std::string &msg) - { - this->_default_err_handler(msg); - }; -} - -// ctor with sinks as init list -inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list): - logger(logger_name, sinks_list.begin(), sinks_list.end()) -{} - - -// ctor with single sink -inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink): - logger(logger_name, -{ - single_sink -}) -{} - - -inline spdlog::logger::~logger() = default; - - -inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter) -{ - _set_formatter(msg_formatter); -} - -inline void spdlog::logger::set_pattern(const std::string& pattern, pattern_time_type pattern_time) -{ - _set_pattern(pattern, pattern_time); -} - -template -inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Args&... args) -{ - if (!should_log(lvl)) return; - - try - { - details::log_msg log_msg(&_name, lvl); - -#if defined(SPDLOG_FMT_PRINTF) - fmt::printf(log_msg.raw, fmt, args...); -#else - log_msg.raw.write(fmt, args...); -#endif - _sink_it(log_msg); - } - catch (const std::exception &ex) - { - _err_handler(ex.what()); - } - catch(...) - { - _err_handler("Unknown exception in logger " + _name); - throw; - } -} - -template -inline void spdlog::logger::log(level::level_enum lvl, const char* msg) -{ - if (!should_log(lvl)) return; - try - { - details::log_msg log_msg(&_name, lvl); - log_msg.raw << msg; - _sink_it(log_msg); - } - catch (const std::exception &ex) - { - _err_handler(ex.what()); - } - catch (...) - { - _err_handler("Unknown exception in logger " + _name); - throw; - } -} - -template -inline void spdlog::logger::log(level::level_enum lvl, const T& msg) -{ - if (!should_log(lvl)) return; - try - { - details::log_msg log_msg(&_name, lvl); - log_msg.raw << msg; - _sink_it(log_msg); - } - catch (const std::exception &ex) - { - _err_handler(ex.what()); - } - catch (...) - { - _err_handler("Unknown exception in logger " + _name); - throw; - } -} - - -template -inline void spdlog::logger::trace(const char* fmt, const Arg1 &arg1, const Args&... args) -{ - log(level::trace, fmt, arg1, args...); -} - -template -inline void spdlog::logger::debug(const char* fmt, const Arg1 &arg1, const Args&... args) -{ - log(level::debug, fmt, arg1, args...); -} - -template -inline void spdlog::logger::info(const char* fmt, const Arg1 &arg1, const Args&... args) -{ - log(level::info, fmt, arg1, args...); -} - -template -inline void spdlog::logger::warn(const char* fmt, const Arg1 &arg1, const Args&... args) -{ - log(level::warn, fmt, arg1, args...); -} - -template -inline void spdlog::logger::error(const char* fmt, const Arg1 &arg1, const Args&... args) -{ - log(level::err, fmt, arg1, args...); -} - -template -inline void spdlog::logger::critical(const char* fmt, const Arg1 &arg1, const Args&... args) -{ - log(level::critical, fmt, arg1, args...); -} - - -template -inline void spdlog::logger::trace(const T& msg) -{ - log(level::trace, msg); -} - -template -inline void spdlog::logger::debug(const T& msg) -{ - log(level::debug, msg); -} - - -template -inline void spdlog::logger::info(const T& msg) -{ - log(level::info, msg); -} - - -template -inline void spdlog::logger::warn(const T& msg) -{ - log(level::warn, msg); -} - -template -inline void spdlog::logger::error(const T& msg) -{ - log(level::err, msg); -} - -template -inline void spdlog::logger::critical(const T& msg) -{ - log(level::critical, msg); -} - - - -#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT -#include -#include - -template -inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* msg) -{ - std::wstring_convert > conv; - - log(lvl, conv.to_bytes(msg)); -} - -template -inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* fmt, const Args&... args) -{ - fmt::WMemoryWriter wWriter; - - wWriter.write(fmt, args...); - log(lvl, wWriter.c_str()); -} - -template -inline void spdlog::logger::trace(const wchar_t* fmt, const Args&... args) -{ - log(level::trace, fmt, args...); -} - -template -inline void spdlog::logger::debug(const wchar_t* fmt, const Args&... args) -{ - log(level::debug, fmt, args...); -} - -template -inline void spdlog::logger::info(const wchar_t* fmt, const Args&... args) -{ - log(level::info, fmt, args...); -} - - -template -inline void spdlog::logger::warn(const wchar_t* fmt, const Args&... args) -{ - log(level::warn, fmt, args...); -} - -template -inline void spdlog::logger::error(const wchar_t* fmt, const Args&... args) -{ - log(level::err, fmt, args...); -} - -template -inline void spdlog::logger::critical(const wchar_t* fmt, const Args&... args) -{ - log(level::critical, fmt, args...); -} - -#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT - - - -// -// name and level -// -inline const std::string& spdlog::logger::name() const -{ - return _name; -} - -inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) -{ - _level.store(log_level); -} - -inline void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler) -{ - _err_handler = err_handler; -} - -inline spdlog::log_err_handler spdlog::logger::error_handler() -{ - return _err_handler; -} - - -inline void spdlog::logger::flush_on(level::level_enum log_level) -{ - _flush_level.store(log_level); -} - -inline spdlog::level::level_enum spdlog::logger::level() const -{ - return static_cast(_level.load(std::memory_order_relaxed)); -} - -inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) const -{ - return msg_level >= _level.load(std::memory_order_relaxed); -} - -// -// protected virtual called at end of each user log call (if enabled) by the line_logger -// -inline void spdlog::logger::_sink_it(details::log_msg& msg) -{ -#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER) - _incr_msg_counter(msg); -#endif - _formatter->format(msg); - for (auto &sink : _sinks) - { - if( sink->should_log( msg.level)) - { - sink->log(msg); - } - } - - if(_should_flush_on(msg)) - flush(); -} - -inline void spdlog::logger::_set_pattern(const std::string& pattern, pattern_time_type pattern_time) -{ - _formatter = std::make_shared(pattern, pattern_time); -} -inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter) -{ - _formatter = msg_formatter; -} - -inline void spdlog::logger::flush() -{ - for (auto& sink : _sinks) - sink->flush(); -} - -inline void spdlog::logger::_default_err_handler(const std::string &msg) -{ - auto now = time(nullptr); - if (now - _last_err_time < 60) - return; - auto tm_time = details::os::localtime(now); - char date_buf[100]; - std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time); - details::log_msg err_msg; - err_msg.formatted.write("[*** LOG ERROR ***] [{}] [{}] [{}]{}", name(), msg, date_buf, details::os::eol); - sinks::stderr_sink_mt::instance()->log(err_msg); - _last_err_time = now; -} - -inline bool spdlog::logger::_should_flush_on(const details::log_msg &msg) -{ - const auto flush_level = _flush_level.load(std::memory_order_relaxed); - return (msg.level >= flush_level) && (msg.level != level::off); -} - -inline void spdlog::logger::_incr_msg_counter(details::log_msg &msg) -{ - msg.msg_id = _msg_counter.fetch_add(1, std::memory_order_relaxed); -} - -inline const std::vector& spdlog::logger::sinks() const -{ - return _sinks; -} - diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/mpmc_bounded_q.h b/fpga/thirdparty/spdlog/include/spdlog/details/mpmc_bounded_q.h deleted file mode 100644 index 102df8555..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/mpmc_bounded_q.h +++ /dev/null @@ -1,176 +0,0 @@ -/* -A modified version of Bounded MPMC queue by Dmitry Vyukov. - -Original code from: -http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue - -licensed by Dmitry Vyukov under the terms below: - -Simplified BSD license - -Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this list of -conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list -of conditions and the following disclaimer in the documentation and/or other materials -provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those of the authors and -should not be interpreted as representing official policies, either expressed or implied, of Dmitry Vyukov. -*/ - -/* -The code in its current form adds the license below: - -Copyright(c) 2015 Gabi Melman. -Distributed under the MIT License (http://opensource.org/licenses/MIT) - -*/ - -#pragma once - -#include "../common.h" - -#include -#include - -namespace spdlog -{ -namespace details -{ - -template -class mpmc_bounded_queue -{ -public: - - using item_type = T; - mpmc_bounded_queue(size_t buffer_size) - :max_size_(buffer_size), - buffer_(new cell_t[buffer_size]), - buffer_mask_(buffer_size - 1) - { - //queue size must be power of two - if (!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0))) - throw spdlog_ex("async logger queue size must be power of two"); - - for (size_t i = 0; i != buffer_size; i += 1) - buffer_[i].sequence_.store(i, std::memory_order_relaxed); - enqueue_pos_.store(0, std::memory_order_relaxed); - dequeue_pos_.store(0, std::memory_order_relaxed); - } - - ~mpmc_bounded_queue() - { - delete[] buffer_; - } - - - bool enqueue(T&& data) - { - cell_t* cell; - size_t pos = enqueue_pos_.load(std::memory_order_relaxed); - for (;;) - { - cell = &buffer_[pos & buffer_mask_]; - size_t seq = cell->sequence_.load(std::memory_order_acquire); - intptr_t dif = static_cast(seq) - static_cast(pos); - if (dif == 0) - { - if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) - break; - } - else if (dif < 0) - { - return false; - } - else - { - pos = enqueue_pos_.load(std::memory_order_relaxed); - } - } - cell->data_ = std::move(data); - cell->sequence_.store(pos + 1, std::memory_order_release); - return true; - } - - bool dequeue(T& data) - { - cell_t* cell; - size_t pos = dequeue_pos_.load(std::memory_order_relaxed); - for (;;) - { - cell = &buffer_[pos & buffer_mask_]; - size_t seq = - cell->sequence_.load(std::memory_order_acquire); - intptr_t dif = static_cast(seq) - static_cast(pos + 1); - if (dif == 0) - { - if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) - break; - } - else if (dif < 0) - return false; - else - pos = dequeue_pos_.load(std::memory_order_relaxed); - } - data = std::move(cell->data_); - cell->sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release); - return true; - } - - bool is_empty() - { - size_t front, front1, back; - // try to take a consistent snapshot of front/tail. - do - { - front = enqueue_pos_.load(std::memory_order_acquire); - back = dequeue_pos_.load(std::memory_order_acquire); - front1 = enqueue_pos_.load(std::memory_order_relaxed); - } - while (front != front1); - return back == front; - } - -private: - struct cell_t - { - std::atomic sequence_; - T data_; - }; - - size_t const max_size_; - - static size_t const cacheline_size = 64; - typedef char cacheline_pad_t[cacheline_size]; - - cacheline_pad_t pad0_; - cell_t* const buffer_; - size_t const buffer_mask_; - cacheline_pad_t pad1_; - std::atomic enqueue_pos_; - cacheline_pad_t pad2_; - std::atomic dequeue_pos_; - cacheline_pad_t pad3_; - - mpmc_bounded_queue(mpmc_bounded_queue const&) = delete; - void operator= (mpmc_bounded_queue const&) = delete; -}; - -} // ns details -} // ns spdlog diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/null_mutex.h b/fpga/thirdparty/spdlog/include/spdlog/details/null_mutex.h deleted file mode 100644 index 67b0aeee0..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/null_mutex.h +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include -// null, no cost dummy "mutex" and dummy "atomic" int - -namespace spdlog -{ -namespace details -{ -struct null_mutex -{ - void lock() {} - void unlock() {} - bool try_lock() - { - return true; - } -}; - -struct null_atomic_int -{ - int value; - null_atomic_int() = default; - - null_atomic_int(int val):value(val) - {} - - int load(std::memory_order) const - { - return value; - } - - void store(int val) - { - value = val; - } -}; - -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/os.h b/fpga/thirdparty/spdlog/include/spdlog/details/os.h deleted file mode 100644 index aaf949ee9..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/os.h +++ /dev/null @@ -1,479 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// -#pragma once - -#include "../common.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 - -#ifndef NOMINMAX -#define NOMINMAX //prevent windows redefining min/max -#endif - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include // _get_pid support -#include // _get_osfhandle and _isatty support - -#ifdef __MINGW32__ -#include -#endif - -#else // unix - -#include -#include - -#ifdef __linux__ -#include //Use gettid() syscall under linux to get thread id - -#elif __FreeBSD__ -#include //Use thr_self() syscall under FreeBSD to get thread id -#endif - -#endif //unix - -#ifndef __has_feature // Clang - feature checking macros. -#define __has_feature(x) 0 // Compatibility with non-clang compilers. -#endif - - -namespace spdlog -{ -namespace details -{ -namespace os -{ - -inline spdlog::log_clock::time_point now() -{ - -#if defined __linux__ && defined SPDLOG_CLOCK_COARSE - timespec ts; - ::clock_gettime(CLOCK_REALTIME_COARSE, &ts); - return std::chrono::time_point( - std::chrono::duration_cast( - std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec))); - - -#else - return log_clock::now(); -#endif - -} -inline std::tm localtime(const std::time_t &time_tt) -{ - -#ifdef _WIN32 - std::tm tm; - localtime_s(&tm, &time_tt); -#else - std::tm tm; - localtime_r(&time_tt, &tm); -#endif - return tm; -} - -inline std::tm localtime() -{ - std::time_t now_t = time(nullptr); - return localtime(now_t); -} - - -inline std::tm gmtime(const std::time_t &time_tt) -{ - -#ifdef _WIN32 - std::tm tm; - gmtime_s(&tm, &time_tt); -#else - std::tm tm; - gmtime_r(&time_tt, &tm); -#endif - return tm; -} - -inline std::tm gmtime() -{ - std::time_t now_t = time(nullptr); - return gmtime(now_t); -} -inline bool operator==(const std::tm& tm1, const std::tm& tm2) -{ - return (tm1.tm_sec == tm2.tm_sec && - tm1.tm_min == tm2.tm_min && - tm1.tm_hour == tm2.tm_hour && - tm1.tm_mday == tm2.tm_mday && - tm1.tm_mon == tm2.tm_mon && - tm1.tm_year == tm2.tm_year && - tm1.tm_isdst == tm2.tm_isdst); -} - -inline bool operator!=(const std::tm& tm1, const std::tm& tm2) -{ - return !(tm1 == tm2); -} - -// eol definition -#if !defined (SPDLOG_EOL) -#ifdef _WIN32 -#define SPDLOG_EOL "\r\n" -#else -#define SPDLOG_EOL "\n" -#endif -#endif - -SPDLOG_CONSTEXPR static const char* eol = SPDLOG_EOL; -SPDLOG_CONSTEXPR static int eol_size = sizeof(SPDLOG_EOL) - 1; - - - -// folder separator -#ifdef _WIN32 -SPDLOG_CONSTEXPR static const char folder_sep = '\\'; -#else -SPDLOG_CONSTEXPR static const char folder_sep = '/'; -#endif - - -inline void prevent_child_fd(FILE *f) -{ -#ifdef _WIN32 - auto file_handle = (HANDLE)_get_osfhandle(_fileno(f)); - if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0)) - throw spdlog_ex("SetHandleInformation failed", errno); -#else - auto fd = fileno(f); - if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) - throw spdlog_ex("fcntl with FD_CLOEXEC failed", errno); -#endif -} - - -//fopen_s on non windows for writing -inline int fopen_s(FILE** fp, const filename_t& filename, const filename_t& mode) -{ -#ifdef _WIN32 -#ifdef SPDLOG_WCHAR_FILENAMES - *fp = _wfsopen((filename.c_str()), mode.c_str(), _SH_DENYWR); -#else - *fp = _fsopen((filename.c_str()), mode.c_str(), _SH_DENYWR); -#endif -#else //unix - *fp = fopen((filename.c_str()), mode.c_str()); -#endif - -#ifdef SPDLOG_PREVENT_CHILD_FD - if (*fp != nullptr) - prevent_child_fd(*fp); -#endif - return *fp == nullptr; -} - - -inline int remove(const filename_t &filename) -{ -#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) - return _wremove(filename.c_str()); -#else - return std::remove(filename.c_str()); -#endif -} - -inline int rename(const filename_t& filename1, const filename_t& filename2) -{ -#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) - return _wrename(filename1.c_str(), filename2.c_str()); -#else - return std::rename(filename1.c_str(), filename2.c_str()); -#endif -} - - -//Return if file exists -inline bool file_exists(const filename_t& filename) -{ -#ifdef _WIN32 -#ifdef SPDLOG_WCHAR_FILENAMES - auto attribs = GetFileAttributesW(filename.c_str()); -#else - auto attribs = GetFileAttributesA(filename.c_str()); -#endif - return (attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY)); -#else //common linux/unix all have the stat system call - struct stat buffer; - return (stat(filename.c_str(), &buffer) == 0); -#endif -} - - - - -//Return file size according to open FILE* object -inline size_t filesize(FILE *f) -{ - if (f == nullptr) - throw spdlog_ex("Failed getting file size. fd is null"); -#if defined ( _WIN32) && !defined(__CYGWIN__) - int fd = _fileno(f); -#if _WIN64 //64 bits - struct _stat64 st; - if (_fstat64(fd, &st) == 0) - return st.st_size; - -#else //windows 32 bits - long ret = _filelength(fd); - if (ret >= 0) - return static_cast(ret); -#endif - -#else // unix - int fd = fileno(f); - //64 bits(but not in osx or cygwin, where fstat64 is deprecated) -#if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__)) && !defined(__CYGWIN__) - struct stat64 st; - if (fstat64(fd, &st) == 0) - return static_cast(st.st_size); -#else // unix 32 bits or cygwin - struct stat st; - if (fstat(fd, &st) == 0) - return static_cast(st.st_size); -#endif -#endif - throw spdlog_ex("Failed getting file size from fd", errno); -} - - - - -//Return utc offset in minutes or throw spdlog_ex on failure -inline int utc_minutes_offset(const std::tm& tm = details::os::localtime()) -{ - -#ifdef _WIN32 -#if _WIN32_WINNT < _WIN32_WINNT_WS08 - TIME_ZONE_INFORMATION tzinfo; - auto rv = GetTimeZoneInformation(&tzinfo); -#else - DYNAMIC_TIME_ZONE_INFORMATION tzinfo; - auto rv = GetDynamicTimeZoneInformation(&tzinfo); -#endif - if (rv == TIME_ZONE_ID_INVALID) - throw spdlog::spdlog_ex("Failed getting timezone info. ", errno); - - int offset = -tzinfo.Bias; - if (tm.tm_isdst) - offset -= tzinfo.DaylightBias; - else - offset -= tzinfo.StandardBias; - return offset; -#else - -#if defined(sun) || defined(__sun) - // 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris - struct helper - { - static long int calculate_gmt_offset(const std::tm & localtm = details::os::localtime(), const std::tm & gmtm = details::os::gmtime()) - { - int local_year = localtm.tm_year + (1900 - 1); - int gmt_year = gmtm.tm_year + (1900 - 1); - - long int days = ( - // difference in day of year - localtm.tm_yday - gmtm.tm_yday - - // + intervening leap days - + ((local_year >> 2) - (gmt_year >> 2)) - - (local_year / 100 - gmt_year / 100) - + ((local_year / 100 >> 2) - (gmt_year / 100 >> 2)) - - // + difference in years * 365 */ - + (long int)(local_year - gmt_year) * 365 - ); - - long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour); - long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min); - long int secs = (60 * mins) + (localtm.tm_sec - gmtm.tm_sec); - - return secs; - } - }; - - long int offset_seconds = helper::calculate_gmt_offset(tm); -#else - long int offset_seconds = tm.tm_gmtoff; -#endif - - return static_cast(offset_seconds / 60); -#endif -} - -//Return current thread id as size_t -//It exists because the std::this_thread::get_id() is much slower(especially under VS 2013) -inline size_t _thread_id() -{ -#ifdef _WIN32 - return static_cast(::GetCurrentThreadId()); -#elif __linux__ -# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21) -# define SYS_gettid __NR_gettid -# endif - return static_cast(syscall(SYS_gettid)); -#elif __FreeBSD__ - long tid; - thr_self(&tid); - return static_cast(tid); -#elif __APPLE__ - uint64_t tid; - pthread_threadid_np(nullptr, &tid); - return static_cast(tid); -#else //Default to standard C++11 (other Unix) - return static_cast(std::hash()(std::this_thread::get_id())); -#endif -} - -//Return current thread id as size_t (from thread local storage) -inline size_t thread_id() -{ -#if defined(SPDLOG_DISABLE_TID_CACHING) || (defined(_MSC_VER) && (_MSC_VER < 1900)) || (defined(__clang__) && !__has_feature(cxx_thread_local)) - return _thread_id(); -#else // cache thread id in tls - static thread_local const size_t tid = _thread_id(); - return tid; -#endif - - -} - - -// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined) -#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) -#define SPDLOG_FILENAME_T(s) L ## s -inline std::string filename_to_str(const filename_t& filename) -{ - std::wstring_convert, wchar_t> c; - return c.to_bytes(filename); -} -#else -#define SPDLOG_FILENAME_T(s) s -inline std::string filename_to_str(const filename_t& filename) -{ - return filename; -} -#endif - -inline std::string errno_to_string(char[256], char* res) -{ - return std::string(res); -} - -inline std::string errno_to_string(char buf[256], int res) -{ - if (res == 0) - { - return std::string(buf); - } - else - { - return "Unknown error"; - } -} - -// Return errno string (thread safe) -inline std::string errno_str(int err_num) -{ - char buf[256]; - SPDLOG_CONSTEXPR auto buf_size = sizeof(buf); - -#ifdef _WIN32 - if (strerror_s(buf, buf_size, err_num) == 0) - return std::string(buf); - else - return "Unknown error"; - -#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(ANDROID) || defined(__SUNPRO_CC) || \ - ((_POSIX_C_SOURCE >= 200112L) && ! defined(_GNU_SOURCE)) // posix version - - if (strerror_r(err_num, buf, buf_size) == 0) - return std::string(buf); - else - return "Unknown error"; - -#else // gnu version (might not use the given buf, so its retval pointer must be used) - auto err = strerror_r(err_num, buf, buf_size); // let compiler choose type - return errno_to_string(buf, err); // use overloading to select correct stringify function -#endif -} - -inline int pid() -{ - -#ifdef _WIN32 - return ::_getpid(); -#else - return static_cast(::getpid()); -#endif - -} - - -// Determine if the terminal supports colors -// Source: https://github.com/agauniyal/rang/ -inline bool is_color_terminal() -{ -#ifdef _WIN32 - return true; -#else - static constexpr const char* Terms[] = - { - "ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", - "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm" - }; - - const char *env_p = std::getenv("TERM"); - if (env_p == nullptr) - { - return false; - } - - static const bool result = std::any_of( - std::begin(Terms), std::end(Terms), [&](const char* term) - { - return std::strstr(env_p, term) != nullptr; - }); - return result; -#endif -} - - -// Detrmine if the terminal attached -// Source: https://github.com/agauniyal/rang/ -inline bool in_terminal(FILE* file) -{ - -#ifdef _WIN32 - return _isatty(_fileno(file)) ? true : false; -#else - return isatty(fileno(file)) ? true : false; -#endif -} -} //os -} //details -} //spdlog diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/pattern_formatter_impl.h b/fpga/thirdparty/spdlog/include/spdlog/details/pattern_formatter_impl.h deleted file mode 100644 index 6457d1034..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/pattern_formatter_impl.h +++ /dev/null @@ -1,699 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "../formatter.h" -#include "../details/log_msg.h" -#include "../details/os.h" -#include "../fmt/fmt.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace spdlog -{ -namespace details -{ -class flag_formatter -{ -public: - virtual ~flag_formatter() - {} - virtual void format(details::log_msg& msg, const std::tm& tm_time) = 0; -}; - -/////////////////////////////////////////////////////////////////////// -// name & level pattern appenders -/////////////////////////////////////////////////////////////////////// -namespace -{ -class name_formatter:public flag_formatter -{ - std::string center(std::string input, int width) { - const int whitespace = std::max(int(width - input.length()), 0); - return std::string(whitespace / 2, ' ') - + input - + std::string(whitespace / 2, ' ') - + ((whitespace % 2 == 0) ? "" : " "); - } - - void format(details::log_msg& msg, const std::tm&) override - { -#ifdef SPDLOG_NAME_WIDTH - msg.formatted << center(*msg.logger_name, SPDLOG_NAME_WIDTH); -#else - msg.formatted << *msg.logger_name; -#endif - } -}; -} - -// log level appender -class level_formatter:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << level::to_str(msg.level); - } -}; - -// short log level appender -class short_level_formatter:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << level::to_short_str(msg.level); - } -}; - -/////////////////////////////////////////////////////////////////////// -// Date time pattern appenders -/////////////////////////////////////////////////////////////////////// - -static const char* ampm(const tm& t) -{ - return t.tm_hour >= 12 ? "PM" : "AM"; -} - -static int to12h(const tm& t) -{ - return t.tm_hour > 12 ? t.tm_hour - 12 : t.tm_hour; -} - -//Abbreviated weekday name -static const std::string days[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -class a_formatter:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << days[tm_time.tm_wday]; - } -}; - -//Full weekday name -static const std::string full_days[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; -class A_formatter:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << full_days[tm_time.tm_wday]; - } -}; - -//Abbreviated month -static const std::string months[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" }; -class b_formatter:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << months[tm_time.tm_mon]; - } -}; - -//Full month name -static const std::string full_months[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; -class B_formatter:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << full_months[tm_time.tm_mon]; - } -}; - - -//write 2 ints separated by sep with padding of 2 -static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, char sep) -{ - w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0'); - return w; -} - -//write 3 ints separated by sep with padding of 2 -static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, int v3, char sep) -{ - w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0') << sep << fmt::pad(v3, 2, '0'); - return w; -} - - -//Date and time representation (Thu Aug 23 15:35:46 2014) -class c_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << days[tm_time.tm_wday] << ' ' << months[tm_time.tm_mon] << ' ' << tm_time.tm_mday << ' '; - pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << tm_time.tm_year + 1900; - } -}; - - -// year - 2 digit -class C_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_year % 100, 2, '0'); - } -}; - - - -// Short MM/DD/YY date, equivalent to %m/%d/%y 08/23/01 -class D_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_year % 100, '/'); - } -}; - - -// year - 4 digit -class Y_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << tm_time.tm_year + 1900; - } -}; - -// month 1-12 -class m_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_mon + 1, 2, '0'); - } -}; - -// day of month 1-31 -class d_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_mday, 2, '0'); - } -}; - -// hours in 24 format 0-23 -class H_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_hour, 2, '0'); - } -}; - -// hours in 12 format 1-12 -class I_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(to12h(tm_time), 2, '0'); - } -}; - -// minutes 0-59 -class M_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_min, 2, '0'); - } -}; - -// seconds 0-59 -class S_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_sec, 2, '0'); - } -}; - -// milliseconds -class e_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - auto duration = msg.time.time_since_epoch(); - auto millis = std::chrono::duration_cast(duration).count() % 1000; - msg.formatted << fmt::pad(static_cast(millis), 3, '0'); - } -}; - -// microseconds -class f_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - auto duration = msg.time.time_since_epoch(); - auto micros = std::chrono::duration_cast(duration).count() % 1000000; - msg.formatted << fmt::pad(static_cast(micros), 6, '0'); - } -}; - -// nanoseconds -class F_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - auto duration = msg.time.time_since_epoch(); - auto ns = std::chrono::duration_cast(duration).count() % 1000000000; - msg.formatted << fmt::pad(static_cast(ns), 9, '0'); - } -}; - -class E_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - auto duration = msg.time.time_since_epoch(); - auto seconds = std::chrono::duration_cast(duration).count(); - msg.formatted << seconds; - } -}; - -// AM/PM -class p_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << ampm(tm_time); - } -}; - - -// 12 hour clock 02:55:02 pm -class r_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, to12h(tm_time), tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << ampm(tm_time); - } -}; - -// 24-hour HH:MM time, equivalent to %H:%M -class R_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, ':'); - } -}; - -// ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S -class T_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':'); - } -}; - -// ISO 8601 offset from UTC in timezone (+-HH:MM) -class z_formatter SPDLOG_FINAL:public flag_formatter -{ -public: - const std::chrono::seconds cache_refresh = std::chrono::seconds(5); - - z_formatter():_last_update(std::chrono::seconds(0)), _offset_minutes(0) - {} - z_formatter(const z_formatter&) = delete; - z_formatter& operator=(const z_formatter&) = delete; - - void format(details::log_msg& msg, const std::tm& tm_time) override - { -#ifdef _WIN32 - int total_minutes = get_cached_offset(msg, tm_time); -#else - // No need to chache under gcc, - // it is very fast (already stored in tm.tm_gmtoff) - int total_minutes = os::utc_minutes_offset(tm_time); -#endif - bool is_negative = total_minutes < 0; - char sign; - if (is_negative) - { - total_minutes = -total_minutes; - sign = '-'; - } - else - { - sign = '+'; - } - - int h = total_minutes / 60; - int m = total_minutes % 60; - msg.formatted << sign; - pad_n_join(msg.formatted, h, m, ':'); - } -private: - log_clock::time_point _last_update; - int _offset_minutes; - std::mutex _mutex; - - int get_cached_offset(const log_msg& msg, const std::tm& tm_time) - { - using namespace std::chrono; - std::lock_guard l(_mutex); - if (msg.time - _last_update >= cache_refresh) - { - _offset_minutes = os::utc_minutes_offset(tm_time); - _last_update = msg.time; - } - return _offset_minutes; - } -}; - - - -// Thread id -class t_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << msg.thread_id; - } -}; - -// Current pid -class pid_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << details::os::pid(); - } -}; - -// message counter formatter -class i_formatter SPDLOG_FINAL :public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << fmt::pad(msg.msg_id, 6, '0'); - } -}; - -class v_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size()); - } -}; - -class ch_formatter SPDLOG_FINAL:public flag_formatter -{ -public: - explicit ch_formatter(char ch): _ch(ch) - {} - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << _ch; - } -private: - char _ch; -}; - - -//aggregate user chars to display as is -class aggregate_formatter SPDLOG_FINAL:public flag_formatter -{ -public: - aggregate_formatter() - {} - void add_ch(char ch) - { - _str += ch; - } - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << _str; - } -private: - std::string _str; -}; - -// Full info formatter -// pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v -class full_formatter SPDLOG_FINAL:public flag_formatter -{ - void format(details::log_msg& msg, const std::tm& tm_time) override - { -#ifndef SPDLOG_NO_DATETIME - auto duration = msg.time.time_since_epoch(); - auto millis = std::chrono::duration_cast(duration).count() % 1000; - - /* Slower version(while still very fast - about 3.2 million lines/sec under 10 threads), - msg.formatted.write("[{:d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}.{:03d}] [{}] [{}] {} ", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec, - static_cast(millis), - msg.logger_name, - level::to_str(msg.level), - msg.raw.str());*/ - - - // Faster (albeit uglier) way to format the line (5.6 million lines/sec under 10 threads) - msg.formatted << '[' << static_cast(tm_time.tm_year + 1900) << '-' - << fmt::pad(static_cast(tm_time.tm_mon + 1), 2, '0') << '-' - << fmt::pad(static_cast(tm_time.tm_mday), 2, '0') << ' ' - << fmt::pad(static_cast(tm_time.tm_hour), 2, '0') << ':' - << fmt::pad(static_cast(tm_time.tm_min), 2, '0') << ':' - << fmt::pad(static_cast(tm_time.tm_sec), 2, '0') << '.' - << fmt::pad(static_cast(millis), 3, '0') << "] "; - - //no datetime needed -#else - (void)tm_time; -#endif - -#ifndef SPDLOG_NO_NAME - msg.formatted << '[' << *msg.logger_name << "] "; -#endif - - msg.formatted << '[' << level::to_str(msg.level) << "] "; - msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size()); - } -}; - - - -} -} -/////////////////////////////////////////////////////////////////////////////// -// pattern_formatter inline impl -/////////////////////////////////////////////////////////////////////////////// -inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern, pattern_time_type pattern_time) - : _pattern_time(pattern_time) -{ - compile_pattern(pattern); -} - -inline void spdlog::pattern_formatter::compile_pattern(const std::string& pattern) -{ - auto end = pattern.end(); - std::unique_ptr user_chars; - for (auto it = pattern.begin(); it != end; ++it) - { - if (*it == '%') - { - if (user_chars) //append user chars found so far - _formatters.push_back(std::move(user_chars)); - - if (++it != end) - handle_flag(*it); - else - break; - } - else // chars not following the % sign should be displayed as is - { - if (!user_chars) - user_chars = std::unique_ptr(new details::aggregate_formatter()); - user_chars->add_ch(*it); - } - } - if (user_chars) //append raw chars found so far - { - _formatters.push_back(std::move(user_chars)); - } - -} -inline void spdlog::pattern_formatter::handle_flag(char flag) -{ - switch (flag) - { - // logger name - case 'n': - _formatters.push_back(std::unique_ptr(new details::name_formatter())); - break; - - case 'l': - _formatters.push_back(std::unique_ptr(new details::level_formatter())); - break; - - case 'L': - _formatters.push_back(std::unique_ptr(new details::short_level_formatter())); - break; - - case('t'): - _formatters.push_back(std::unique_ptr(new details::t_formatter())); - break; - - case('v'): - _formatters.push_back(std::unique_ptr(new details::v_formatter())); - break; - - case('a'): - _formatters.push_back(std::unique_ptr(new details::a_formatter())); - break; - - case('A'): - _formatters.push_back(std::unique_ptr(new details::A_formatter())); - break; - - case('b'): - case('h'): - _formatters.push_back(std::unique_ptr(new details::b_formatter())); - break; - - case('B'): - _formatters.push_back(std::unique_ptr(new details::B_formatter())); - break; - case('c'): - _formatters.push_back(std::unique_ptr(new details::c_formatter())); - break; - - case('C'): - _formatters.push_back(std::unique_ptr(new details::C_formatter())); - break; - - case('Y'): - _formatters.push_back(std::unique_ptr(new details::Y_formatter())); - break; - - case('D'): - case('x'): - - _formatters.push_back(std::unique_ptr(new details::D_formatter())); - break; - - case('m'): - _formatters.push_back(std::unique_ptr(new details::m_formatter())); - break; - - case('d'): - _formatters.push_back(std::unique_ptr(new details::d_formatter())); - break; - - case('H'): - _formatters.push_back(std::unique_ptr(new details::H_formatter())); - break; - - case('I'): - _formatters.push_back(std::unique_ptr(new details::I_formatter())); - break; - - case('M'): - _formatters.push_back(std::unique_ptr(new details::M_formatter())); - break; - - case('S'): - _formatters.push_back(std::unique_ptr(new details::S_formatter())); - break; - - case('e'): - _formatters.push_back(std::unique_ptr(new details::e_formatter())); - break; - - case('f'): - _formatters.push_back(std::unique_ptr(new details::f_formatter())); - break; - case('F'): - _formatters.push_back(std::unique_ptr(new details::F_formatter())); - break; - - case('E'): - _formatters.push_back(std::unique_ptr(new details::E_formatter())); - break; - - case('p'): - _formatters.push_back(std::unique_ptr(new details::p_formatter())); - break; - - case('r'): - _formatters.push_back(std::unique_ptr(new details::r_formatter())); - break; - - case('R'): - _formatters.push_back(std::unique_ptr(new details::R_formatter())); - break; - - case('T'): - case('X'): - _formatters.push_back(std::unique_ptr(new details::T_formatter())); - break; - - case('z'): - _formatters.push_back(std::unique_ptr(new details::z_formatter())); - break; - - case ('+'): - _formatters.push_back(std::unique_ptr(new details::full_formatter())); - break; - - case ('P'): - _formatters.push_back(std::unique_ptr(new details::pid_formatter())); - break; - - - case ('i'): - _formatters.push_back(std::unique_ptr(new details::i_formatter())); - break; - - default: //Unknown flag appears as is - _formatters.push_back(std::unique_ptr(new details::ch_formatter('%'))); - _formatters.push_back(std::unique_ptr(new details::ch_formatter(flag))); - break; - } -} - -inline std::tm spdlog::pattern_formatter::get_time(details::log_msg& msg) -{ - if (_pattern_time == pattern_time_type::local) - return details::os::localtime(log_clock::to_time_t(msg.time)); - else - return details::os::gmtime(log_clock::to_time_t(msg.time)); -} - -inline void spdlog::pattern_formatter::format(details::log_msg& msg) -{ - -#ifndef SPDLOG_NO_DATETIME - auto tm_time = get_time(msg); -#else - std::tm tm_time; -#endif - for (auto &f : _formatters) - { - f->format(msg, tm_time); - } - //write eol - msg.formatted.write(details::os::eol, details::os::eol_size); -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/registry.h b/fpga/thirdparty/spdlog/include/spdlog/details/registry.h deleted file mode 100644 index b68b9f5a3..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/registry.h +++ /dev/null @@ -1,225 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// Loggers registy of unique name->logger pointer -// An attempt to create a logger with an already existing name will be ignored -// If user requests a non existing logger, nullptr will be returned -// This class is thread safe - -#include "../details/null_mutex.h" -#include "../logger.h" -#include "../async_logger.h" -#include "../common.h" - -#include -#include -#include -#include -#include -#include - -namespace spdlog -{ -namespace details -{ -template class registry_t -{ -public: - - void register_logger(std::shared_ptr logger) - { - std::lock_guard lock(_mutex); - auto logger_name = logger->name(); - throw_if_exists(logger_name); - _loggers[logger_name] = logger; - } - - - std::shared_ptr get(const std::string& logger_name) - { - std::lock_guard lock(_mutex); - auto found = _loggers.find(logger_name); - return found == _loggers.end() ? nullptr : found->second; - } - - template - std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) - { - std::lock_guard lock(_mutex); - throw_if_exists(logger_name); - std::shared_ptr new_logger; - if (_async_mode) - new_logger = std::make_shared(logger_name, sinks_begin, sinks_end, _async_q_size, _overflow_policy, _worker_warmup_cb, _flush_interval_ms, _worker_teardown_cb); - else - new_logger = std::make_shared(logger_name, sinks_begin, sinks_end); - - if (_formatter) - new_logger->set_formatter(_formatter); - - if (_err_handler) - new_logger->set_error_handler(_err_handler); - - new_logger->set_level(_level); - new_logger->flush_on(_flush_level); - - - //Add to registry - _loggers[logger_name] = new_logger; - return new_logger; - } - - template - std::shared_ptr create_async(const std::string& logger_name, size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb, const It& sinks_begin, const It& sinks_end) - { - std::lock_guard lock(_mutex); - throw_if_exists(logger_name); - auto new_logger = std::make_shared(logger_name, sinks_begin, sinks_end, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb); - - if (_formatter) - new_logger->set_formatter(_formatter); - - if (_err_handler) - new_logger->set_error_handler(_err_handler); - - new_logger->set_level(_level); - new_logger->flush_on(_flush_level); - - //Add to registry - _loggers[logger_name] = new_logger; - return new_logger; - } - - void apply_all(std::function)> fun) - { - std::lock_guard lock(_mutex); - for (auto &l : _loggers) - fun(l.second); - } - - void drop(const std::string& logger_name) - { - std::lock_guard lock(_mutex); - _loggers.erase(logger_name); - } - - void drop_all() - { - std::lock_guard lock(_mutex); - _loggers.clear(); - } - std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks) - { - return create(logger_name, sinks.begin(), sinks.end()); - } - - std::shared_ptr create(const std::string& logger_name, sink_ptr sink) - { - return create(logger_name, { sink }); - } - - std::shared_ptr create_async(const std::string& logger_name, size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb, sinks_init_list sinks) - { - return create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks.begin(), sinks.end()); - } - - std::shared_ptr create_async(const std::string& logger_name, size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb, sink_ptr sink) - { - return create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, { sink }); - } - - void formatter(formatter_ptr f) - { - std::lock_guard lock(_mutex); - _formatter = f; - for (auto& l : _loggers) - l.second->set_formatter(_formatter); - } - - void set_pattern(const std::string& pattern) - { - std::lock_guard lock(_mutex); - _formatter = std::make_shared(pattern); - for (auto& l : _loggers) - l.second->set_formatter(_formatter); - } - - void set_level(level::level_enum log_level) - { - std::lock_guard lock(_mutex); - for (auto& l : _loggers) - l.second->set_level(log_level); - _level = log_level; - } - - void flush_on(level::level_enum log_level) - { - std::lock_guard lock(_mutex); - for (auto& l : _loggers) - l.second->flush_on(log_level); - _flush_level = log_level; - } - - void set_error_handler(log_err_handler handler) - { - for (auto& l : _loggers) - l.second->set_error_handler(handler); - _err_handler = handler; - } - - void set_async_mode(size_t q_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb) - { - std::lock_guard lock(_mutex); - _async_mode = true; - _async_q_size = q_size; - _overflow_policy = overflow_policy; - _worker_warmup_cb = worker_warmup_cb; - _flush_interval_ms = flush_interval_ms; - _worker_teardown_cb = worker_teardown_cb; - } - - void set_sync_mode() - { - std::lock_guard lock(_mutex); - _async_mode = false; - } - - static registry_t& instance() - { - static registry_t s_instance; - return s_instance; - } - -private: - registry_t() {} - registry_t(const registry_t&) = delete; - registry_t& operator=(const registry_t&) = delete; - - void throw_if_exists(const std::string &logger_name) - { - if (_loggers.find(logger_name) != _loggers.end()) - throw spdlog_ex("logger with name '" + logger_name + "' already exists"); - } - Mutex _mutex; - std::unordered_map > _loggers; - formatter_ptr _formatter; - level::level_enum _level = level::info; - level::level_enum _flush_level = level::off; - log_err_handler _err_handler; - bool _async_mode = false; - size_t _async_q_size = 0; - async_overflow_policy _overflow_policy = async_overflow_policy::block_retry; - std::function _worker_warmup_cb = nullptr; - std::chrono::milliseconds _flush_interval_ms; - std::function _worker_teardown_cb = nullptr; -}; -#ifdef SPDLOG_NO_REGISTRY_MUTEX -typedef registry_t registry; -#else -typedef registry_t registry; -#endif -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/details/spdlog_impl.h b/fpga/thirdparty/spdlog/include/spdlog/details/spdlog_impl.h deleted file mode 100644 index 25c7b7e9a..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/details/spdlog_impl.h +++ /dev/null @@ -1,268 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// -// Global registry functions -// -#include "../spdlog.h" -#include "../details/registry.h" -#include "../sinks/file_sinks.h" -#include "../sinks/stdout_sinks.h" -#ifdef SPDLOG_ENABLE_SYSLOG -#include "../sinks/syslog_sink.h" -#endif - -#ifdef _WIN32 -#include "../sinks/wincolor_sink.h" -#else -#include "../sinks/ansicolor_sink.h" -#endif - - -#ifdef __ANDROID__ -#include "../sinks/android_sink.h" -#endif - -#include -#include -#include -#include - -inline void spdlog::register_logger(std::shared_ptr logger) -{ - return details::registry::instance().register_logger(logger); -} - -inline std::shared_ptr spdlog::get(const std::string& name) -{ - return details::registry::instance().get(name); -} - -inline void spdlog::drop(const std::string &name) -{ - details::registry::instance().drop(name); -} - -// Create multi/single threaded simple file logger -inline std::shared_ptr spdlog::basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate) -{ - return create(logger_name, filename, truncate); -} - -inline std::shared_ptr spdlog::basic_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate) -{ - return create(logger_name, filename, truncate); -} - -// Create multi/single threaded rotating file logger -inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files) -{ - return create(logger_name, filename, max_file_size, max_files); -} - -inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files) -{ - return create(logger_name, filename, max_file_size, max_files); -} - -// Create file logger which creates new file at midnight): -inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const filename_t& filename, int hour, int minute) -{ - return create(logger_name, filename, hour, minute); -} - -inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour, int minute) -{ - return create(logger_name, filename, hour, minute); -} - - -// -// stdout/stderr loggers -// -inline std::shared_ptr spdlog::stdout_logger_mt(const std::string& logger_name) -{ - return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance()); -} - -inline std::shared_ptr spdlog::stdout_logger_st(const std::string& logger_name) -{ - return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance()); -} - -inline std::shared_ptr spdlog::stderr_logger_mt(const std::string& logger_name) -{ - return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance()); -} - -inline std::shared_ptr spdlog::stderr_logger_st(const std::string& logger_name) -{ - return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance()); -} - -// -// stdout/stderr color loggers -// -#ifdef _WIN32 -inline std::shared_ptr spdlog::stdout_color_mt(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} - -inline std::shared_ptr spdlog::stdout_color_st(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} - -inline std::shared_ptr spdlog::stderr_color_mt(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} - - -inline std::shared_ptr spdlog::stderr_color_st(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} - -#else //ansi terminal colors - -inline std::shared_ptr spdlog::stdout_color_mt(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} - -inline std::shared_ptr spdlog::stdout_color_st(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} - -inline std::shared_ptr spdlog::stderr_color_mt(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} - -inline std::shared_ptr spdlog::stderr_color_st(const std::string& logger_name) -{ - auto sink = std::make_shared(); - return spdlog::details::registry::instance().create(logger_name, sink); -} -#endif - -#ifdef SPDLOG_ENABLE_SYSLOG -// Create syslog logger -inline std::shared_ptr spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option, int syslog_facility) -{ - return create(logger_name, syslog_ident, syslog_option, syslog_facility); -} -#endif - -#ifdef __ANDROID__ -inline std::shared_ptr spdlog::android_logger(const std::string& logger_name, const std::string& tag) -{ - return create(logger_name, tag); -} -#endif - -// Create and register a logger a single sink -inline std::shared_ptr spdlog::create(const std::string& logger_name, const spdlog::sink_ptr& sink) -{ - return details::registry::instance().create(logger_name, sink); -} - -//Create logger with multiple sinks - -inline std::shared_ptr spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) -{ - return details::registry::instance().create(logger_name, sinks); -} - - -template -inline std::shared_ptr spdlog::create(const std::string& logger_name, Args... args) -{ - sink_ptr sink = std::make_shared(args...); - return details::registry::instance().create(logger_name, { sink }); -} - - -template -inline std::shared_ptr spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) -{ - return details::registry::instance().create(logger_name, sinks_begin, sinks_end); -} - -// Create and register an async logger with a single sink -inline std::shared_ptr spdlog::create_async(const std::string& logger_name, const sink_ptr& sink, size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb) -{ - return details::registry::instance().create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sink); -} - -// Create and register an async logger with multiple sinks -inline std::shared_ptr spdlog::create_async(const std::string& logger_name, sinks_init_list sinks, size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb ) -{ - return details::registry::instance().create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks); -} - -template -inline std::shared_ptr spdlog::create_async(const std::string& logger_name, const It& sinks_begin, const It& sinks_end, size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb) -{ - return details::registry::instance().create_async(logger_name, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb, sinks_begin, sinks_end); -} - -inline void spdlog::set_formatter(spdlog::formatter_ptr f) -{ - details::registry::instance().formatter(f); -} - -inline void spdlog::set_pattern(const std::string& format_string) -{ - return details::registry::instance().set_pattern(format_string); -} - -inline void spdlog::set_level(level::level_enum log_level) -{ - return details::registry::instance().set_level(log_level); -} - -inline void spdlog::flush_on(level::level_enum log_level) -{ - return details::registry::instance().flush_on(log_level); -} - -inline void spdlog::set_error_handler(log_err_handler handler) -{ - return details::registry::instance().set_error_handler(handler); -} - - -inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function& worker_teardown_cb) -{ - details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb); -} - -inline void spdlog::set_sync_mode() -{ - details::registry::instance().set_sync_mode(); -} - -inline void spdlog::apply_all(std::function)> fun) -{ - details::registry::instance().apply_all(fun); -} - -inline void spdlog::drop_all() -{ - details::registry::instance().drop_all(); -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/LICENSE.rst b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/LICENSE.rst deleted file mode 100644 index eb6be6503..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/LICENSE.rst +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2012 - 2016, Victor Zverovich - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.cc b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.cc deleted file mode 100644 index 09d2ea9fd..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.cc +++ /dev/null @@ -1,535 +0,0 @@ -/* - Formatting library for C++ - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "format.h" - -#include - -#include -#include -#include -#include -#include -#include // for std::ptrdiff_t - -#if defined(_WIN32) && defined(__MINGW32__) -# include -#endif - -#if FMT_USE_WINDOWS_H -# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN) -# define WIN32_LEAN_AND_MEAN -# endif -# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX) -# include -# else -# define NOMINMAX -# include -# undef NOMINMAX -# endif -#endif - -#if FMT_EXCEPTIONS -# define FMT_TRY try -# define FMT_CATCH(x) catch (x) -#else -# define FMT_TRY if (true) -# define FMT_CATCH(x) if (false) -#endif - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4127) // conditional expression is constant -# pragma warning(disable: 4702) // unreachable code -// Disable deprecation warning for strerror. The latter is not called but -// MSVC fails to detect it. -# pragma warning(disable: 4996) -#endif - -// Dummy implementations of strerror_r and strerror_s called if corresponding -// system functions are not available. -static inline fmt::internal::Null<> strerror_r(int, char *, ...) { - return fmt::internal::Null<>(); -} -static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) { - return fmt::internal::Null<>(); -} - -namespace fmt { - -FMT_FUNC internal::RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {} -FMT_FUNC FormatError::~FormatError() FMT_DTOR_NOEXCEPT {} -FMT_FUNC SystemError::~SystemError() FMT_DTOR_NOEXCEPT {} - -namespace { - -#ifndef _MSC_VER -# define FMT_SNPRINTF snprintf -#else // _MSC_VER -inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) { - va_list args; - va_start(args, format); - int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args); - va_end(args); - return result; -} -# define FMT_SNPRINTF fmt_snprintf -#endif // _MSC_VER - -#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT) -# define FMT_SWPRINTF snwprintf -#else -# define FMT_SWPRINTF swprintf -#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT) - -const char RESET_COLOR[] = "\x1b[0m"; - -typedef void (*FormatFunc)(Writer &, int, StringRef); - -// Portable thread-safe version of strerror. -// Sets buffer to point to a string describing the error code. -// This can be either a pointer to a string stored in buffer, -// or a pointer to some static immutable string. -// Returns one of the following values: -// 0 - success -// ERANGE - buffer is not large enough to store the error message -// other - failure -// Buffer should be at least of size 1. -int safe_strerror( - int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT { - FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer"); - - class StrError { - private: - int error_code_; - char *&buffer_; - std::size_t buffer_size_; - - // A noop assignment operator to avoid bogus warnings. - void operator=(const StrError &) {} - - // Handle the result of XSI-compliant version of strerror_r. - int handle(int result) { - // glibc versions before 2.13 return result in errno. - return result == -1 ? errno : result; - } - - // Handle the result of GNU-specific version of strerror_r. - int handle(char *message) { - // If the buffer is full then the message is probably truncated. - if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1) - return ERANGE; - buffer_ = message; - return 0; - } - - // Handle the case when strerror_r is not available. - int handle(internal::Null<>) { - return fallback(strerror_s(buffer_, buffer_size_, error_code_)); - } - - // Fallback to strerror_s when strerror_r is not available. - int fallback(int result) { - // If the buffer is full then the message is probably truncated. - return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? - ERANGE : result; - } - - // Fallback to strerror if strerror_r and strerror_s are not available. - int fallback(internal::Null<>) { - errno = 0; - buffer_ = strerror(error_code_); - return errno; - } - - public: - StrError(int err_code, char *&buf, std::size_t buf_size) - : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} - - int run() { - // Suppress a warning about unused strerror_r. - strerror_r(0, FMT_NULL, ""); - return handle(strerror_r(error_code_, buffer_, buffer_size_)); - } - }; - return StrError(error_code, buffer, buffer_size).run(); -} - -void format_error_code(Writer &out, int error_code, - StringRef message) FMT_NOEXCEPT { - // Report error code making sure that the output fits into - // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential - // bad_alloc. - out.clear(); - static const char SEP[] = ": "; - static const char ERROR_STR[] = "error "; - // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. - std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; - typedef internal::IntTraits::MainType MainType; - MainType abs_value = static_cast(error_code); - if (internal::is_negative(error_code)) { - abs_value = 0 - abs_value; - ++error_code_size; - } - error_code_size += internal::count_digits(abs_value); - if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size) - out << message << SEP; - out << ERROR_STR << error_code; - assert(out.size() <= internal::INLINE_BUFFER_SIZE); -} - -void report_error(FormatFunc func, int error_code, - StringRef message) FMT_NOEXCEPT { - MemoryWriter full_message; - func(full_message, error_code, message); - // Use Writer::data instead of Writer::c_str to avoid potential memory - // allocation. - std::fwrite(full_message.data(), full_message.size(), 1, stderr); - std::fputc('\n', stderr); -} -} // namespace - -FMT_FUNC void SystemError::init( - int err_code, CStringRef format_str, ArgList args) { - error_code_ = err_code; - MemoryWriter w; - format_system_error(w, err_code, format(format_str, args)); - std::runtime_error &base = *this; - base = std::runtime_error(w.str()); -} - -template -int internal::CharTraits::format_float( - char *buffer, std::size_t size, const char *format, - unsigned width, int precision, T value) { - if (width == 0) { - return precision < 0 ? - FMT_SNPRINTF(buffer, size, format, value) : - FMT_SNPRINTF(buffer, size, format, precision, value); - } - return precision < 0 ? - FMT_SNPRINTF(buffer, size, format, width, value) : - FMT_SNPRINTF(buffer, size, format, width, precision, value); -} - -template -int internal::CharTraits::format_float( - wchar_t *buffer, std::size_t size, const wchar_t *format, - unsigned width, int precision, T value) { - if (width == 0) { - return precision < 0 ? - FMT_SWPRINTF(buffer, size, format, value) : - FMT_SWPRINTF(buffer, size, format, precision, value); - } - return precision < 0 ? - FMT_SWPRINTF(buffer, size, format, width, value) : - FMT_SWPRINTF(buffer, size, format, width, precision, value); -} - -template -const char internal::BasicData::DIGITS[] = - "0001020304050607080910111213141516171819" - "2021222324252627282930313233343536373839" - "4041424344454647484950515253545556575859" - "6061626364656667686970717273747576777879" - "8081828384858687888990919293949596979899"; - -#define FMT_POWERS_OF_10(factor) \ - factor * 10, \ - factor * 100, \ - factor * 1000, \ - factor * 10000, \ - factor * 100000, \ - factor * 1000000, \ - factor * 10000000, \ - factor * 100000000, \ - factor * 1000000000 - -template -const uint32_t internal::BasicData::POWERS_OF_10_32[] = { - 0, FMT_POWERS_OF_10(1) -}; - -template -const uint64_t internal::BasicData::POWERS_OF_10_64[] = { - 0, - FMT_POWERS_OF_10(1), - FMT_POWERS_OF_10(ULongLong(1000000000)), - // Multiply several constants instead of using a single long long constant - // to avoid warnings about C++98 not supporting long long. - ULongLong(1000000000) * ULongLong(1000000000) * 10 -}; - -FMT_FUNC void internal::report_unknown_type(char code, const char *type) { - (void)type; - if (std::isprint(static_cast(code))) { - FMT_THROW(FormatError( - format("unknown format code '{}' for {}", code, type))); - } - FMT_THROW(FormatError( - format("unknown format code '\\x{:02x}' for {}", - static_cast(code), type))); -} - -#if FMT_USE_WINDOWS_H - -FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) { - static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; - if (s.size() > INT_MAX) - FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG)); - int s_size = static_cast(s.size()); - int length = MultiByteToWideChar( - CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0); - if (length == 0) - FMT_THROW(WindowsError(GetLastError(), ERROR_MSG)); - buffer_.resize(length + 1); - length = MultiByteToWideChar( - CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length); - if (length == 0) - FMT_THROW(WindowsError(GetLastError(), ERROR_MSG)); - buffer_[length] = 0; -} - -FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) { - if (int error_code = convert(s)) { - FMT_THROW(WindowsError(error_code, - "cannot convert string from UTF-16 to UTF-8")); - } -} - -FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) { - if (s.size() > INT_MAX) - return ERROR_INVALID_PARAMETER; - int s_size = static_cast(s.size()); - int length = WideCharToMultiByte( - CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL); - if (length == 0) - return GetLastError(); - buffer_.resize(length + 1); - length = WideCharToMultiByte( - CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL); - if (length == 0) - return GetLastError(); - buffer_[length] = 0; - return 0; -} - -FMT_FUNC void WindowsError::init( - int err_code, CStringRef format_str, ArgList args) { - error_code_ = err_code; - MemoryWriter w; - internal::format_windows_error(w, err_code, format(format_str, args)); - std::runtime_error &base = *this; - base = std::runtime_error(w.str()); -} - -FMT_FUNC void internal::format_windows_error( - Writer &out, int error_code, StringRef message) FMT_NOEXCEPT { - FMT_TRY { - MemoryBuffer buffer; - buffer.resize(INLINE_BUFFER_SIZE); - for (;;) { - wchar_t *system_message = &buffer[0]; - int result = FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - system_message, static_cast(buffer.size()), FMT_NULL); - if (result != 0) { - UTF16ToUTF8 utf8_message; - if (utf8_message.convert(system_message) == ERROR_SUCCESS) { - out << message << ": " << utf8_message; - return; - } - break; - } - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - break; // Can't get error message, report error code instead. - buffer.resize(buffer.size() * 2); - } - } FMT_CATCH(...) {} - fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. -} - -#endif // FMT_USE_WINDOWS_H - -FMT_FUNC void format_system_error( - Writer &out, int error_code, StringRef message) FMT_NOEXCEPT { - FMT_TRY { - internal::MemoryBuffer buffer; - buffer.resize(internal::INLINE_BUFFER_SIZE); - for (;;) { - char *system_message = &buffer[0]; - int result = safe_strerror(error_code, system_message, buffer.size()); - if (result == 0) { - out << message << ": " << system_message; - return; - } - if (result != ERANGE) - break; // Can't get error message, report error code instead. - buffer.resize(buffer.size() * 2); - } - } FMT_CATCH(...) {} - fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. -} - -template -void internal::ArgMap::init(const ArgList &args) { - if (!map_.empty()) - return; - typedef internal::NamedArg NamedArg; - const NamedArg *named_arg = FMT_NULL; - bool use_values = - args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE; - if (use_values) { - for (unsigned i = 0;/*nothing*/; ++i) { - internal::Arg::Type arg_type = args.type(i); - switch (arg_type) { - case internal::Arg::NONE: - return; - case internal::Arg::NAMED_ARG: - named_arg = static_cast(args.values_[i].pointer); - map_.push_back(Pair(named_arg->name, *named_arg)); - break; - default: - /*nothing*/; - } - } - return; - } - for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) { - internal::Arg::Type arg_type = args.type(i); - if (arg_type == internal::Arg::NAMED_ARG) { - named_arg = static_cast(args.args_[i].pointer); - map_.push_back(Pair(named_arg->name, *named_arg)); - } - } - for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) { - switch (args.args_[i].type) { - case internal::Arg::NONE: - return; - case internal::Arg::NAMED_ARG: - named_arg = static_cast(args.args_[i].pointer); - map_.push_back(Pair(named_arg->name, *named_arg)); - break; - default: - /*nothing*/; - } - } -} - -template -void internal::FixedBuffer::grow(std::size_t) { - FMT_THROW(std::runtime_error("buffer overflow")); -} - -FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg( - unsigned arg_index, const char *&error) { - internal::Arg arg = args_[arg_index]; - switch (arg.type) { - case internal::Arg::NONE: - error = "argument index out of range"; - break; - case internal::Arg::NAMED_ARG: - arg = *static_cast(arg.pointer); - break; - default: - /*nothing*/; - } - return arg; -} - -FMT_FUNC void report_system_error( - int error_code, fmt::StringRef message) FMT_NOEXCEPT { - // 'fmt::' is for bcc32. - report_error(format_system_error, error_code, message); -} - -#if FMT_USE_WINDOWS_H -FMT_FUNC void report_windows_error( - int error_code, fmt::StringRef message) FMT_NOEXCEPT { - // 'fmt::' is for bcc32. - report_error(internal::format_windows_error, error_code, message); -} -#endif - -FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) { - MemoryWriter w; - w.write(format_str, args); - std::fwrite(w.data(), 1, w.size(), f); -} - -FMT_FUNC void print(CStringRef format_str, ArgList args) { - print(stdout, format_str, args); -} - -FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) { - char escape[] = "\x1b[30m"; - escape[3] = static_cast('0' + c); - std::fputs(escape, stdout); - print(format, args); - std::fputs(RESET_COLOR, stdout); -} - -#ifndef FMT_HEADER_ONLY - -template struct internal::BasicData; - -// Explicit instantiations for char. - -template void internal::FixedBuffer::grow(std::size_t); - -template void internal::ArgMap::init(const ArgList &args); - -template FMT_API int internal::CharTraits::format_float( - char *buffer, std::size_t size, const char *format, - unsigned width, int precision, double value); - -template FMT_API int internal::CharTraits::format_float( - char *buffer, std::size_t size, const char *format, - unsigned width, int precision, long double value); - -// Explicit instantiations for wchar_t. - -template void internal::FixedBuffer::grow(std::size_t); - -template void internal::ArgMap::init(const ArgList &args); - -template FMT_API int internal::CharTraits::format_float( - wchar_t *buffer, std::size_t size, const wchar_t *format, - unsigned width, int precision, double value); - -template FMT_API int internal::CharTraits::format_float( - wchar_t *buffer, std::size_t size, const wchar_t *format, - unsigned width, int precision, long double value); - -#endif // FMT_HEADER_ONLY - -} // namespace fmt - -#ifdef _MSC_VER -# pragma warning(pop) -#endif diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.h b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.h deleted file mode 100644 index 91f434813..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/format.h +++ /dev/null @@ -1,4659 +0,0 @@ -/* - Formatting library for C++ - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FMT_FORMAT_H_ -#define FMT_FORMAT_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // for std::pair - -// The fmt library version in the form major * 10000 + minor * 100 + patch. -#define FMT_VERSION 40000 - -#ifdef _SECURE_SCL -# define FMT_SECURE_SCL _SECURE_SCL -#else -# define FMT_SECURE_SCL 0 -#endif - -#if FMT_SECURE_SCL -# include -#endif - -#ifdef _MSC_VER -# define FMT_MSC_VER _MSC_VER -#else -# define FMT_MSC_VER 0 -#endif - -#if FMT_MSC_VER && FMT_MSC_VER <= 1500 -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; -typedef __int64 intmax_t; -#else -#include -#endif - -#if !defined(FMT_HEADER_ONLY) && defined(_WIN32) -# ifdef FMT_EXPORT -# define FMT_API __declspec(dllexport) -# elif defined(FMT_SHARED) -# define FMT_API __declspec(dllimport) -# endif -#endif -#ifndef FMT_API -# define FMT_API -#endif - -#ifdef __GNUC__ -# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -# define FMT_GCC_EXTENSION __extension__ -# if FMT_GCC_VERSION >= 406 -# pragma GCC diagnostic push -// Disable the warning about "long long" which is sometimes reported even -// when using __extension__. -# pragma GCC diagnostic ignored "-Wlong-long" -// Disable the warning about declaration shadowing because it affects too -// many valid cases. -# pragma GCC diagnostic ignored "-Wshadow" -// Disable the warning about implicit conversions that may change the sign of -// an integer; silencing it otherwise would require many explicit casts. -# pragma GCC diagnostic ignored "-Wsign-conversion" -# endif -# if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__ -# define FMT_HAS_GXX_CXX11 1 -# endif -#else -# define FMT_GCC_EXTENSION -#endif - -#if defined(__INTEL_COMPILER) -# define FMT_ICC_VERSION __INTEL_COMPILER -#elif defined(__ICL) -# define FMT_ICC_VERSION __ICL -#endif - -#if defined(__clang__) && !defined(FMT_ICC_VERSION) -# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -# pragma clang diagnostic ignored "-Wpadded" -#endif - -#ifdef __GNUC_LIBSTD__ -# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) -#endif - -#ifdef __has_feature -# define FMT_HAS_FEATURE(x) __has_feature(x) -#else -# define FMT_HAS_FEATURE(x) 0 -#endif - -#ifdef __has_builtin -# define FMT_HAS_BUILTIN(x) __has_builtin(x) -#else -# define FMT_HAS_BUILTIN(x) 0 -#endif - -#ifdef __has_cpp_attribute -# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -# define FMT_HAS_CPP_ATTRIBUTE(x) 0 -#endif - -#ifndef FMT_USE_VARIADIC_TEMPLATES -// Variadic templates are available in GCC since version 4.4 -// (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++ -// since version 2013. -# define FMT_USE_VARIADIC_TEMPLATES \ - (FMT_HAS_FEATURE(cxx_variadic_templates) || \ - (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800) -#endif - -#ifndef FMT_USE_RVALUE_REFERENCES -// Don't use rvalue references when compiling with clang and an old libstdc++ -// as the latter doesn't provide std::move. -# if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402 -# define FMT_USE_RVALUE_REFERENCES 0 -# else -# define FMT_USE_RVALUE_REFERENCES \ - (FMT_HAS_FEATURE(cxx_rvalue_references) || \ - (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600) -# endif -#endif - -// Check if exceptions are disabled. -#if defined(__GNUC__) && !defined(__EXCEPTIONS) -# define FMT_EXCEPTIONS 0 -#endif -#if FMT_MSC_VER && !_HAS_EXCEPTIONS -# define FMT_EXCEPTIONS 0 -#endif -#ifndef FMT_EXCEPTIONS -# define FMT_EXCEPTIONS 1 -#endif - -#ifndef FMT_THROW -# if FMT_EXCEPTIONS -# define FMT_THROW(x) throw x -# else -# define FMT_THROW(x) assert(false) -# endif -#endif - -// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature). -#ifndef FMT_USE_NOEXCEPT -# define FMT_USE_NOEXCEPT 0 -#endif - -#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ - FMT_MSC_VER >= 1900 -# define FMT_DETECTED_NOEXCEPT noexcept -#else -# define FMT_DETECTED_NOEXCEPT throw() -#endif - -#ifndef FMT_NOEXCEPT -# if FMT_EXCEPTIONS -# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT -# else -# define FMT_NOEXCEPT -# endif -#endif - -// This is needed because GCC still uses throw() in its headers when exceptions -// are disabled. -#if FMT_GCC_VERSION -# define FMT_DTOR_NOEXCEPT FMT_DETECTED_NOEXCEPT -#else -# define FMT_DTOR_NOEXCEPT FMT_NOEXCEPT -#endif - -#ifndef FMT_OVERRIDE -# if (defined(FMT_USE_OVERRIDE) && FMT_USE_OVERRIDE) || FMT_HAS_FEATURE(cxx_override) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ - FMT_MSC_VER >= 1900 -# define FMT_OVERRIDE override -# else -# define FMT_OVERRIDE -# endif -#endif - -#ifndef FMT_NULL -# if FMT_HAS_FEATURE(cxx_nullptr) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ - FMT_MSC_VER >= 1600 -# define FMT_NULL nullptr -# else -# define FMT_NULL NULL -# endif -#endif - -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for a class -#ifndef FMT_USE_DELETED_FUNCTIONS -# define FMT_USE_DELETED_FUNCTIONS 0 -#endif - -#if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \ - (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800 -# define FMT_DELETED_OR_UNDEFINED = delete -# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - TypeName& operator=(const TypeName&) = delete -#else -# define FMT_DELETED_OR_UNDEFINED -# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - TypeName& operator=(const TypeName&) -#endif - -#ifndef FMT_USE_DEFAULTED_FUNCTIONS -# define FMT_USE_DEFAULTED_FUNCTIONS 0 -#endif - -#ifndef FMT_DEFAULTED_COPY_CTOR -# if FMT_USE_DEFAULTED_FUNCTIONS || FMT_HAS_FEATURE(cxx_defaulted_functions) || \ - (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800 -# define FMT_DEFAULTED_COPY_CTOR(TypeName) \ - TypeName(const TypeName&) = default; -# else -# define FMT_DEFAULTED_COPY_CTOR(TypeName) -# endif -#endif - -#ifndef FMT_USE_USER_DEFINED_LITERALS -// All compilers which support UDLs also support variadic templates. This -// makes the fmt::literals implementation easier. However, an explicit check -// for variadic templates is added here just in case. -// For Intel's compiler both it and the system gcc/msc must support UDLs. -# define FMT_USE_USER_DEFINED_LITERALS \ - FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \ - (FMT_HAS_FEATURE(cxx_user_literals) || \ - (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \ - (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500) -#endif - -#ifndef FMT_USE_EXTERN_TEMPLATES -# define FMT_USE_EXTERN_TEMPLATES \ - (FMT_CLANG_VERSION >= 209 || (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11)) -#endif - -#ifdef FMT_HEADER_ONLY -// If header only do not use extern templates. -# undef FMT_USE_EXTERN_TEMPLATES -# define FMT_USE_EXTERN_TEMPLATES 0 -#endif - -#ifndef FMT_ASSERT -# define FMT_ASSERT(condition, message) assert((condition) && message) -#endif - -// __builtin_clz is broken in clang with Microsoft CodeGen: -// https://github.com/fmtlib/fmt/issues/519 -#ifndef _MSC_VER -# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) -# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) -# endif - -# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) -# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) -# endif -#endif - -// Some compilers masquerade as both MSVC and GCC-likes or -// otherwise support __builtin_clz and __builtin_clzll, so -// only define FMT_BUILTIN_CLZ using the MSVC intrinsics -// if the clz and clzll builtins are not available. -#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED) -# include // _BitScanReverse, _BitScanReverse64 - -namespace fmt -{ -namespace internal -{ -# pragma intrinsic(_BitScanReverse) -inline uint32_t clz(uint32_t x) -{ - unsigned long r = 0; - _BitScanReverse(&r, x); - - assert(x != 0); - // Static analysis complains about using uninitialized data - // "r", but the only way that can happen is if "x" is 0, - // which the callers guarantee to not happen. -# pragma warning(suppress: 6102) - return 31 - r; -} -# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n) - -# ifdef _WIN64 -# pragma intrinsic(_BitScanReverse64) -# endif - -inline uint32_t clzll(uint64_t x) -{ - unsigned long r = 0; -# ifdef _WIN64 - _BitScanReverse64(&r, x); -# else - // Scan the high 32 bits. - if (_BitScanReverse(&r, static_cast(x >> 32))) - return 63 - (r + 32); - - // Scan the low 32 bits. - _BitScanReverse(&r, static_cast(x)); -# endif - - assert(x != 0); - // Static analysis complains about using uninitialized data - // "r", but the only way that can happen is if "x" is 0, - // which the callers guarantee to not happen. -# pragma warning(suppress: 6102) - return 63 - r; -} -# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n) -} -} -#endif - -namespace fmt -{ -namespace internal -{ -struct DummyInt -{ - int data[2]; - operator int() const - { - return 0; - } -}; -typedef std::numeric_limits FPUtil; - -// Dummy implementations of system functions such as signbit and ecvt called -// if the latter are not available. -inline DummyInt signbit(...) -{ - return DummyInt(); -} -inline DummyInt _ecvt_s(...) -{ - return DummyInt(); -} -inline DummyInt isinf(...) -{ - return DummyInt(); -} -inline DummyInt _finite(...) -{ - return DummyInt(); -} -inline DummyInt isnan(...) -{ - return DummyInt(); -} -inline DummyInt _isnan(...) -{ - return DummyInt(); -} - -// A helper function to suppress bogus "conditional expression is constant" -// warnings. -template -inline T const_check(T value) -{ - return value; -} -} -} // namespace fmt - -namespace std -{ -// Standard permits specialization of std::numeric_limits. This specialization -// is used to resolve ambiguity between isinf and std::isinf in glibc: -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891 -// and the same for isnan and signbit. -template <> -class numeric_limits : - public std::numeric_limits -{ -public: - // Portable version of isinf. - template - static bool isinfinity(T x) - { - using namespace fmt::internal; - // The resolution "priority" is: - // isinf macro > std::isinf > ::isinf > fmt::internal::isinf - if (const_check(sizeof(isinf(x)) == sizeof(bool) || - sizeof(isinf(x)) == sizeof(int))) - { - return isinf(x) != 0; - } - return !_finite(static_cast(x)); - } - - // Portable version of isnan. - template - static bool isnotanumber(T x) - { - using namespace fmt::internal; - if (const_check(sizeof(isnan(x)) == sizeof(bool) || - sizeof(isnan(x)) == sizeof(int))) - { - return isnan(x) != 0; - } - return _isnan(static_cast(x)) != 0; - } - - // Portable version of signbit. - static bool isnegative(double x) - { - using namespace fmt::internal; - if (const_check(sizeof(signbit(x)) == sizeof(bool) || - sizeof(signbit(x)) == sizeof(int))) - { - return signbit(x) != 0; - } - if (x < 0) return true; - if (!isnotanumber(x)) return false; - int dec = 0, sign = 0; - char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. - _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign); - return sign != 0; - } -}; -} // namespace std - -namespace fmt -{ - -// Fix the warning about long long on older versions of GCC -// that don't support the diagnostic pragma. -FMT_GCC_EXTENSION typedef long long LongLong; -FMT_GCC_EXTENSION typedef unsigned long long ULongLong; - -#if FMT_USE_RVALUE_REFERENCES -using std::move; -#endif - -template -class BasicWriter; - -typedef BasicWriter Writer; -typedef BasicWriter WWriter; - -template -class ArgFormatter; - -struct FormatSpec; - -template -class BasicPrintfArgFormatter; - -template > -class BasicFormatter; - -/** - \rst - A string reference. It can be constructed from a C string or - ``std::basic_string``. - - You can use one of the following typedefs for common character types: - - +------------+-------------------------+ - | Type | Definition | - +============+=========================+ - | StringRef | BasicStringRef | - +------------+-------------------------+ - | WStringRef | BasicStringRef | - +------------+-------------------------+ - - This class is most useful as a parameter type to allow passing - different types of strings to a function, for example:: - - template - std::string format(StringRef format_str, const Args & ... args); - - format("{}", 42); - format(std::string("{}"), 42); - \endrst - */ -template -class BasicStringRef -{ -private: - const Char *data_; - std::size_t size_; - -public: - /** Constructs a string reference object from a C string and a size. */ - BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {} - - /** - \rst - Constructs a string reference object from a C string computing - the size with ``std::char_traits::length``. - \endrst - */ - BasicStringRef(const Char *s) - : data_(s), size_(std::char_traits::length(s)) {} - - /** - \rst - Constructs a string reference from a ``std::basic_string`` object. - \endrst - */ - template - BasicStringRef( - const std::basic_string, Allocator> &s) - : data_(s.c_str()), size_(s.size()) {} - - /** - \rst - Converts a string reference to an ``std::string`` object. - \endrst - */ - std::basic_string to_string() const - { - return std::basic_string(data_, size_); - } - - /** Returns a pointer to the string data. */ - const Char *data() const - { - return data_; - } - - /** Returns the string size. */ - std::size_t size() const - { - return size_; - } - - // Lexicographically compare this string reference to other. - int compare(BasicStringRef other) const - { - std::size_t size = size_ < other.size_ ? size_ : other.size_; - int result = std::char_traits::compare(data_, other.data_, size); - if (result == 0) - result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); - return result; - } - - friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.compare(rhs) == 0; - } - friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.compare(rhs) != 0; - } - friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.compare(rhs) < 0; - } - friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.compare(rhs) <= 0; - } - friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.compare(rhs) > 0; - } - friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.compare(rhs) >= 0; - } -}; - -typedef BasicStringRef StringRef; -typedef BasicStringRef WStringRef; - -/** - \rst - A reference to a null terminated string. It can be constructed from a C - string or ``std::basic_string``. - - You can use one of the following typedefs for common character types: - - +-------------+--------------------------+ - | Type | Definition | - +=============+==========================+ - | CStringRef | BasicCStringRef | - +-------------+--------------------------+ - | WCStringRef | BasicCStringRef | - +-------------+--------------------------+ - - This class is most useful as a parameter type to allow passing - different types of strings to a function, for example:: - - template - std::string format(CStringRef format_str, const Args & ... args); - - format("{}", 42); - format(std::string("{}"), 42); - \endrst - */ -template -class BasicCStringRef -{ -private: - const Char *data_; - -public: - /** Constructs a string reference object from a C string. */ - BasicCStringRef(const Char *s) : data_(s) {} - - /** - \rst - Constructs a string reference from a ``std::basic_string`` object. - \endrst - */ - template - BasicCStringRef( - const std::basic_string, Allocator> &s) - : data_(s.c_str()) {} - - /** Returns the pointer to a C string. */ - const Char *c_str() const - { - return data_; - } -}; - -typedef BasicCStringRef CStringRef; -typedef BasicCStringRef WCStringRef; - -/** A formatting error such as invalid format string. */ -class FormatError : public std::runtime_error -{ -public: - explicit FormatError(CStringRef message) - : std::runtime_error(message.c_str()) {} - FormatError(const FormatError &ferr) : std::runtime_error(ferr) {} - FMT_API ~FormatError() FMT_DTOR_NOEXCEPT; -}; - -namespace internal -{ - -// MakeUnsigned::Type gives an unsigned type corresponding to integer type T. -template -struct MakeUnsigned -{ - typedef T Type; -}; - -#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \ - template <> \ - struct MakeUnsigned { typedef U Type; } - -FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char); -FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char); -FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short); -FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned); -FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long); -FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong); - -// Casts nonnegative integer to unsigned. -template -inline typename MakeUnsigned::Type to_unsigned(Int value) -{ - FMT_ASSERT(value >= 0, "negative value"); - return static_cast::Type>(value); -} - -// The number of characters to store in the MemoryBuffer object itself -// to avoid dynamic memory allocation. -enum { INLINE_BUFFER_SIZE = 500 }; - -#if FMT_SECURE_SCL -// Use checked iterator to avoid warnings on MSVC. -template -inline stdext::checked_array_iterator make_ptr(T *ptr, std::size_t size) -{ - return stdext::checked_array_iterator(ptr, size); -} -#else -template -inline T *make_ptr(T *ptr, std::size_t) -{ - return ptr; -} -#endif -} // namespace internal - -/** - \rst - A buffer supporting a subset of ``std::vector``'s operations. - \endrst - */ -template -class Buffer -{ -private: - FMT_DISALLOW_COPY_AND_ASSIGN(Buffer); - -protected: - T *ptr_; - std::size_t size_; - std::size_t capacity_; - - Buffer(T *ptr = FMT_NULL, std::size_t capacity = 0) - : ptr_(ptr), size_(0), capacity_(capacity) {} - - /** - \rst - Increases the buffer capacity to hold at least *size* elements updating - ``ptr_`` and ``capacity_``. - \endrst - */ - virtual void grow(std::size_t size) = 0; - -public: - virtual ~Buffer() {} - - /** Returns the size of this buffer. */ - std::size_t size() const - { - return size_; - } - - /** Returns the capacity of this buffer. */ - std::size_t capacity() const - { - return capacity_; - } - - /** - Resizes the buffer. If T is a POD type new elements may not be initialized. - */ - void resize(std::size_t new_size) - { - if (new_size > capacity_) - grow(new_size); - size_ = new_size; - } - - /** - \rst - Reserves space to store at least *capacity* elements. - \endrst - */ - void reserve(std::size_t capacity) - { - if (capacity > capacity_) - grow(capacity); - } - - void clear() FMT_NOEXCEPT { size_ = 0; } - - void push_back(const T &value) - { - if (size_ == capacity_) - grow(size_ + 1); - ptr_[size_++] = value; - } - - /** Appends data to the end of the buffer. */ - template - void append(const U *begin, const U *end); - - T &operator[](std::size_t index) - { - return ptr_[index]; - } - const T &operator[](std::size_t index) const - { - return ptr_[index]; - } -}; - -template -template -void Buffer::append(const U *begin, const U *end) -{ - FMT_ASSERT(end >= begin, "negative value"); - std::size_t new_size = size_ + (end - begin); - if (new_size > capacity_) - grow(new_size); - std::uninitialized_copy(begin, end, - internal::make_ptr(ptr_, capacity_) + size_); - size_ = new_size; -} - -namespace internal -{ - -// A memory buffer for trivially copyable/constructible types with the first -// SIZE elements stored in the object itself. -template > -class MemoryBuffer : private Allocator, public Buffer -{ -private: - T data_[SIZE]; - - // Deallocate memory allocated by the buffer. - void deallocate() - { - if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_); - } - -protected: - void grow(std::size_t size) FMT_OVERRIDE; - -public: - explicit MemoryBuffer(const Allocator &alloc = Allocator()) - : Allocator(alloc), Buffer(data_, SIZE) {} - ~MemoryBuffer() - { - deallocate(); - } - -#if FMT_USE_RVALUE_REFERENCES -private: - // Move data from other to this buffer. - void move(MemoryBuffer &other) - { - Allocator &this_alloc = *this, &other_alloc = other; - this_alloc = std::move(other_alloc); - this->size_ = other.size_; - this->capacity_ = other.capacity_; - if (other.ptr_ == other.data_) - { - this->ptr_ = data_; - std::uninitialized_copy(other.data_, other.data_ + this->size_, - make_ptr(data_, this->capacity_)); - } - else - { - this->ptr_ = other.ptr_; - // Set pointer to the inline array so that delete is not called - // when deallocating. - other.ptr_ = other.data_; - } - } - -public: - MemoryBuffer(MemoryBuffer &&other) - { - move(other); - } - - MemoryBuffer &operator=(MemoryBuffer &&other) - { - assert(this != &other); - deallocate(); - move(other); - return *this; - } -#endif - - // Returns a copy of the allocator associated with this buffer. - Allocator get_allocator() const - { - return *this; - } -}; - -template -void MemoryBuffer::grow(std::size_t size) -{ - std::size_t new_capacity = this->capacity_ + this->capacity_ / 2; - if (size > new_capacity) - new_capacity = size; - T *new_ptr = this->allocate(new_capacity, FMT_NULL); - // The following code doesn't throw, so the raw pointer above doesn't leak. - std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_, - make_ptr(new_ptr, new_capacity)); - std::size_t old_capacity = this->capacity_; - T *old_ptr = this->ptr_; - this->capacity_ = new_capacity; - this->ptr_ = new_ptr; - // deallocate may throw (at least in principle), but it doesn't matter since - // the buffer already uses the new storage and will deallocate it in case - // of exception. - if (old_ptr != data_) - Allocator::deallocate(old_ptr, old_capacity); -} - -// A fixed-size buffer. -template -class FixedBuffer : public fmt::Buffer -{ -public: - FixedBuffer(Char *array, std::size_t size) : fmt::Buffer(array, size) {} - -protected: - FMT_API void grow(std::size_t size) FMT_OVERRIDE; -}; - -template -class BasicCharTraits -{ -public: -#if FMT_SECURE_SCL - typedef stdext::checked_array_iterator CharPtr; -#else - typedef Char *CharPtr; -#endif - static Char cast(int value) - { - return static_cast(value); - } -}; - -template -class CharTraits; - -template <> -class CharTraits : public BasicCharTraits -{ -private: - // Conversion from wchar_t to char is not allowed. - static char convert(wchar_t); - -public: - static char convert(char value) - { - return value; - } - - // Formats a floating-point number. - template - FMT_API static int format_float(char *buffer, std::size_t size, - const char *format, unsigned width, int precision, T value); -}; - -#if FMT_USE_EXTERN_TEMPLATES -extern template int CharTraits::format_float -(char *buffer, std::size_t size, - const char* format, unsigned width, int precision, double value); -extern template int CharTraits::format_float -(char *buffer, std::size_t size, - const char* format, unsigned width, int precision, long double value); -#endif - -template <> -class CharTraits : public BasicCharTraits -{ -public: - static wchar_t convert(char value) - { - return value; - } - static wchar_t convert(wchar_t value) - { - return value; - } - - template - FMT_API static int format_float(wchar_t *buffer, std::size_t size, - const wchar_t *format, unsigned width, int precision, T value); -}; - -#if FMT_USE_EXTERN_TEMPLATES -extern template int CharTraits::format_float -(wchar_t *buffer, std::size_t size, - const wchar_t* format, unsigned width, int precision, double value); -extern template int CharTraits::format_float -(wchar_t *buffer, std::size_t size, - const wchar_t* format, unsigned width, int precision, long double value); -#endif - -// Checks if a number is negative - used to avoid warnings. -template -struct SignChecker -{ - template - static bool is_negative(T value) - { - return value < 0; - } -}; - -template <> -struct SignChecker -{ - template - static bool is_negative(T) - { - return false; - } -}; - -// Returns true if value is negative, false otherwise. -// Same as (value < 0) but doesn't produce warnings if T is an unsigned type. -template -inline bool is_negative(T value) -{ - return SignChecker::is_signed>::is_negative(value); -} - -// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise. -template -struct TypeSelector -{ - typedef uint32_t Type; -}; - -template <> -struct TypeSelector -{ - typedef uint64_t Type; -}; - -template -struct IntTraits -{ - // Smallest of uint32_t and uint64_t that is large enough to represent - // all values of T. - typedef typename - TypeSelector::digits <= 32>::Type MainType; -}; - -FMT_API void report_unknown_type(char code, const char *type); - -// Static data is placed in this class template to allow header-only -// configuration. -template -struct FMT_API BasicData -{ - static const uint32_t POWERS_OF_10_32[]; - static const uint64_t POWERS_OF_10_64[]; - static const char DIGITS[]; -}; - -#if FMT_USE_EXTERN_TEMPLATES -extern template struct BasicData; -#endif - -typedef BasicData<> Data; - -#ifdef FMT_BUILTIN_CLZLL -// Returns the number of decimal digits in n. Leading zeros are not counted -// except for n == 0 in which case count_digits returns 1. -inline unsigned count_digits(uint64_t n) -{ - // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. - int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12; - return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1; -} -#else -// Fallback version of count_digits used when __builtin_clz is not available. -inline unsigned count_digits(uint64_t n) -{ - unsigned count = 1; - for (;;) - { - // Integer division is slow so do it for a group of four digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - if (n < 10) return count; - if (n < 100) return count + 1; - if (n < 1000) return count + 2; - if (n < 10000) return count + 3; - n /= 10000u; - count += 4; - } -} -#endif - -#ifdef FMT_BUILTIN_CLZ -// Optional version of count_digits for better performance on 32-bit platforms. -inline unsigned count_digits(uint32_t n) -{ - int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12; - return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1; -} -#endif - -// A functor that doesn't add a thousands separator. -struct NoThousandsSep -{ - template - void operator()(Char *) {} -}; - -// A functor that adds a thousands separator. -class ThousandsSep -{ -private: - fmt::StringRef sep_; - - // Index of a decimal digit with the least significant digit having index 0. - unsigned digit_index_; - -public: - explicit ThousandsSep(fmt::StringRef sep) : sep_(sep), digit_index_(0) {} - - template - void operator()(Char *&buffer) - { - if (++digit_index_ % 3 != 0) - return; - buffer -= sep_.size(); - std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(), - internal::make_ptr(buffer, sep_.size())); - } -}; - -// Formats a decimal unsigned integer value writing into buffer. -// thousands_sep is a functor that is called after writing each char to -// add a thousands separator if necessary. -template -inline void format_decimal(Char *buffer, UInt value, unsigned num_digits, - ThousandsSep thousands_sep) -{ - buffer += num_digits; - while (value >= 100) - { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = static_cast((value % 100) * 2); - value /= 100; - *--buffer = Data::DIGITS[index + 1]; - thousands_sep(buffer); - *--buffer = Data::DIGITS[index]; - thousands_sep(buffer); - } - if (value < 10) - { - *--buffer = static_cast('0' + value); - return; - } - unsigned index = static_cast(value * 2); - *--buffer = Data::DIGITS[index + 1]; - thousands_sep(buffer); - *--buffer = Data::DIGITS[index]; -} - -template -inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) -{ - format_decimal(buffer, value, num_digits, NoThousandsSep()); - return; -} - -#ifndef _WIN32 -# define FMT_USE_WINDOWS_H 0 -#elif !defined(FMT_USE_WINDOWS_H) -# define FMT_USE_WINDOWS_H 1 -#endif - -// Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h. -// All the functionality that relies on it will be disabled too. -#if FMT_USE_WINDOWS_H -// A converter from UTF-8 to UTF-16. -// It is only provided for Windows since other systems support UTF-8 natively. -class UTF8ToUTF16 -{ -private: - MemoryBuffer buffer_; - -public: - FMT_API explicit UTF8ToUTF16(StringRef s); - operator WStringRef() const - { - return WStringRef(&buffer_[0], size()); - } - size_t size() const - { - return buffer_.size() - 1; - } - const wchar_t *c_str() const - { - return &buffer_[0]; - } - std::wstring str() const - { - return std::wstring(&buffer_[0], size()); - } -}; - -// A converter from UTF-16 to UTF-8. -// It is only provided for Windows since other systems support UTF-8 natively. -class UTF16ToUTF8 -{ -private: - MemoryBuffer buffer_; - -public: - UTF16ToUTF8() {} - FMT_API explicit UTF16ToUTF8(WStringRef s); - operator StringRef() const - { - return StringRef(&buffer_[0], size()); - } - size_t size() const - { - return buffer_.size() - 1; - } - const char *c_str() const - { - return &buffer_[0]; - } - std::string str() const - { - return std::string(&buffer_[0], size()); - } - - // Performs conversion returning a system error code instead of - // throwing exception on conversion error. This method may still throw - // in case of memory allocation error. - FMT_API int convert(WStringRef s); -}; - -FMT_API void format_windows_error(fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT; -#endif - -// A formatting argument value. -struct Value -{ - template - struct StringValue - { - const Char *value; - std::size_t size; - }; - - typedef void (*FormatFunc)( - void *formatter, const void *arg, void *format_str_ptr); - - struct CustomValue - { - const void *value; - FormatFunc format; - }; - - union - { - int int_value; - unsigned uint_value; - LongLong long_long_value; - ULongLong ulong_long_value; - double double_value; - long double long_double_value; - const void *pointer; - StringValue string; - StringValue sstring; - StringValue ustring; - StringValue wstring; - CustomValue custom; - }; - - enum Type - { - NONE, NAMED_ARG, - // Integer types should go first, - INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR, - // followed by floating-point types. - DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, - CSTRING, STRING, WSTRING, POINTER, CUSTOM - }; -}; - -// A formatting argument. It is a trivially copyable/constructible type to -// allow storage in internal::MemoryBuffer. -struct Arg : Value -{ - Type type; -}; - -template -struct NamedArg; -template -struct NamedArgWithType; - -template -struct Null {}; - -// A helper class template to enable or disable overloads taking wide -// characters and strings in MakeValue. -template -struct WCharHelper -{ - typedef Null Supported; - typedef T Unsupported; -}; - -template -struct WCharHelper -{ - typedef T Supported; - typedef Null Unsupported; -}; - -typedef char Yes[1]; -typedef char No[2]; - -template -T &get(); - -// These are non-members to workaround an overload resolution bug in bcc32. -Yes &convert(fmt::ULongLong); -No &convert(...); - -template -struct ConvertToIntImpl -{ - enum { value = ENABLE_CONVERSION }; -}; - -template -struct ConvertToIntImpl2 -{ - enum { value = false }; -}; - -template -struct ConvertToIntImpl2 -{ - enum - { - // Don't convert numeric types. - value = ConvertToIntImpl::is_specialized>::value - }; -}; - -template -struct ConvertToInt -{ - enum - { - enable_conversion = sizeof(fmt::internal::convert(get())) == sizeof(Yes) - }; - enum { value = ConvertToIntImpl2::value }; -}; - -#define FMT_DISABLE_CONVERSION_TO_INT(Type) \ - template <> \ - struct ConvertToInt { enum { value = 0 }; } - -// Silence warnings about convering float to int. -FMT_DISABLE_CONVERSION_TO_INT(float); -FMT_DISABLE_CONVERSION_TO_INT(double); -FMT_DISABLE_CONVERSION_TO_INT(long double); - -template -struct EnableIf {}; - -template -struct EnableIf -{ - typedef T type; -}; - -template -struct Conditional -{ - typedef T type; -}; - -template -struct Conditional -{ - typedef F type; -}; - -// For bcc32 which doesn't understand ! in template arguments. -template -struct Not -{ - enum { value = 0 }; -}; - -template <> -struct Not -{ - enum { value = 1 }; -}; - -template -struct FalseType -{ - enum { value = 0 }; -}; - -template struct LConvCheck -{ - LConvCheck(int) {} -}; - -// Returns the thousands separator for the current locale. -// We check if ``lconv`` contains ``thousands_sep`` because on Android -// ``lconv`` is stubbed as an empty struct. -template -inline StringRef thousands_sep( - LConv *lc, LConvCheck = 0) -{ - return lc->thousands_sep; -} - -inline fmt::StringRef thousands_sep(...) -{ - return ""; -} - -#define FMT_CONCAT(a, b) a##b - -#if FMT_GCC_VERSION >= 303 -# define FMT_UNUSED __attribute__((unused)) -#else -# define FMT_UNUSED -#endif - -#ifndef FMT_USE_STATIC_ASSERT -# define FMT_USE_STATIC_ASSERT 0 -#endif - -#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \ - (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600 -# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message) -#else -# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b) -# define FMT_STATIC_ASSERT(cond, message) \ - typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED -#endif - -template -void format_arg(Formatter &, const Char *, const T &) -{ - FMT_STATIC_ASSERT(FalseType::value, - "Cannot format argument. To enable the use of ostream " - "operator<< include fmt/ostream.h. Otherwise provide " - "an overload of format_arg."); -} - -// Makes an Arg object from any type. -template -class MakeValue : public Arg -{ -public: - typedef typename Formatter::Char Char; - -private: - // The following two methods are private to disallow formatting of - // arbitrary pointers. If you want to output a pointer cast it to - // "void *" or "const void *". In particular, this forbids formatting - // of "[const] volatile char *" which is printed as bool by iostreams. - // Do not implement! - template - MakeValue(const T *value); - template - MakeValue(T *value); - - // The following methods are private to disallow formatting of wide - // characters and strings into narrow strings as in - // fmt::format("{}", L"test"); - // To fix this, use a wide format string: fmt::format(L"{}", L"test"). -#if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED) - MakeValue(typename WCharHelper::Unsupported); -#endif - MakeValue(typename WCharHelper::Unsupported); - MakeValue(typename WCharHelper::Unsupported); - MakeValue(typename WCharHelper::Unsupported); - MakeValue(typename WCharHelper::Unsupported); - - void set_string(StringRef str) - { - string.value = str.data(); - string.size = str.size(); - } - - void set_string(WStringRef str) - { - wstring.value = str.data(); - wstring.size = str.size(); - } - - // Formats an argument of a custom type, such as a user-defined class. - template - static void format_custom_arg( - void *formatter, const void *arg, void *format_str_ptr) - { - format_arg(*static_cast(formatter), - *static_cast(format_str_ptr), - *static_cast(arg)); - } - -public: - MakeValue() {} - -#define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \ - MakeValue(Type value) { field = rhs; } \ - static uint64_t type(Type) { return Arg::TYPE; } - -#define FMT_MAKE_VALUE(Type, field, TYPE) \ - FMT_MAKE_VALUE_(Type, field, TYPE, value) - - FMT_MAKE_VALUE(bool, int_value, BOOL) - FMT_MAKE_VALUE(short, int_value, INT) - FMT_MAKE_VALUE(unsigned short, uint_value, UINT) - FMT_MAKE_VALUE(int, int_value, INT) - FMT_MAKE_VALUE(unsigned, uint_value, UINT) - - MakeValue(long value) - { - // To minimize the number of types we need to deal with, long is - // translated either to int or to long long depending on its size. - if (const_check(sizeof(long) == sizeof(int))) - int_value = static_cast(value); - else - long_long_value = value; - } - static uint64_t type(long) - { - return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG; - } - - MakeValue(unsigned long value) - { - if (const_check(sizeof(unsigned long) == sizeof(unsigned))) - uint_value = static_cast(value); - else - ulong_long_value = value; - } - static uint64_t type(unsigned long) - { - return sizeof(unsigned long) == sizeof(unsigned) ? - Arg::UINT : Arg::ULONG_LONG; - } - - FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG) - FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG) - FMT_MAKE_VALUE(float, double_value, DOUBLE) - FMT_MAKE_VALUE(double, double_value, DOUBLE) - FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE) - FMT_MAKE_VALUE(signed char, int_value, INT) - FMT_MAKE_VALUE(unsigned char, uint_value, UINT) - FMT_MAKE_VALUE(char, int_value, CHAR) - -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) - MakeValue(typename WCharHelper::Supported value) - { - int_value = value; - } - static uint64_t type(wchar_t) - { - return Arg::CHAR; - } -#endif - -#define FMT_MAKE_STR_VALUE(Type, TYPE) \ - MakeValue(Type value) { set_string(value); } \ - static uint64_t type(Type) { return Arg::TYPE; } - - FMT_MAKE_VALUE(char *, string.value, CSTRING) - FMT_MAKE_VALUE(const char *, string.value, CSTRING) - FMT_MAKE_VALUE(signed char *, sstring.value, CSTRING) - FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING) - FMT_MAKE_VALUE(unsigned char *, ustring.value, CSTRING) - FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) - FMT_MAKE_STR_VALUE(const std::string &, STRING) - FMT_MAKE_STR_VALUE(StringRef, STRING) - FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str()) - -#define FMT_MAKE_WSTR_VALUE(Type, TYPE) \ - MakeValue(typename WCharHelper::Supported value) { \ - set_string(value); \ - } \ - static uint64_t type(Type) { return Arg::TYPE; } - - FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING) - FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING) - FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING) - FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING) - - FMT_MAKE_VALUE(void *, pointer, POINTER) - FMT_MAKE_VALUE(const void *, pointer, POINTER) - - template - MakeValue(const T &value, - typename EnableIf::value>::value, int>::type = 0) - { - custom.value = &value; - custom.format = &format_custom_arg; - } - - template - static typename EnableIf::value>::value, uint64_t>::type - type(const T &) - { - return Arg::CUSTOM; - } - - // Additional template param `Char_` is needed here because make_type always - // uses char. - template - MakeValue(const NamedArg &value) - { - pointer = &value; - } - template - MakeValue(const NamedArgWithType &value) - { - pointer = &value; - } - - template - static uint64_t type(const NamedArg &) - { - return Arg::NAMED_ARG; - } - template - static uint64_t type(const NamedArgWithType &) - { - return Arg::NAMED_ARG; - } -}; - -template -class MakeArg : public Arg -{ -public: - MakeArg() - { - type = Arg::NONE; - } - - template - MakeArg(const T &value) - : Arg(MakeValue(value)) - { - type = static_cast(MakeValue::type(value)); - } -}; - -template -struct NamedArg : Arg -{ - BasicStringRef name; - - template - NamedArg(BasicStringRef argname, const T &value) - : Arg(MakeArg< BasicFormatter >(value)), name(argname) {} -}; - -template -struct NamedArgWithType : NamedArg -{ - NamedArgWithType(BasicStringRef argname, const T &value) - : NamedArg(argname, value) {} -}; - -class RuntimeError : public std::runtime_error -{ -protected: - RuntimeError() : std::runtime_error("") {} - RuntimeError(const RuntimeError &rerr) : std::runtime_error(rerr) {} - FMT_API ~RuntimeError() FMT_DTOR_NOEXCEPT; -}; - -template -class ArgMap; -} // namespace internal - -/** An argument list. */ -class ArgList -{ -private: - // To reduce compiled code size per formatting function call, types of first - // MAX_PACKED_ARGS arguments are passed in the types_ field. - uint64_t types_; - union - { - // If the number of arguments is less than MAX_PACKED_ARGS, the argument - // values are stored in values_, otherwise they are stored in args_. - // This is done to reduce compiled code size as storing larger objects - // may require more code (at least on x86-64) even if the same amount of - // data is actually copied to stack. It saves ~10% on the bloat test. - const internal::Value *values_; - const internal::Arg *args_; - }; - - internal::Arg::Type type(unsigned index) const - { - return type(types_, index); - } - - template - friend class internal::ArgMap; - -public: - // Maximum number of arguments with packed types. - enum { MAX_PACKED_ARGS = 16 }; - - ArgList() : types_(0) {} - - ArgList(ULongLong types, const internal::Value *values) - : types_(types), values_(values) {} - ArgList(ULongLong types, const internal::Arg *args) - : types_(types), args_(args) {} - - uint64_t types() const - { - return types_; - } - - /** Returns the argument at specified index. */ - internal::Arg operator[](unsigned index) const - { - using internal::Arg; - Arg arg; - bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE; - if (index < MAX_PACKED_ARGS) - { - Arg::Type arg_type = type(index); - internal::Value &val = arg; - if (arg_type != Arg::NONE) - val = use_values ? values_[index] : args_[index]; - arg.type = arg_type; - return arg; - } - if (use_values) - { - // The index is greater than the number of arguments that can be stored - // in values, so return a "none" argument. - arg.type = Arg::NONE; - return arg; - } - for (unsigned i = MAX_PACKED_ARGS; i <= index; ++i) - { - if (args_[i].type == Arg::NONE) - return args_[i]; - } - return args_[index]; - } - - static internal::Arg::Type type(uint64_t types, unsigned index) - { - unsigned shift = index * 4; - uint64_t mask = 0xf; - return static_cast( - (types & (mask << shift)) >> shift); - } -}; - -#define FMT_DISPATCH(call) static_cast(this)->call - -/** - \rst - An argument visitor based on the `curiously recurring template pattern - `_. - - To use `~fmt::ArgVisitor` define a subclass that implements some or all of the - visit methods with the same signatures as the methods in `~fmt::ArgVisitor`, - for example, `~fmt::ArgVisitor::visit_int()`. - Pass the subclass as the *Impl* template parameter. Then calling - `~fmt::ArgVisitor::visit` for some argument will dispatch to a visit method - specific to the argument type. For example, if the argument type is - ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass - will be called. If the subclass doesn't contain a method with this signature, - then a corresponding method of `~fmt::ArgVisitor` will be called. - - **Example**:: - - class MyArgVisitor : public fmt::ArgVisitor { - public: - void visit_int(int value) { fmt::print("{}", value); } - void visit_double(double value) { fmt::print("{}", value ); } - }; - \endrst - */ -template -class ArgVisitor -{ -private: - typedef internal::Arg Arg; - -public: - void report_unhandled_arg() {} - - Result visit_unhandled_arg() - { - FMT_DISPATCH(report_unhandled_arg()); - return Result(); - } - - /** Visits an ``int`` argument. **/ - Result visit_int(int value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - - /** Visits a ``long long`` argument. **/ - Result visit_long_long(LongLong value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - - /** Visits an ``unsigned`` argument. **/ - Result visit_uint(unsigned value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - - /** Visits an ``unsigned long long`` argument. **/ - Result visit_ulong_long(ULongLong value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - - /** Visits a ``bool`` argument. **/ - Result visit_bool(bool value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - - /** Visits a ``char`` or ``wchar_t`` argument. **/ - Result visit_char(int value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - - /** Visits an argument of any integral type. **/ - template - Result visit_any_int(T) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - /** Visits a ``double`` argument. **/ - Result visit_double(double value) - { - return FMT_DISPATCH(visit_any_double(value)); - } - - /** Visits a ``long double`` argument. **/ - Result visit_long_double(long double value) - { - return FMT_DISPATCH(visit_any_double(value)); - } - - /** Visits a ``double`` or ``long double`` argument. **/ - template - Result visit_any_double(T) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - /** Visits a null-terminated C string (``const char *``) argument. **/ - Result visit_cstring(const char *) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - /** Visits a string argument. **/ - Result visit_string(Arg::StringValue) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - /** Visits a wide string argument. **/ - Result visit_wstring(Arg::StringValue) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - /** Visits a pointer argument. **/ - Result visit_pointer(const void *) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - /** Visits an argument of a custom (user-defined) type. **/ - Result visit_custom(Arg::CustomValue) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - /** - \rst - Visits an argument dispatching to the appropriate visit method based on - the argument type. For example, if the argument type is ``double`` then - the `~fmt::ArgVisitor::visit_double()` method of the *Impl* class will be - called. - \endrst - */ - Result visit(const Arg &arg) - { - switch (arg.type) - { - case Arg::NONE: - case Arg::NAMED_ARG: - FMT_ASSERT(false, "invalid argument type"); - break; - case Arg::INT: - return FMT_DISPATCH(visit_int(arg.int_value)); - case Arg::UINT: - return FMT_DISPATCH(visit_uint(arg.uint_value)); - case Arg::LONG_LONG: - return FMT_DISPATCH(visit_long_long(arg.long_long_value)); - case Arg::ULONG_LONG: - return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); - case Arg::BOOL: - return FMT_DISPATCH(visit_bool(arg.int_value != 0)); - case Arg::CHAR: - return FMT_DISPATCH(visit_char(arg.int_value)); - case Arg::DOUBLE: - return FMT_DISPATCH(visit_double(arg.double_value)); - case Arg::LONG_DOUBLE: - return FMT_DISPATCH(visit_long_double(arg.long_double_value)); - case Arg::CSTRING: - return FMT_DISPATCH(visit_cstring(arg.string.value)); - case Arg::STRING: - return FMT_DISPATCH(visit_string(arg.string)); - case Arg::WSTRING: - return FMT_DISPATCH(visit_wstring(arg.wstring)); - case Arg::POINTER: - return FMT_DISPATCH(visit_pointer(arg.pointer)); - case Arg::CUSTOM: - return FMT_DISPATCH(visit_custom(arg.custom)); - } - return Result(); - } -}; - -enum Alignment -{ - ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC -}; - -// Flags. -enum -{ - SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8, - CHAR_FLAG = 0x10 // Argument has char type - used in error reporting. -}; - -// An empty format specifier. -struct EmptySpec {}; - -// A type specifier. -template -struct TypeSpec : EmptySpec -{ - Alignment align() const - { - return ALIGN_DEFAULT; - } - unsigned width() const - { - return 0; - } - int precision() const - { - return -1; - } - bool flag(unsigned) const - { - return false; - } - char type() const - { - return TYPE; - } - char type_prefix() const - { - return TYPE; - } - char fill() const - { - return ' '; - } -}; - -// A width specifier. -struct WidthSpec -{ - unsigned width_; - // Fill is always wchar_t and cast to char if necessary to avoid having - // two specialization of WidthSpec and its subclasses. - wchar_t fill_; - - WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {} - - unsigned width() const - { - return width_; - } - wchar_t fill() const - { - return fill_; - } -}; - -// An alignment specifier. -struct AlignSpec : WidthSpec -{ - Alignment align_; - - AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT) - : WidthSpec(width, fill), align_(align) {} - - Alignment align() const - { - return align_; - } - - int precision() const - { - return -1; - } -}; - -// An alignment and type specifier. -template -struct AlignTypeSpec : AlignSpec -{ - AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {} - - bool flag(unsigned) const - { - return false; - } - char type() const - { - return TYPE; - } - char type_prefix() const - { - return TYPE; - } -}; - -// A full format specifier. -struct FormatSpec : AlignSpec -{ - unsigned flags_; - int precision_; - char type_; - - FormatSpec( - unsigned width = 0, char type = 0, wchar_t fill = ' ') - : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} - - bool flag(unsigned f) const - { - return (flags_ & f) != 0; - } - int precision() const - { - return precision_; - } - char type() const - { - return type_; - } - char type_prefix() const - { - return type_; - } -}; - -// An integer format specifier. -template , typename Char = char> -class IntFormatSpec : public SpecT -{ -private: - T value_; - -public: - IntFormatSpec(T val, const SpecT &spec = SpecT()) - : SpecT(spec), value_(val) {} - - T value() const - { - return value_; - } -}; - -// A string format specifier. -template -class StrFormatSpec : public AlignSpec -{ -private: - const Char *str_; - -public: - template - StrFormatSpec(const Char *str, unsigned width, FillChar fill) - : AlignSpec(width, fill), str_(str) - { - internal::CharTraits::convert(FillChar()); - } - - const Char *str() const - { - return str_; - } -}; - -/** - Returns an integer format specifier to format the value in base 2. - */ -IntFormatSpec > bin(int value); - -/** - Returns an integer format specifier to format the value in base 8. - */ -IntFormatSpec > oct(int value); - -/** - Returns an integer format specifier to format the value in base 16 using - lower-case letters for the digits above 9. - */ -IntFormatSpec > hex(int value); - -/** - Returns an integer formatter format specifier to format in base 16 using - upper-case letters for the digits above 9. - */ -IntFormatSpec > hexu(int value); - -/** - \rst - Returns an integer format specifier to pad the formatted argument with the - fill character to the specified width using the default (right) numeric - alignment. - - **Example**:: - - MemoryWriter out; - out << pad(hex(0xcafe), 8, '0'); - // out.str() == "0000cafe" - - \endrst - */ -template -IntFormatSpec, Char> pad( - int value, unsigned width, Char fill = ' '); - -#define FMT_DEFINE_INT_FORMATTERS(TYPE) \ -inline IntFormatSpec > bin(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'b'>()); \ -} \ - \ -inline IntFormatSpec > oct(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'o'>()); \ -} \ - \ -inline IntFormatSpec > hex(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'x'>()); \ -} \ - \ -inline IntFormatSpec > hexu(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'X'>()); \ -} \ - \ -template \ -inline IntFormatSpec > pad( \ - IntFormatSpec > f, unsigned width) { \ - return IntFormatSpec >( \ - f.value(), AlignTypeSpec(width, ' ')); \ -} \ - \ -/* For compatibility with older compilers we provide two overloads for pad, */ \ -/* one that takes a fill character and one that doesn't. In the future this */ \ -/* can be replaced with one overload making the template argument Char */ \ -/* default to char (C++11). */ \ -template \ -inline IntFormatSpec, Char> pad( \ - IntFormatSpec, Char> f, \ - unsigned width, Char fill) { \ - return IntFormatSpec, Char>( \ - f.value(), AlignTypeSpec(width, fill)); \ -} \ - \ -inline IntFormatSpec > pad( \ - TYPE value, unsigned width) { \ - return IntFormatSpec >( \ - value, AlignTypeSpec<0>(width, ' ')); \ -} \ - \ -template \ -inline IntFormatSpec, Char> pad( \ - TYPE value, unsigned width, Char fill) { \ - return IntFormatSpec, Char>( \ - value, AlignTypeSpec<0>(width, fill)); \ -} - -FMT_DEFINE_INT_FORMATTERS(int) -FMT_DEFINE_INT_FORMATTERS(long) -FMT_DEFINE_INT_FORMATTERS(unsigned) -FMT_DEFINE_INT_FORMATTERS(unsigned long) -FMT_DEFINE_INT_FORMATTERS(LongLong) -FMT_DEFINE_INT_FORMATTERS(ULongLong) - -/** - \rst - Returns a string formatter that pads the formatted argument with the fill - character to the specified width using the default (left) string alignment. - - **Example**:: - - std::string s = str(MemoryWriter() << pad("abc", 8)); - // s == "abc " - - \endrst - */ -template -inline StrFormatSpec pad( - const Char *str, unsigned width, Char fill = ' ') -{ - return StrFormatSpec(str, width, fill); -} - -inline StrFormatSpec pad( - const wchar_t *str, unsigned width, char fill = ' ') -{ - return StrFormatSpec(str, width, fill); -} - -namespace internal -{ - -template -class ArgMap -{ -private: - typedef std::vector< - std::pair, internal::Arg> > MapType; - typedef typename MapType::value_type Pair; - - MapType map_; - -public: - FMT_API void init(const ArgList &args); - - const internal::Arg *find(const fmt::BasicStringRef &name) const - { - // The list is unsorted, so just return the first matching name. - for (typename MapType::const_iterator it = map_.begin(), end = map_.end(); - it != end; ++it) - { - if (it->first == name) - return &it->second; - } - return FMT_NULL; - } -}; - -template -class ArgFormatterBase : public ArgVisitor -{ -private: - BasicWriter &writer_; - Spec &spec_; - - FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase); - - void write_pointer(const void *p) - { - spec_.flags_ = HASH_FLAG; - spec_.type_ = 'x'; - writer_.write_int(reinterpret_cast(p), spec_); - } - - // workaround MSVC two-phase lookup issue - typedef internal::Arg Arg; - -protected: - BasicWriter &writer() - { - return writer_; - } - Spec &spec() - { - return spec_; - } - - void write(bool value) - { - const char *str_value = value ? "true" : "false"; - Arg::StringValue str = { str_value, std::strlen(str_value) }; - writer_.write_str(str, spec_); - } - - void write(const char *value) - { - Arg::StringValue str = {value, value ? std::strlen(value) : 0}; - writer_.write_str(str, spec_); - } - -public: - typedef Spec SpecType; - - ArgFormatterBase(BasicWriter &w, Spec &s) - : writer_(w), spec_(s) {} - - template - void visit_any_int(T value) - { - writer_.write_int(value, spec_); - } - - template - void visit_any_double(T value) - { - writer_.write_double(value, spec_); - } - - void visit_bool(bool value) - { - if (spec_.type_) - { - visit_any_int(value); - return; - } - write(value); - } - - void visit_char(int value) - { - if (spec_.type_ && spec_.type_ != 'c') - { - spec_.flags_ |= CHAR_FLAG; - writer_.write_int(value, spec_); - return; - } - if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) - FMT_THROW(FormatError("invalid format specifier for char")); - typedef typename BasicWriter::CharPtr CharPtr; - Char fill = internal::CharTraits::cast(spec_.fill()); - CharPtr out = CharPtr(); - const unsigned CHAR_SIZE = 1; - if (spec_.width_ > CHAR_SIZE) - { - out = writer_.grow_buffer(spec_.width_); - if (spec_.align_ == ALIGN_RIGHT) - { - std::uninitialized_fill_n(out, spec_.width_ - CHAR_SIZE, fill); - out += spec_.width_ - CHAR_SIZE; - } - else if (spec_.align_ == ALIGN_CENTER) - { - out = writer_.fill_padding(out, spec_.width_, - internal::const_check(CHAR_SIZE), fill); - } - else - { - std::uninitialized_fill_n(out + CHAR_SIZE, - spec_.width_ - CHAR_SIZE, fill); - } - } - else - { - out = writer_.grow_buffer(CHAR_SIZE); - } - *out = internal::CharTraits::cast(value); - } - - void visit_cstring(const char *value) - { - if (spec_.type_ == 'p') - return write_pointer(value); - write(value); - } - - // Qualification with "internal" here and below is a workaround for nvcc. - void visit_string(internal::Arg::StringValue value) - { - writer_.write_str(value, spec_); - } - - using ArgVisitor::visit_wstring; - - void visit_wstring(internal::Arg::StringValue value) - { - writer_.write_str(value, spec_); - } - - void visit_pointer(const void *value) - { - if (spec_.type_ && spec_.type_ != 'p') - report_unknown_type(spec_.type_, "pointer"); - write_pointer(value); - } -}; - -class FormatterBase -{ -private: - ArgList args_; - int next_arg_index_; - - // Returns the argument with specified index. - FMT_API Arg do_get_arg(unsigned arg_index, const char *&error); - -protected: - const ArgList &args() const - { - return args_; - } - - explicit FormatterBase(const ArgList &args) - { - args_ = args; - next_arg_index_ = 0; - } - - // Returns the next argument. - Arg next_arg(const char *&error) - { - if (next_arg_index_ >= 0) - return do_get_arg(internal::to_unsigned(next_arg_index_++), error); - error = "cannot switch from manual to automatic argument indexing"; - return Arg(); - } - - // Checks if manual indexing is used and returns the argument with - // specified index. - Arg get_arg(unsigned arg_index, const char *&error) - { - return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg(); - } - - bool check_no_auto_index(const char *&error) - { - if (next_arg_index_ > 0) - { - error = "cannot switch from automatic to manual argument indexing"; - return false; - } - next_arg_index_ = -1; - return true; - } - - template - void write(BasicWriter &w, const Char *start, const Char *end) - { - if (start != end) - w << BasicStringRef(start, internal::to_unsigned(end - start)); - } -}; -} // namespace internal - -/** - \rst - An argument formatter based on the `curiously recurring template pattern - `_. - - To use `~fmt::BasicArgFormatter` define a subclass that implements some or - all of the visit methods with the same signatures as the methods in - `~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`. - Pass the subclass as the *Impl* template parameter. When a formatting - function processes an argument, it will dispatch to a visit method - specific to the argument type. For example, if the argument type is - ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass - will be called. If the subclass doesn't contain a method with this signature, - then a corresponding method of `~fmt::BasicArgFormatter` or its superclass - will be called. - \endrst - */ -template -class BasicArgFormatter : public internal::ArgFormatterBase -{ -private: - BasicFormatter &formatter_; - const Char *format_; - -public: - /** - \rst - Constructs an argument formatter object. - *formatter* is a reference to the main formatter object, *spec* contains - format specifier information for standard argument types, and *fmt* points - to the part of the format string being parsed for custom argument types. - \endrst - */ - BasicArgFormatter(BasicFormatter &formatter, - Spec &spec, const Char *fmt) - : internal::ArgFormatterBase(formatter.writer(), spec), - formatter_(formatter), format_(fmt) {} - - /** Formats an argument of a custom (user-defined) type. */ - void visit_custom(internal::Arg::CustomValue c) - { - c.format(&formatter_, c.value, &format_); - } -}; - -/** The default argument formatter. */ -template -class ArgFormatter : - public BasicArgFormatter, Char, FormatSpec> -{ -public: - /** Constructs an argument formatter object. */ - ArgFormatter(BasicFormatter &formatter, - FormatSpec &spec, const Char *fmt) - : BasicArgFormatter, - Char, FormatSpec>(formatter, spec, fmt) {} -}; - -/** This template formats data and writes the output to a writer. */ -template -class BasicFormatter : private internal::FormatterBase -{ -public: - /** The character type for the output. */ - typedef CharType Char; - -private: - BasicWriter &writer_; - internal::ArgMap map_; - - FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter); - - using internal::FormatterBase::get_arg; - - // Checks if manual indexing is used and returns the argument with - // specified name. - internal::Arg get_arg(BasicStringRef arg_name, const char *&error); - - // Parses argument index and returns corresponding argument. - internal::Arg parse_arg_index(const Char *&s); - - // Parses argument name and returns corresponding argument. - internal::Arg parse_arg_name(const Char *&s); - -public: - /** - \rst - Constructs a ``BasicFormatter`` object. References to the arguments and - the writer are stored in the formatter object so make sure they have - appropriate lifetimes. - \endrst - */ - BasicFormatter(const ArgList &args, BasicWriter &w) - : internal::FormatterBase(args), writer_(w) {} - - /** Returns a reference to the writer associated with this formatter. */ - BasicWriter &writer() - { - return writer_; - } - - /** Formats stored arguments and writes the output to the writer. */ - void format(BasicCStringRef format_str); - - // Formats a single argument and advances format_str, a format string pointer. - const Char *format(const Char *&format_str, const internal::Arg &arg); -}; - -// Generates a comma-separated list with results of applying f to -// numbers 0..n-1. -# define FMT_GEN(n, f) FMT_GEN##n(f) -# define FMT_GEN1(f) f(0) -# define FMT_GEN2(f) FMT_GEN1(f), f(1) -# define FMT_GEN3(f) FMT_GEN2(f), f(2) -# define FMT_GEN4(f) FMT_GEN3(f), f(3) -# define FMT_GEN5(f) FMT_GEN4(f), f(4) -# define FMT_GEN6(f) FMT_GEN5(f), f(5) -# define FMT_GEN7(f) FMT_GEN6(f), f(6) -# define FMT_GEN8(f) FMT_GEN7(f), f(7) -# define FMT_GEN9(f) FMT_GEN8(f), f(8) -# define FMT_GEN10(f) FMT_GEN9(f), f(9) -# define FMT_GEN11(f) FMT_GEN10(f), f(10) -# define FMT_GEN12(f) FMT_GEN11(f), f(11) -# define FMT_GEN13(f) FMT_GEN12(f), f(12) -# define FMT_GEN14(f) FMT_GEN13(f), f(13) -# define FMT_GEN15(f) FMT_GEN14(f), f(14) - -namespace internal -{ -inline uint64_t make_type() -{ - return 0; -} - -template -inline uint64_t make_type(const T &arg) -{ - return MakeValue< BasicFormatter >::type(arg); -} - -template - struct ArgArray; - -template -struct ArgArray -{ - typedef Value Type[N > 0 ? N : 1]; - -template -static Value make(const T &value) -{ -#ifdef __clang__ - Value result = MakeValue(value); - // Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang: - // https://github.com/fmtlib/fmt/issues/276 - (void)result.custom.format; - return result; -#else - return MakeValue(value); -#endif -} - }; - -template -struct ArgArray -{ - typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE - - template - static Arg make(const T &value) - { - return MakeArg(value); - } -}; - -#if FMT_USE_VARIADIC_TEMPLATES -template -inline uint64_t make_type(const Arg &first, const Args & ... tail) -{ - return make_type(first) | (make_type(tail...) << 4); -} - -#else - -struct ArgType -{ - uint64_t type; - - ArgType() : type(0) {} - - template - ArgType(const T &arg) : type(make_type(arg)) {} -}; - -# define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType() - -inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) -{ - return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) | - (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) | - (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) | - (t12.type << 48) | (t13.type << 52) | (t14.type << 56); -} -#endif -} // namespace internal - -# define FMT_MAKE_TEMPLATE_ARG(n) typename T##n -# define FMT_MAKE_ARG_TYPE(n) T##n -# define FMT_MAKE_ARG(n) const T##n &v##n -# define FMT_ASSIGN_char(n) \ - arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter >(v##n) -# define FMT_ASSIGN_wchar_t(n) \ - arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter >(v##n) - -#if FMT_USE_VARIADIC_TEMPLATES -// Defines a variadic function returning void. -# define FMT_VARIADIC_VOID(func, arg_type) \ - template \ - void func(arg_type arg0, const Args & ... args) { \ - typedef fmt::internal::ArgArray ArgArray; \ - typename ArgArray::Type array{ \ - ArgArray::template make >(args)...}; \ - func(arg0, fmt::ArgList(fmt::internal::make_type(args...), array)); \ - } - -// Defines a variadic constructor. -# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ - template \ - ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ - typedef fmt::internal::ArgArray ArgArray; \ - typename ArgArray::Type array{ \ - ArgArray::template make >(args)...}; \ - func(arg0, arg1, fmt::ArgList(fmt::internal::make_type(args...), array)); \ - } - -#else - -# define FMT_MAKE_REF(n) \ - fmt::internal::MakeValue< fmt::BasicFormatter >(v##n) -# define FMT_MAKE_REF2(n) v##n - -// Defines a wrapper for a function taking one argument of type arg_type -// and n additional arguments of arbitrary types. -# define FMT_WRAP1(func, arg_type, n) \ - template \ - inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ - const fmt::internal::ArgArray::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \ - func(arg1, fmt::ArgList( \ - fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \ - } - -// Emulates a variadic function returning void on a pre-C++11 compiler. -# define FMT_VARIADIC_VOID(func, arg_type) \ - inline void func(arg_type arg) { func(arg, fmt::ArgList()); } \ - FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \ - FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \ - FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \ - FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \ - FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10) - -# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \ - template \ - ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ - const fmt::internal::ArgArray::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \ - func(arg0, arg1, fmt::ArgList( \ - fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \ - } - -// Emulates a variadic constructor on a pre-C++11 compiler. -# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 10) -#endif - -// Generates a comma-separated list with results of applying f to pairs -// (argument, index). -#define FMT_FOR_EACH1(f, x0) f(x0, 0) -#define FMT_FOR_EACH2(f, x0, x1) \ - FMT_FOR_EACH1(f, x0), f(x1, 1) -#define FMT_FOR_EACH3(f, x0, x1, x2) \ - FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2) -#define FMT_FOR_EACH4(f, x0, x1, x2, x3) \ - FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3) -#define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \ - FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4) -#define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \ - FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5) -#define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \ - FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6) -#define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \ - FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7) -#define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \ - FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8) -#define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \ - FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9) - -/** - An error returned by an operating system or a language runtime, - for example a file opening error. -*/ -class SystemError : public internal::RuntimeError -{ -private: - FMT_API void init(int err_code, CStringRef format_str, ArgList args); - -protected: - int error_code_; - - typedef char Char; // For FMT_VARIADIC_CTOR. - - SystemError() {} - -public: - /** - \rst - Constructs a :class:`fmt::SystemError` object with a description - formatted with `fmt::format_system_error`. *message* and additional - arguments passed into the constructor are formatted similarly to - `fmt::format`. - - **Example**:: - - // This throws a SystemError with the description - // cannot open file 'madeup': No such file or directory - // or similar (system message may vary). - const char *filename = "madeup"; - std::FILE *file = std::fopen(filename, "r"); - if (!file) - throw fmt::SystemError(errno, "cannot open file '{}'", filename); - \endrst - */ - SystemError(int error_code, CStringRef message) - { - init(error_code, message, ArgList()); - } - FMT_DEFAULTED_COPY_CTOR(SystemError) - FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef) - - FMT_API ~SystemError() FMT_DTOR_NOEXCEPT; - - int error_code() const - { - return error_code_; - } -}; - -/** - \rst - Formats an error returned by an operating system or a language runtime, - for example a file opening error, and writes it to *out* in the following - form: - - .. parsed-literal:: - **: ** - - where ** is the passed message and ** is - the system message corresponding to the error code. - *error_code* is a system error code as given by ``errno``. - If *error_code* is not a valid error code such as -1, the system message - may look like "Unknown error -1" and is platform-dependent. - \endrst - */ -FMT_API void format_system_error(fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT; - -/** - \rst - This template provides operations for formatting and writing data into - a character stream. The output is stored in a buffer provided by a subclass - such as :class:`fmt::BasicMemoryWriter`. - - You can use one of the following typedefs for common character types: - - +---------+----------------------+ - | Type | Definition | - +=========+======================+ - | Writer | BasicWriter | - +---------+----------------------+ - | WWriter | BasicWriter | - +---------+----------------------+ - - \endrst - */ -template -class BasicWriter -{ -private: - // Output buffer. - Buffer &buffer_; - - FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter); - - typedef typename internal::CharTraits::CharPtr CharPtr; - -#if FMT_SECURE_SCL - // Returns pointer value. - static Char *get(CharPtr p) - { - return p.base(); - } -#else - static Char *get(Char *p) - { - return p; - } -#endif - - // Fills the padding around the content and returns the pointer to the - // content area. - static CharPtr fill_padding(CharPtr buffer, - unsigned total_size, std::size_t content_size, wchar_t fill); - - // Grows the buffer by n characters and returns a pointer to the newly - // allocated area. - CharPtr grow_buffer(std::size_t n) - { - std::size_t size = buffer_.size(); - buffer_.resize(size + n); - return internal::make_ptr(&buffer_[size], n); - } - - // Writes an unsigned decimal integer. - template - Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) - { - unsigned num_digits = internal::count_digits(value); - Char *ptr = get(grow_buffer(prefix_size + num_digits)); - internal::format_decimal(ptr + prefix_size, value, num_digits); - return ptr; - } - - // Writes a decimal integer. - template - void write_decimal(Int value) - { - typedef typename internal::IntTraits::MainType MainType; - MainType abs_value = static_cast(value); - if (internal::is_negative(value)) - { - abs_value = 0 - abs_value; - *write_unsigned_decimal(abs_value, 1) = '-'; - } - else - { - write_unsigned_decimal(abs_value, 0); - } - } - - // Prepare a buffer for integer formatting. - CharPtr prepare_int_buffer(unsigned num_digits, - const EmptySpec &, const char *prefix, unsigned prefix_size) - { - unsigned size = prefix_size + num_digits; - CharPtr p = grow_buffer(size); - std::uninitialized_copy(prefix, prefix + prefix_size, p); - return p + size - 1; - } - - template - CharPtr prepare_int_buffer(unsigned num_digits, - const Spec &spec, const char *prefix, unsigned prefix_size); - - // Formats an integer. - template - void write_int(T value, Spec spec); - - // Formats a floating-point number (double or long double). - template - void write_double(T value, const Spec &spec); - - // Writes a formatted string. - template - CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec); - - template - void write_str(const internal::Arg::StringValue &str, - const Spec &spec); - - // This following methods are private to disallow writing wide characters - // and strings to a char stream. If you want to print a wide string as a - // pointer as std::ostream does, cast it to const void*. - // Do not implement! - void operator<<(typename internal::WCharHelper::Unsupported); - void operator<<( - typename internal::WCharHelper::Unsupported); - - // Appends floating-point length specifier to the format string. - // The second argument is only used for overload resolution. - void append_float_length(Char *&format_ptr, long double) - { - *format_ptr++ = 'L'; - } - - template - void append_float_length(Char *&, T) {} - - template - friend class internal::ArgFormatterBase; - - template - friend class BasicPrintfArgFormatter; - -protected: - /** - Constructs a ``BasicWriter`` object. - */ - explicit BasicWriter(Buffer &b) : buffer_(b) {} - -public: - /** - \rst - Destroys a ``BasicWriter`` object. - \endrst - */ - virtual ~BasicWriter() {} - - /** - Returns the total number of characters written. - */ - std::size_t size() const - { - return buffer_.size(); - } - - /** - Returns a pointer to the output buffer content. No terminating null - character is appended. - */ - const Char *data() const FMT_NOEXCEPT - { - return &buffer_[0]; - } - - /** - Returns a pointer to the output buffer content with terminating null - character appended. - */ - const Char *c_str() const - { - std::size_t size = buffer_.size(); - buffer_.reserve(size + 1); - buffer_[size] = '\0'; - return &buffer_[0]; - } - - /** - \rst - Returns the content of the output buffer as an `std::string`. - \endrst - */ - std::basic_string str() const - { - return std::basic_string(&buffer_[0], buffer_.size()); - } - - /** - \rst - Writes formatted data. - - *args* is an argument list representing arbitrary arguments. - - **Example**:: - - MemoryWriter out; - out.write("Current point:\n"); - out.write("({:+f}, {:+f})", -3.14, 3.14); - - This will write the following output to the ``out`` object: - - .. code-block:: none - - Current point: - (-3.140000, +3.140000) - - The output can be accessed using :func:`data()`, :func:`c_str` or - :func:`str` methods. - - See also :ref:`syntax`. - \endrst - */ - void write(BasicCStringRef format, ArgList args) - { - BasicFormatter(args, *this).format(format); - } - FMT_VARIADIC_VOID(write, BasicCStringRef) - - BasicWriter &operator<<(int value) - { - write_decimal(value); - return *this; - } - BasicWriter &operator<<(unsigned value) - { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(long value) - { - write_decimal(value); - return *this; - } - BasicWriter &operator<<(unsigned long value) - { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(LongLong value) - { - write_decimal(value); - return *this; - } - - /** - \rst - Formats *value* and writes it to the stream. - \endrst - */ - BasicWriter &operator<<(ULongLong value) - { - return *this << IntFormatSpec(value); - } - - BasicWriter &operator<<(double value) - { - write_double(value, FormatSpec()); - return *this; - } - - /** - \rst - Formats *value* using the general format for floating-point numbers - (``'g'``) and writes it to the stream. - \endrst - */ - BasicWriter &operator<<(long double value) - { - write_double(value, FormatSpec()); - return *this; - } - - /** - Writes a character to the stream. - */ - BasicWriter &operator<<(char value) - { - buffer_.push_back(value); - return *this; - } - - BasicWriter &operator<<( - typename internal::WCharHelper::Supported value) - { - buffer_.push_back(value); - return *this; - } - - /** - \rst - Writes *value* to the stream. - \endrst - */ - BasicWriter &operator<<(fmt::BasicStringRef value) - { - const Char *str = value.data(); - buffer_.append(str, str + value.size()); - return *this; - } - - BasicWriter &operator<<( - typename internal::WCharHelper::Supported value) - { - const char *str = value.data(); - buffer_.append(str, str + value.size()); - return *this; - } - - template - BasicWriter &operator<<(IntFormatSpec spec) - { - internal::CharTraits::convert(FillChar()); - write_int(spec.value(), spec); - return *this; - } - - template - BasicWriter &operator<<(const StrFormatSpec &spec) - { - const StrChar *s = spec.str(); - write_str(s, std::char_traits::length(s), spec); - return *this; - } - - void clear() FMT_NOEXCEPT { buffer_.clear(); } - - Buffer &buffer() FMT_NOEXCEPT { return buffer_; } -}; - -template -template -typename BasicWriter::CharPtr BasicWriter::write_str( - const StrChar *s, std::size_t size, const AlignSpec &spec) -{ - CharPtr out = CharPtr(); - if (spec.width() > size) - { - out = grow_buffer(spec.width()); - Char fill = internal::CharTraits::cast(spec.fill()); - if (spec.align() == ALIGN_RIGHT) - { - std::uninitialized_fill_n(out, spec.width() - size, fill); - out += spec.width() - size; - } - else if (spec.align() == ALIGN_CENTER) - { - out = fill_padding(out, spec.width(), size, fill); - } - else - { - std::uninitialized_fill_n(out + size, spec.width() - size, fill); - } - } - else - { - out = grow_buffer(size); - } - std::uninitialized_copy(s, s + size, out); - return out; -} - -template -template -void BasicWriter::write_str( - const internal::Arg::StringValue &s, const Spec &spec) -{ - // Check if StrChar is convertible to Char. - internal::CharTraits::convert(StrChar()); - if (spec.type_ && spec.type_ != 's') - internal::report_unknown_type(spec.type_, "string"); - const StrChar *str_value = s.value; - std::size_t str_size = s.size; - if (str_size == 0) - { - if (!str_value) - { - FMT_THROW(FormatError("string pointer is null")); - } - } - std::size_t precision = static_cast(spec.precision_); - if (spec.precision_ >= 0 && precision < str_size) - str_size = precision; - write_str(str_value, str_size, spec); -} - -template -typename BasicWriter::CharPtr -BasicWriter::fill_padding( - CharPtr buffer, unsigned total_size, - std::size_t content_size, wchar_t fill) -{ - std::size_t padding = total_size - content_size; - std::size_t left_padding = padding / 2; - Char fill_char = internal::CharTraits::cast(fill); - std::uninitialized_fill_n(buffer, left_padding, fill_char); - buffer += left_padding; - CharPtr content = buffer; - std::uninitialized_fill_n(buffer + content_size, - padding - left_padding, fill_char); - return content; -} - -template -template -typename BasicWriter::CharPtr -BasicWriter::prepare_int_buffer( - unsigned num_digits, const Spec &spec, - const char *prefix, unsigned prefix_size) -{ - unsigned width = spec.width(); - Alignment align = spec.align(); - Char fill = internal::CharTraits::cast(spec.fill()); - if (spec.precision() > static_cast(num_digits)) - { - // Octal prefix '0' is counted as a digit, so ignore it if precision - // is specified. - if (prefix_size > 0 && prefix[prefix_size - 1] == '0') - --prefix_size; - unsigned number_size = - prefix_size + internal::to_unsigned(spec.precision()); - AlignSpec subspec(number_size, '0', ALIGN_NUMERIC); - if (number_size >= width) - return prepare_int_buffer(num_digits, subspec, prefix, prefix_size); - buffer_.reserve(width); - unsigned fill_size = width - number_size; - if (align != ALIGN_LEFT) - { - CharPtr p = grow_buffer(fill_size); - std::uninitialized_fill(p, p + fill_size, fill); - } - CharPtr result = prepare_int_buffer( - num_digits, subspec, prefix, prefix_size); - if (align == ALIGN_LEFT) - { - CharPtr p = grow_buffer(fill_size); - std::uninitialized_fill(p, p + fill_size, fill); - } - return result; - } - unsigned size = prefix_size + num_digits; - if (width <= size) - { - CharPtr p = grow_buffer(size); - std::uninitialized_copy(prefix, prefix + prefix_size, p); - return p + size - 1; - } - CharPtr p = grow_buffer(width); - CharPtr end = p + width; - if (align == ALIGN_LEFT) - { - std::uninitialized_copy(prefix, prefix + prefix_size, p); - p += size; - std::uninitialized_fill(p, end, fill); - } - else if (align == ALIGN_CENTER) - { - p = fill_padding(p, width, size, fill); - std::uninitialized_copy(prefix, prefix + prefix_size, p); - p += size; - } - else - { - if (align == ALIGN_NUMERIC) - { - if (prefix_size != 0) - { - p = std::uninitialized_copy(prefix, prefix + prefix_size, p); - size -= prefix_size; - } - } - else - { - std::uninitialized_copy(prefix, prefix + prefix_size, end - size); - } - std::uninitialized_fill(p, end - size, fill); - p = end; - } - return p - 1; -} - -template -template -void BasicWriter::write_int(T value, Spec spec) -{ - unsigned prefix_size = 0; - typedef typename internal::IntTraits::MainType UnsignedType; - UnsignedType abs_value = static_cast(value); - char prefix[4] = ""; - if (internal::is_negative(value)) - { - prefix[0] = '-'; - ++prefix_size; - abs_value = 0 - abs_value; - } - else if (spec.flag(SIGN_FLAG)) - { - prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' '; - ++prefix_size; - } - switch (spec.type()) - { - case 0: - case 'd': - { - unsigned num_digits = internal::count_digits(abs_value); - CharPtr p = prepare_int_buffer(num_digits, spec, prefix, prefix_size) + 1; - internal::format_decimal(get(p), abs_value, 0); - break; - } - case 'x': - case 'X': - { - UnsignedType n = abs_value; - if (spec.flag(HASH_FLAG)) - { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type_prefix(); - } - unsigned num_digits = 0; - do - { - ++num_digits; - } - while ((n >>= 4) != 0); - Char *p = get(prepare_int_buffer( - num_digits, spec, prefix, prefix_size)); - n = abs_value; - const char *digits = spec.type() == 'x' ? - "0123456789abcdef" : "0123456789ABCDEF"; - do - { - *p-- = digits[n & 0xf]; - } - while ((n >>= 4) != 0); - break; - } - case 'b': - case 'B': - { - UnsignedType n = abs_value; - if (spec.flag(HASH_FLAG)) - { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type_prefix(); - } - unsigned num_digits = 0; - do - { - ++num_digits; - } - while ((n >>= 1) != 0); - Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); - n = abs_value; - do - { - *p-- = static_cast('0' + (n & 1)); - } - while ((n >>= 1) != 0); - break; - } - case 'o': - { - UnsignedType n = abs_value; - if (spec.flag(HASH_FLAG)) - prefix[prefix_size++] = '0'; - unsigned num_digits = 0; - do - { - ++num_digits; - } - while ((n >>= 3) != 0); - Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); - n = abs_value; - do - { - *p-- = static_cast('0' + (n & 7)); - } - while ((n >>= 3) != 0); - break; - } - case 'n': - { - unsigned num_digits = internal::count_digits(abs_value); - fmt::StringRef sep = ""; -#if !(defined(ANDROID) || defined(__ANDROID__)) - sep = internal::thousands_sep(std::localeconv()); -#endif - unsigned size = static_cast( - num_digits + sep.size() * ((num_digits - 1) / 3)); - CharPtr p = prepare_int_buffer(size, spec, prefix, prefix_size) + 1; - internal::format_decimal(get(p), abs_value, 0, internal::ThousandsSep(sep)); - break; - } - default: - internal::report_unknown_type( - spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer"); - break; - } -} - -template -template -void BasicWriter::write_double(T value, const Spec &spec) -{ - // Check type. - char type = spec.type(); - bool upper = false; - switch (type) - { - case 0: - type = 'g'; - break; - case 'e': - case 'f': - case 'g': - case 'a': - break; - case 'F': -#if FMT_MSC_VER - // MSVC's printf doesn't support 'F'. - type = 'f'; -#endif - // Fall through. - case 'E': - case 'G': - case 'A': - upper = true; - break; - default: - internal::report_unknown_type(type, "double"); - break; - } - - char sign = 0; - // Use isnegative instead of value < 0 because the latter is always - // false for NaN. - if (internal::FPUtil::isnegative(static_cast(value))) - { - sign = '-'; - value = -value; - } - else if (spec.flag(SIGN_FLAG)) - { - sign = spec.flag(PLUS_FLAG) ? '+' : ' '; - } - - if (internal::FPUtil::isnotanumber(value)) - { - // Format NaN ourselves because sprintf's output is not consistent - // across platforms. - std::size_t nan_size = 4; - const char *nan = upper ? " NAN" : " nan"; - if (!sign) - { - --nan_size; - ++nan; - } - CharPtr out = write_str(nan, nan_size, spec); - if (sign) - *out = sign; - return; - } - - if (internal::FPUtil::isinfinity(value)) - { - // Format infinity ourselves because sprintf's output is not consistent - // across platforms. - std::size_t inf_size = 4; - const char *inf = upper ? " INF" : " inf"; - if (!sign) - { - --inf_size; - ++inf; - } - CharPtr out = write_str(inf, inf_size, spec); - if (sign) - *out = sign; - return; - } - - std::size_t offset = buffer_.size(); - unsigned width = spec.width(); - if (sign) - { - buffer_.reserve(buffer_.size() + (width > 1u ? width : 1u)); - if (width > 0) - --width; - ++offset; - } - - // Build format string. - enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg - Char format[MAX_FORMAT_SIZE]; - Char *format_ptr = format; - *format_ptr++ = '%'; - unsigned width_for_sprintf = width; - if (spec.flag(HASH_FLAG)) - *format_ptr++ = '#'; - if (spec.align() == ALIGN_CENTER) - { - width_for_sprintf = 0; - } - else - { - if (spec.align() == ALIGN_LEFT) - *format_ptr++ = '-'; - if (width != 0) - *format_ptr++ = '*'; - } - if (spec.precision() >= 0) - { - *format_ptr++ = '.'; - *format_ptr++ = '*'; - } - - append_float_length(format_ptr, value); - *format_ptr++ = type; - *format_ptr = '\0'; - - // Format using snprintf. - Char fill = internal::CharTraits::cast(spec.fill()); - unsigned n = 0; - Char *start = FMT_NULL; - for (;;) - { - std::size_t buffer_size = buffer_.capacity() - offset; -#if FMT_MSC_VER - // MSVC's vsnprintf_s doesn't work with zero size, so reserve - // space for at least one extra character to make the size non-zero. - // Note that the buffer's capacity will increase by more than 1. - if (buffer_size == 0) - { - buffer_.reserve(offset + 1); - buffer_size = buffer_.capacity() - offset; - } -#endif - start = &buffer_[offset]; - int result = internal::CharTraits::format_float( - start, buffer_size, format, width_for_sprintf, spec.precision(), value); - if (result >= 0) - { - n = internal::to_unsigned(result); - if (offset + n < buffer_.capacity()) - break; // The buffer is large enough - continue with formatting. - buffer_.reserve(offset + n + 1); - } - else - { - // If result is negative we ask to increase the capacity by at least 1, - // but as std::vector, the buffer grows exponentially. - buffer_.reserve(buffer_.capacity() + 1); - } - } - if (sign) - { - if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || - *start != ' ') - { - *(start - 1) = sign; - sign = 0; - } - else - { - *(start - 1) = fill; - } - ++n; - } - if (spec.align() == ALIGN_CENTER && spec.width() > n) - { - width = spec.width(); - CharPtr p = grow_buffer(width); - std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char)); - fill_padding(p, spec.width(), n, fill); - return; - } - if (spec.fill() != ' ' || sign) - { - while (*start == ' ') - *start++ = fill; - if (sign) - *(start - 1) = sign; - } - grow_buffer(n); -} - -/** - \rst - This class template provides operations for formatting and writing data - into a character stream. The output is stored in a memory buffer that grows - dynamically. - - You can use one of the following typedefs for common character types - and the standard allocator: - - +---------------+-----------------------------------------------------+ - | Type | Definition | - +===============+=====================================================+ - | MemoryWriter | BasicMemoryWriter> | - +---------------+-----------------------------------------------------+ - | WMemoryWriter | BasicMemoryWriter> | - +---------------+-----------------------------------------------------+ - - **Example**:: - - MemoryWriter out; - out << "The answer is " << 42 << "\n"; - out.write("({:+f}, {:+f})", -3.14, 3.14); - - This will write the following output to the ``out`` object: - - .. code-block:: none - - The answer is 42 - (-3.140000, +3.140000) - - The output can be converted to an ``std::string`` with ``out.str()`` or - accessed as a C string with ``out.c_str()``. - \endrst - */ -template > -class BasicMemoryWriter : public BasicWriter -{ -private: - internal::MemoryBuffer buffer_; - -public: - explicit BasicMemoryWriter(const Allocator& alloc = Allocator()) - : BasicWriter(buffer_), buffer_(alloc) {} - -#if FMT_USE_RVALUE_REFERENCES - /** - \rst - Constructs a :class:`fmt::BasicMemoryWriter` object moving the content - of the other object to it. - \endrst - */ - BasicMemoryWriter(BasicMemoryWriter &&other) - : BasicWriter(buffer_), buffer_(std::move(other.buffer_)) - { - } - - /** - \rst - Moves the content of the other ``BasicMemoryWriter`` object to this one. - \endrst - */ - BasicMemoryWriter &operator=(BasicMemoryWriter &&other) - { - buffer_ = std::move(other.buffer_); - return *this; - } -#endif -}; - -typedef BasicMemoryWriter MemoryWriter; -typedef BasicMemoryWriter WMemoryWriter; - -/** - \rst - This class template provides operations for formatting and writing data - into a fixed-size array. For writing into a dynamically growing buffer - use :class:`fmt::BasicMemoryWriter`. - - Any write method will throw ``std::runtime_error`` if the output doesn't fit - into the array. - - You can use one of the following typedefs for common character types: - - +--------------+---------------------------+ - | Type | Definition | - +==============+===========================+ - | ArrayWriter | BasicArrayWriter | - +--------------+---------------------------+ - | WArrayWriter | BasicArrayWriter | - +--------------+---------------------------+ - \endrst - */ -template -class BasicArrayWriter : public BasicWriter -{ -private: - internal::FixedBuffer buffer_; - -public: - /** - \rst - Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the - given size. - \endrst - */ - BasicArrayWriter(Char *array, std::size_t size) - : BasicWriter(buffer_), buffer_(array, size) {} - - /** - \rst - Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the - size known at compile time. - \endrst - */ - template - explicit BasicArrayWriter(Char (&array)[SIZE]) - : BasicWriter(buffer_), buffer_(array, SIZE) {} -}; - -typedef BasicArrayWriter ArrayWriter; -typedef BasicArrayWriter WArrayWriter; - -// Reports a system error without throwing an exception. -// Can be used to report errors from destructors. -FMT_API void report_system_error(int error_code, - StringRef message) FMT_NOEXCEPT; - -#if FMT_USE_WINDOWS_H - -/** A Windows error. */ -class WindowsError : public SystemError -{ -private: - FMT_API void init(int error_code, CStringRef format_str, ArgList args); - -public: - /** - \rst - Constructs a :class:`fmt::WindowsError` object with the description - of the form - - .. parsed-literal:: - **: ** - - where ** is the formatted message and ** is the - system message corresponding to the error code. - *error_code* is a Windows error code as given by ``GetLastError``. - If *error_code* is not a valid error code such as -1, the system message - will look like "error -1". - - **Example**:: - - // This throws a WindowsError with the description - // cannot open file 'madeup': The system cannot find the file specified. - // or similar (system message may vary). - const char *filename = "madeup"; - LPOFSTRUCT of = LPOFSTRUCT(); - HFILE file = OpenFile(filename, &of, OF_READ); - if (file == HFILE_ERROR) { - throw fmt::WindowsError(GetLastError(), - "cannot open file '{}'", filename); - } - \endrst - */ - WindowsError(int error_code, CStringRef message) - { - init(error_code, message, ArgList()); - } - FMT_VARIADIC_CTOR(WindowsError, init, int, CStringRef) -}; - -// Reports a Windows error without throwing an exception. -// Can be used to report errors from destructors. -FMT_API void report_windows_error(int error_code, - StringRef message) FMT_NOEXCEPT; - -#endif - -enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; - -/** - Formats a string and prints it to stdout using ANSI escape sequences - to specify color (experimental). - Example: - print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23); - */ -FMT_API void print_colored(Color c, CStringRef format, ArgList args); - -/** - \rst - Formats arguments and returns the result as a string. - - **Example**:: - - std::string message = format("The answer is {}", 42); - \endrst -*/ -inline std::string format(CStringRef format_str, ArgList args) -{ - MemoryWriter w; - w.write(format_str, args); - return w.str(); -} - -inline std::wstring format(WCStringRef format_str, ArgList args) -{ - WMemoryWriter w; - w.write(format_str, args); - return w.str(); -} - -/** - \rst - Prints formatted data to the file *f*. - - **Example**:: - - print(stderr, "Don't {}!", "panic"); - \endrst - */ -FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args); - -/** - \rst - Prints formatted data to ``stdout``. - - **Example**:: - - print("Elapsed time: {0:.2f} seconds", 1.23); - \endrst - */ -FMT_API void print(CStringRef format_str, ArgList args); - -/** - Fast integer formatter. - */ -class FormatInt -{ -private: - // Buffer should be large enough to hold all digits (digits10 + 1), - // a sign and a null character. - enum {BUFFER_SIZE = std::numeric_limits::digits10 + 3}; - mutable char buffer_[BUFFER_SIZE]; - char *str_; - - // Formats value in reverse and returns the number of digits. - char *format_decimal(ULongLong value) - { - char *buffer_end = buffer_ + BUFFER_SIZE - 1; - while (value >= 100) - { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = static_cast((value % 100) * 2); - value /= 100; - *--buffer_end = internal::Data::DIGITS[index + 1]; - *--buffer_end = internal::Data::DIGITS[index]; - } - if (value < 10) - { - *--buffer_end = static_cast('0' + value); - return buffer_end; - } - unsigned index = static_cast(value * 2); - *--buffer_end = internal::Data::DIGITS[index + 1]; - *--buffer_end = internal::Data::DIGITS[index]; - return buffer_end; - } - - void FormatSigned(LongLong value) - { - ULongLong abs_value = static_cast(value); - bool negative = value < 0; - if (negative) - abs_value = 0 - abs_value; - str_ = format_decimal(abs_value); - if (negative) - *--str_ = '-'; - } - -public: - explicit FormatInt(int value) - { - FormatSigned(value); - } - explicit FormatInt(long value) - { - FormatSigned(value); - } - explicit FormatInt(LongLong value) - { - FormatSigned(value); - } - explicit FormatInt(unsigned value) : str_(format_decimal(value)) {} - explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {} - explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {} - - /** Returns the number of characters written to the output buffer. */ - std::size_t size() const - { - return internal::to_unsigned(buffer_ - str_ + BUFFER_SIZE - 1); - } - - /** - Returns a pointer to the output buffer content. No terminating null - character is appended. - */ - const char *data() const - { - return str_; - } - - /** - Returns a pointer to the output buffer content with terminating null - character appended. - */ - const char *c_str() const - { - buffer_[BUFFER_SIZE - 1] = '\0'; - return str_; - } - - /** - \rst - Returns the content of the output buffer as an ``std::string``. - \endrst - */ - std::string str() const - { - return std::string(str_, size()); - } -}; - -// Formats a decimal integer value writing into buffer and returns -// a pointer to the end of the formatted string. This function doesn't -// write a terminating null character. -template -inline void format_decimal(char *&buffer, T value) -{ - typedef typename internal::IntTraits::MainType MainType; - MainType abs_value = static_cast(value); - if (internal::is_negative(value)) - { - *buffer++ = '-'; - abs_value = 0 - abs_value; - } - if (abs_value < 100) - { - if (abs_value < 10) - { - *buffer++ = static_cast('0' + abs_value); - return; - } - unsigned index = static_cast(abs_value * 2); - *buffer++ = internal::Data::DIGITS[index]; - *buffer++ = internal::Data::DIGITS[index + 1]; - return; - } - unsigned num_digits = internal::count_digits(abs_value); - internal::format_decimal(buffer, abs_value, num_digits); - buffer += num_digits; -} - -/** - \rst - Returns a named argument for formatting functions. - - **Example**:: - - print("Elapsed time: {s:.2f} seconds", arg("s", 1.23)); - - \endrst - */ -template -inline internal::NamedArgWithType arg(StringRef name, const T &arg) -{ - return internal::NamedArgWithType(name, arg); -} - -template -inline internal::NamedArgWithType arg(WStringRef name, const T &arg) -{ - return internal::NamedArgWithType(name, arg); -} - -// The following two functions are deleted intentionally to disable -// nested named arguments as in ``format("{}", arg("a", arg("b", 42)))``. -template -void arg(StringRef, const internal::NamedArg&) FMT_DELETED_OR_UNDEFINED; -template -void arg(WStringRef, const internal::NamedArg&) FMT_DELETED_OR_UNDEFINED; -} - -#if FMT_GCC_VERSION -// Use the system_header pragma to suppress warnings about variadic macros -// because suppressing -Wvariadic-macros with the diagnostic pragma doesn't -// work. It is used at the end because we want to suppress as little warnings -// as possible. -# pragma GCC system_header -#endif - -// This is used to work around VC++ bugs in handling variadic macros. -#define FMT_EXPAND(args) args - -// Returns the number of arguments. -// Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s. -#define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N()) -#define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__)) -#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N -#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - -#define FMT_FOR_EACH_(N, f, ...) \ - FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) -#define FMT_FOR_EACH(f, ...) \ - FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__)) - -#define FMT_ADD_ARG_NAME(type, index) type arg##index -#define FMT_GET_ARG_NAME(type, index) arg##index - -#if FMT_USE_VARIADIC_TEMPLATES -# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ - template \ - ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ - const Args & ... args) { \ - typedef fmt::internal::ArgArray ArgArray; \ - typename ArgArray::Type array{ \ - ArgArray::template make >(args)...}; \ - call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ - fmt::ArgList(fmt::internal::make_type(args...), array)); \ - } -#else -// Defines a wrapper for a function taking __VA_ARGS__ arguments -// and n additional arguments of arbitrary types. -# define FMT_WRAP(Char, ReturnType, func, call, n, ...) \ - template \ - inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ - FMT_GEN(n, FMT_MAKE_ARG)) { \ - fmt::internal::ArgArray::Type arr; \ - FMT_GEN(n, FMT_ASSIGN_##Char); \ - call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \ - fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \ - } - -# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ - inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \ - call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \ - } \ - FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__) -#endif // FMT_USE_VARIADIC_TEMPLATES - -/** - \rst - Defines a variadic function with the specified return type, function name - and argument types passed as variable arguments to this macro. - - **Example**:: - - void print_error(const char *file, int line, const char *format, - fmt::ArgList args) { - fmt::print("{}: {}: ", file, line); - fmt::print(format, args); - } - FMT_VARIADIC(void, print_error, const char *, int, const char *) - - ``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that - don't implement variadic templates. You don't have to use this macro if - you don't need legacy compiler support and can use variadic templates - directly:: - - template - void print_error(const char *file, int line, const char *format, - const Args & ... args) { - fmt::print("{}: {}: ", file, line); - fmt::print(format, args...); - } - \endrst - */ -#define FMT_VARIADIC(ReturnType, func, ...) \ - FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__) - -#define FMT_VARIADIC_W(ReturnType, func, ...) \ - FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) - -#define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id) - -#define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id) - -/** - \rst - Convenient macro to capture the arguments' names and values into several - ``fmt::arg(name, value)``. - - **Example**:: - - int x = 1, y = 2; - print("point: ({x}, {y})", FMT_CAPTURE(x, y)); - // same as: - // print("point: ({x}, {y})", arg("x", x), arg("y", y)); - - \endrst - */ -#define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__) - -#define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__) - -namespace fmt -{ -FMT_VARIADIC(std::string, format, CStringRef) -FMT_VARIADIC_W(std::wstring, format, WCStringRef) -FMT_VARIADIC(void, print, CStringRef) -FMT_VARIADIC(void, print, std::FILE *, CStringRef) -FMT_VARIADIC(void, print_colored, Color, CStringRef) - -namespace internal -{ -template -inline bool is_name_start(Char c) -{ - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; -} - -// Parses an unsigned integer advancing s to the end of the parsed input. -// This function assumes that the first character of s is a digit. -template -unsigned parse_nonnegative_int(const Char *&s) -{ - assert('0' <= *s && *s <= '9'); - unsigned value = 0; - do - { - unsigned new_value = value * 10 + (*s++ - '0'); - // Check if value wrapped around. - if (new_value < value) - { - value = (std::numeric_limits::max)(); - break; - } - value = new_value; - } - while ('0' <= *s && *s <= '9'); - // Convert to unsigned to prevent a warning. - unsigned max_int = (std::numeric_limits::max)(); - if (value > max_int) - FMT_THROW(FormatError("number is too big")); - return value; -} - -inline void require_numeric_argument(const Arg &arg, char spec) -{ - if (arg.type > Arg::LAST_NUMERIC_TYPE) - { - std::string message = - fmt::format("format specifier '{}' requires numeric argument", spec); - FMT_THROW(fmt::FormatError(message)); - } -} - -template -void check_sign(const Char *&s, const Arg &arg) -{ - char sign = static_cast(*s); - require_numeric_argument(arg, sign); - if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) - { - FMT_THROW(FormatError(fmt::format( - "format specifier '{}' requires signed argument", sign))); - } - ++s; -} -} // namespace internal - -template -inline internal::Arg BasicFormatter::get_arg( - BasicStringRef arg_name, const char *&error) -{ - if (check_no_auto_index(error)) - { - map_.init(args()); - const internal::Arg *arg = map_.find(arg_name); - if (arg) - return *arg; - error = "argument not found"; - } - return internal::Arg(); -} - -template -inline internal::Arg BasicFormatter::parse_arg_index(const Char *&s) -{ - const char *error = FMT_NULL; - internal::Arg arg = *s < '0' || *s > '9' ? - next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error); - if (error) - { - FMT_THROW(FormatError( - *s != '}' && *s != ':' ? "invalid format string" : error)); - } - return arg; -} - -template -inline internal::Arg BasicFormatter::parse_arg_name(const Char *&s) -{ - assert(internal::is_name_start(*s)); - const Char *start = s; - Char c; - do - { - c = *++s; - } - while (internal::is_name_start(c) || ('0' <= c && c <= '9')); - const char *error = FMT_NULL; - internal::Arg arg = get_arg(BasicStringRef(start, s - start), error); - if (error) - FMT_THROW(FormatError(error)); - return arg; -} - -template -const Char *BasicFormatter::format( - const Char *&format_str, const internal::Arg &arg) -{ - using internal::Arg; - const Char *s = format_str; - typename ArgFormatter::SpecType spec; - if (*s == ':') - { - if (arg.type == Arg::CUSTOM) - { - arg.custom.format(this, arg.custom.value, &s); - return s; - } - ++s; - // Parse fill and alignment. - if (Char c = *s) - { - const Char *p = s + 1; - spec.align_ = ALIGN_DEFAULT; - do - { - switch (*p) - { - case '<': - spec.align_ = ALIGN_LEFT; - break; - case '>': - spec.align_ = ALIGN_RIGHT; - break; - case '=': - spec.align_ = ALIGN_NUMERIC; - break; - case '^': - spec.align_ = ALIGN_CENTER; - break; - } - if (spec.align_ != ALIGN_DEFAULT) - { - if (p != s) - { - if (c == '}') break; - if (c == '{') - FMT_THROW(FormatError("invalid fill character '{'")); - s += 2; - spec.fill_ = c; - } - else ++s; - if (spec.align_ == ALIGN_NUMERIC) - require_numeric_argument(arg, '='); - break; - } - } - while (--p >= s); - } - - // Parse sign. - switch (*s) - { - case '+': - check_sign(s, arg); - spec.flags_ |= SIGN_FLAG | PLUS_FLAG; - break; - case '-': - check_sign(s, arg); - spec.flags_ |= MINUS_FLAG; - break; - case ' ': - check_sign(s, arg); - spec.flags_ |= SIGN_FLAG; - break; - } - - if (*s == '#') - { - require_numeric_argument(arg, '#'); - spec.flags_ |= HASH_FLAG; - ++s; - } - - // Parse zero flag. - if (*s == '0') - { - require_numeric_argument(arg, '0'); - spec.align_ = ALIGN_NUMERIC; - spec.fill_ = '0'; - ++s; - } - - // Parse width. - if ('0' <= *s && *s <= '9') - { - spec.width_ = internal::parse_nonnegative_int(s); - } - else if (*s == '{') - { - ++s; - Arg width_arg = internal::is_name_start(*s) ? - parse_arg_name(s) : parse_arg_index(s); - if (*s++ != '}') - FMT_THROW(FormatError("invalid format string")); - ULongLong value = 0; - switch (width_arg.type) - { - case Arg::INT: - if (width_arg.int_value < 0) - FMT_THROW(FormatError("negative width")); - value = width_arg.int_value; - break; - case Arg::UINT: - value = width_arg.uint_value; - break; - case Arg::LONG_LONG: - if (width_arg.long_long_value < 0) - FMT_THROW(FormatError("negative width")); - value = width_arg.long_long_value; - break; - case Arg::ULONG_LONG: - value = width_arg.ulong_long_value; - break; - default: - FMT_THROW(FormatError("width is not integer")); - } - if (value > (std::numeric_limits::max)()) - FMT_THROW(FormatError("number is too big")); - spec.width_ = static_cast(value); - } - - // Parse precision. - if (*s == '.') - { - ++s; - spec.precision_ = 0; - if ('0' <= *s && *s <= '9') - { - spec.precision_ = internal::parse_nonnegative_int(s); - } - else if (*s == '{') - { - ++s; - Arg precision_arg = internal::is_name_start(*s) ? - parse_arg_name(s) : parse_arg_index(s); - if (*s++ != '}') - FMT_THROW(FormatError("invalid format string")); - ULongLong value = 0; - switch (precision_arg.type) - { - case Arg::INT: - if (precision_arg.int_value < 0) - FMT_THROW(FormatError("negative precision")); - value = precision_arg.int_value; - break; - case Arg::UINT: - value = precision_arg.uint_value; - break; - case Arg::LONG_LONG: - if (precision_arg.long_long_value < 0) - FMT_THROW(FormatError("negative precision")); - value = precision_arg.long_long_value; - break; - case Arg::ULONG_LONG: - value = precision_arg.ulong_long_value; - break; - default: - FMT_THROW(FormatError("precision is not integer")); - } - if (value > (std::numeric_limits::max)()) - FMT_THROW(FormatError("number is too big")); - spec.precision_ = static_cast(value); - } - else - { - FMT_THROW(FormatError("missing precision specifier")); - } - if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) - { - FMT_THROW(FormatError( - fmt::format("precision not allowed in {} format specifier", - arg.type == Arg::POINTER ? "pointer" : "integer"))); - } - } - - // Parse type. - if (*s != '}' && *s) - spec.type_ = static_cast(*s++); - } - - if (*s++ != '}') - FMT_THROW(FormatError("missing '}' in format string")); - - // Format argument. - ArgFormatter(*this, spec, s - 1).visit(arg); - return s; -} - -template -void BasicFormatter::format(BasicCStringRef format_str) -{ - const Char *s = format_str.c_str(); - const Char *start = s; - while (*s) - { - Char c = *s++; - if (c != '{' && c != '}') continue; - if (*s == c) - { - write(writer_, start, s); - start = ++s; - continue; - } - if (c == '}') - FMT_THROW(FormatError("unmatched '}' in format string")); - write(writer_, start, s - 1); - internal::Arg arg = internal::is_name_start(*s) ? - parse_arg_name(s) : parse_arg_index(s); - start = s = format(s, arg); - } - write(writer_, start, s); -} - -template -struct ArgJoin -{ - It first; - It last; - BasicCStringRef sep; - - ArgJoin(It first, It last, const BasicCStringRef& sep) : - first(first), - last(last), - sep(sep) {} -}; - -template -ArgJoin join(It first, It last, const BasicCStringRef& sep) -{ - return ArgJoin(first, last, sep); -} - -template -ArgJoin join(It first, It last, const BasicCStringRef& sep) -{ - return ArgJoin(first, last, sep); -} - -#if FMT_HAS_GXX_CXX11 -template -auto join(const Range& range, const BasicCStringRef& sep) --> ArgJoin -{ - return join(std::begin(range), std::end(range), sep); -} - -template -auto join(const Range& range, const BasicCStringRef& sep) --> ArgJoin -{ - return join(std::begin(range), std::end(range), sep); -} -#endif - -template -void format_arg(fmt::BasicFormatter &f, - const Char *&format_str, const ArgJoin& e) -{ - const Char* end = format_str; - if (*end == ':') - ++end; - while (*end && *end != '}') - ++end; - if (*end != '}') - FMT_THROW(FormatError("missing '}' in format string")); - - It it = e.first; - if (it != e.last) - { - const Char* save = format_str; - f.format(format_str, internal::MakeArg >(*it++)); - while (it != e.last) - { - f.writer().write(e.sep); - format_str = save; - f.format(format_str, internal::MakeArg >(*it++)); - } - } - format_str = end + 1; -} -} // namespace fmt - -#if FMT_USE_USER_DEFINED_LITERALS -namespace fmt -{ -namespace internal -{ - -template -struct UdlFormat -{ - const Char *str; - - template - auto operator()(Args && ... args) const - -> decltype(format(str, std::forward(args)...)) - { - return format(str, std::forward(args)...); - } -}; - -template -struct UdlArg -{ - const Char *str; - - template - NamedArgWithType operator=(T &&value) const - { - return {str, std::forward(value)}; - } -}; - -} // namespace internal - -inline namespace literals -{ - -/** - \rst - C++11 literal equivalent of :func:`fmt::format`. - - **Example**:: - - using namespace fmt::literals; - std::string message = "The answer is {}"_format(42); - \endrst - */ -inline internal::UdlFormat -operator"" _format(const char *s, std::size_t) -{ - return {s}; -} -inline internal::UdlFormat -operator"" _format(const wchar_t *s, std::size_t) -{ - return {s}; -} - -/** - \rst - C++11 literal equivalent of :func:`fmt::arg`. - - **Example**:: - - using namespace fmt::literals; - print("Elapsed time: {s:.2f} seconds", "s"_a=1.23); - \endrst - */ -inline internal::UdlArg -operator"" _a(const char *s, std::size_t) -{ - return {s}; -} -inline internal::UdlArg -operator"" _a(const wchar_t *s, std::size_t) -{ - return {s}; -} - -} // inline namespace literals -} // namespace fmt -#endif // FMT_USE_USER_DEFINED_LITERALS - -// Restore warnings. -#if FMT_GCC_VERSION >= 406 -# pragma GCC diagnostic pop -#endif - -#if defined(__clang__) && !defined(FMT_ICC_VERSION) -# pragma clang diagnostic pop -#endif - -#ifdef FMT_HEADER_ONLY -# define FMT_FUNC inline -# include "format.cc" -#else -# define FMT_FUNC -#endif - -#endif // FMT_FORMAT_H_ diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.cc b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.cc deleted file mode 100644 index 2d443f730..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* - Formatting library for C++ - std::ostream support - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - For the license information refer to format.h. - */ - -#include "ostream.h" - -namespace fmt { - -namespace internal { -FMT_FUNC void write(std::ostream &os, Writer &w) { - const char *data = w.data(); - typedef internal::MakeUnsigned::Type UnsignedStreamSize; - UnsignedStreamSize size = w.size(); - UnsignedStreamSize max_size = - internal::to_unsigned((std::numeric_limits::max)()); - do { - UnsignedStreamSize n = size <= max_size ? size : max_size; - os.write(data, static_cast(n)); - data += n; - size -= n; - } while (size != 0); -} -} - -FMT_FUNC void print(std::ostream &os, CStringRef format_str, ArgList args) { - MemoryWriter w; - w.write(format_str, args); - internal::write(os, w); -} -} // namespace fmt diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.h b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.h deleted file mode 100644 index cfb8e0355..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/ostream.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Formatting library for C++ - std::ostream support - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - For the license information refer to format.h. - */ - -#ifndef FMT_OSTREAM_H_ -#define FMT_OSTREAM_H_ - -#include "format.h" -#include - -namespace fmt -{ - -namespace internal -{ - -template -class FormatBuf : public std::basic_streambuf -{ -private: - typedef typename std::basic_streambuf::int_type int_type; - typedef typename std::basic_streambuf::traits_type traits_type; - - Buffer &buffer_; - -public: - FormatBuf(Buffer &buffer) : buffer_(buffer) {} - -protected: - // The put-area is actually always empty. This makes the implementation - // simpler and has the advantage that the streambuf and the buffer are always - // in sync and sputc never writes into uninitialized memory. The obvious - // disadvantage is that each call to sputc always results in a (virtual) call - // to overflow. There is no disadvantage here for sputn since this always - // results in a call to xsputn. - - int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE - { - if (!traits_type::eq_int_type(ch, traits_type::eof())) - buffer_.push_back(static_cast(ch)); - return ch; - } - - std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE - { - buffer_.append(s, s + count); - return count; - } -}; - -Yes &convert(std::ostream &); - -struct DummyStream : std::ostream -{ - DummyStream(); // Suppress a bogus warning in MSVC. - // Hide all operator<< overloads from std::ostream. - void operator<<(Null<>); -}; - -No &operator<<(std::ostream &, int); - -template -struct ConvertToIntImpl -{ - // Convert to int only if T doesn't have an overloaded operator<<. - enum - { - value = sizeof(convert(get() << get())) == sizeof(No) - }; -}; - -// Write the content of w to os. -FMT_API void write(std::ostream &os, Writer &w); -} // namespace internal - -// Formats a value. -template -void format_arg(BasicFormatter &f, - const Char *&format_str, const T &value) -{ - internal::MemoryBuffer buffer; - - internal::FormatBuf format_buf(buffer); - std::basic_ostream output(&format_buf); - output << value; - - BasicStringRef str(&buffer[0], buffer.size()); - typedef internal::MakeArg< BasicFormatter > MakeArg; - format_str = f.format(format_str, MakeArg(str)); -} - -/** - \rst - Prints formatted data to the stream *os*. - - **Example**:: - - print(cerr, "Don't {}!", "panic"); - \endrst - */ -FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args); -FMT_VARIADIC(void, print, std::ostream &, CStringRef) -} // namespace fmt - -#ifdef FMT_HEADER_ONLY -# include "ostream.cc" -#endif - -#endif // FMT_OSTREAM_H_ diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.cc b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.cc deleted file mode 100644 index 356668c13..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.cc +++ /dev/null @@ -1,241 +0,0 @@ -/* - A C++ interface to POSIX functions. - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - For the license information refer to format.h. - */ - -// Disable bogus MSVC warnings. -#ifndef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS -#endif - -#include "posix.h" - -#include -#include -#include - -#ifndef _WIN32 -# include -#else -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include - -# define O_CREAT _O_CREAT -# define O_TRUNC _O_TRUNC - -# ifndef S_IRUSR -# define S_IRUSR _S_IREAD -# endif - -# ifndef S_IWUSR -# define S_IWUSR _S_IWRITE -# endif - -# ifdef __MINGW32__ -# define _SH_DENYNO 0x40 -# endif - -#endif // _WIN32 - -#ifdef fileno -# undef fileno -#endif - -namespace { -#ifdef _WIN32 -// Return type of read and write functions. -typedef int RWResult; - -// On Windows the count argument to read and write is unsigned, so convert -// it from size_t preventing integer overflow. -inline unsigned convert_rwcount(std::size_t count) { - return count <= UINT_MAX ? static_cast(count) : UINT_MAX; -} -#else -// Return type of read and write functions. -typedef ssize_t RWResult; - -inline std::size_t convert_rwcount(std::size_t count) { return count; } -#endif -} - -fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT { - if (file_ && FMT_SYSTEM(fclose(file_)) != 0) - fmt::report_system_error(errno, "cannot close file"); -} - -fmt::BufferedFile::BufferedFile( - fmt::CStringRef filename, fmt::CStringRef mode) { - FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), 0); - if (!file_) - FMT_THROW(SystemError(errno, "cannot open file {}", filename)); -} - -void fmt::BufferedFile::close() { - if (!file_) - return; - int result = FMT_SYSTEM(fclose(file_)); - file_ = FMT_NULL; - if (result != 0) - FMT_THROW(SystemError(errno, "cannot close file")); -} - -// A macro used to prevent expansion of fileno on broken versions of MinGW. -#define FMT_ARGS - -int fmt::BufferedFile::fileno() const { - int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_)); - if (fd == -1) - FMT_THROW(SystemError(errno, "cannot get file descriptor")); - return fd; -} - -fmt::File::File(fmt::CStringRef path, int oflag) { - int mode = S_IRUSR | S_IWUSR; -#if defined(_WIN32) && !defined(__MINGW32__) - fd_ = -1; - FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode)); -#else - FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode))); -#endif - if (fd_ == -1) - FMT_THROW(SystemError(errno, "cannot open file {}", path)); -} - -fmt::File::~File() FMT_NOEXCEPT { - // Don't retry close in case of EINTR! - // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html - if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0) - fmt::report_system_error(errno, "cannot close file"); -} - -void fmt::File::close() { - if (fd_ == -1) - return; - // Don't retry close in case of EINTR! - // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html - int result = FMT_POSIX_CALL(close(fd_)); - fd_ = -1; - if (result != 0) - FMT_THROW(SystemError(errno, "cannot close file")); -} - -fmt::LongLong fmt::File::size() const { -#ifdef _WIN32 - // Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT - // is less than 0x0500 as is the case with some default MinGW builds. - // Both functions support large file sizes. - DWORD size_upper = 0; - HANDLE handle = reinterpret_cast(_get_osfhandle(fd_)); - DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper)); - if (size_lower == INVALID_FILE_SIZE) { - DWORD error = GetLastError(); - if (error != NO_ERROR) - FMT_THROW(WindowsError(GetLastError(), "cannot get file size")); - } - fmt::ULongLong long_size = size_upper; - return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower; -#else - typedef struct stat Stat; - Stat file_stat = Stat(); - if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1) - FMT_THROW(SystemError(errno, "cannot get file attributes")); - FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(file_stat.st_size), - "return type of File::size is not large enough"); - return file_stat.st_size; -#endif -} - -std::size_t fmt::File::read(void *buffer, std::size_t count) { - RWResult result = 0; - FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count)))); - if (result < 0) - FMT_THROW(SystemError(errno, "cannot read from file")); - return internal::to_unsigned(result); -} - -std::size_t fmt::File::write(const void *buffer, std::size_t count) { - RWResult result = 0; - FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count)))); - if (result < 0) - FMT_THROW(SystemError(errno, "cannot write to file")); - return internal::to_unsigned(result); -} - -fmt::File fmt::File::dup(int fd) { - // Don't retry as dup doesn't return EINTR. - // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html - int new_fd = FMT_POSIX_CALL(dup(fd)); - if (new_fd == -1) - FMT_THROW(SystemError(errno, "cannot duplicate file descriptor {}", fd)); - return File(new_fd); -} - -void fmt::File::dup2(int fd) { - int result = 0; - FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); - if (result == -1) { - FMT_THROW(SystemError(errno, - "cannot duplicate file descriptor {} to {}", fd_, fd)); - } -} - -void fmt::File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT { - int result = 0; - FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); - if (result == -1) - ec = ErrorCode(errno); -} - -void fmt::File::pipe(File &read_end, File &write_end) { - // Close the descriptors first to make sure that assignments don't throw - // and there are no leaks. - read_end.close(); - write_end.close(); - int fds[2] = {}; -#ifdef _WIN32 - // Make the default pipe capacity same as on Linux 2.6.11+. - enum { DEFAULT_CAPACITY = 65536 }; - int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY)); -#else - // Don't retry as the pipe function doesn't return EINTR. - // http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html - int result = FMT_POSIX_CALL(pipe(fds)); -#endif - if (result != 0) - FMT_THROW(SystemError(errno, "cannot create pipe")); - // The following assignments don't throw because read_fd and write_fd - // are closed. - read_end = File(fds[0]); - write_end = File(fds[1]); -} - -fmt::BufferedFile fmt::File::fdopen(const char *mode) { - // Don't retry as fdopen doesn't return EINTR. - FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode)); - if (!f) - FMT_THROW(SystemError(errno, "cannot associate stream with file descriptor")); - BufferedFile file(f); - fd_ = -1; - return file; -} - -long fmt::getpagesize() { -#ifdef _WIN32 - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwPageSize; -#else - long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); - if (size < 0) - FMT_THROW(SystemError(errno, "cannot get memory page size")); - return size; -#endif -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.h b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.h deleted file mode 100644 index 693272500..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/posix.h +++ /dev/null @@ -1,424 +0,0 @@ -/* - A C++ interface to POSIX functions. - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - For the license information refer to format.h. - */ - -#ifndef FMT_POSIX_H_ -#define FMT_POSIX_H_ - -#if defined(__MINGW32__) || defined(__CYGWIN__) -// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/. -# undef __STRICT_ANSI__ -#endif - -#include -#include // for O_RDONLY -#include // for locale_t -#include -#include // for strtod_l - -#include - -#if defined __APPLE__ || defined(__FreeBSD__) -# include // for LC_NUMERIC_MASK on OS X -#endif - -#include "format.h" - -#ifndef FMT_POSIX -# if defined(_WIN32) && !defined(__MINGW32__) -// Fix warnings about deprecated symbols. -# define FMT_POSIX(call) _##call -# else -# define FMT_POSIX(call) call -# endif -#endif - -// Calls to system functions are wrapped in FMT_SYSTEM for testability. -#ifdef FMT_SYSTEM -# define FMT_POSIX_CALL(call) FMT_SYSTEM(call) -#else -# define FMT_SYSTEM(call) call -# ifdef _WIN32 -// Fix warnings about deprecated symbols. -# define FMT_POSIX_CALL(call) ::_##call -# else -# define FMT_POSIX_CALL(call) ::call -# endif -#endif - -// Retries the expression while it evaluates to error_result and errno -// equals to EINTR. -#ifndef _WIN32 -# define FMT_RETRY_VAL(result, expression, error_result) \ - do { \ - result = (expression); \ - } while (result == error_result && errno == EINTR) -#else -# define FMT_RETRY_VAL(result, expression, error_result) result = (expression) -#endif - -#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1) - -namespace fmt -{ - -// An error code. -class ErrorCode -{ -private: - int value_; - -public: -explicit ErrorCode(int value = 0) FMT_NOEXCEPT : - value_(value) {} - - int get() const FMT_NOEXCEPT - { - return value_; - } -}; - -// A buffered file. -class BufferedFile -{ -private: - FILE *file_; - - friend class File; - - explicit BufferedFile(FILE *f) : file_(f) {} - -public: - // Constructs a BufferedFile object which doesn't represent any file. -BufferedFile() FMT_NOEXCEPT : - file_(FMT_NULL) {} - - // Destroys the object closing the file it represents if any. - FMT_API ~BufferedFile() FMT_NOEXCEPT; - -#if !FMT_USE_RVALUE_REFERENCES - // Emulate a move constructor and a move assignment operator if rvalue - // references are not supported. - -private: - // A proxy object to emulate a move constructor. - // It is private to make it impossible call operator Proxy directly. - struct Proxy - { - FILE *file; - }; - -public: - // A "move constructor" for moving from a temporary. -BufferedFile(Proxy p) FMT_NOEXCEPT : - file_(p.file) {} - - // A "move constructor" for moving from an lvalue. -BufferedFile(BufferedFile &f) FMT_NOEXCEPT : - file_(f.file_) - { - f.file_ = FMT_NULL; - } - - // A "move assignment operator" for moving from a temporary. - BufferedFile &operator=(Proxy p) - { - close(); - file_ = p.file; - return *this; - } - - // A "move assignment operator" for moving from an lvalue. - BufferedFile &operator=(BufferedFile &other) - { - close(); - file_ = other.file_; - other.file_ = FMT_NULL; - return *this; - } - - // Returns a proxy object for moving from a temporary: - // BufferedFile file = BufferedFile(...); - operator Proxy() FMT_NOEXCEPT - { - Proxy p = {file_}; - file_ = FMT_NULL; - return p; - } - -#else -private: - FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile); - -public: -BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : - file_(other.file_) - { - other.file_ = FMT_NULL; - } - - BufferedFile& operator=(BufferedFile &&other) - { - close(); - file_ = other.file_; - other.file_ = FMT_NULL; - return *this; - } -#endif - - // Opens a file. - FMT_API BufferedFile(CStringRef filename, CStringRef mode); - - // Closes the file. - FMT_API void close(); - - // Returns the pointer to a FILE object representing this file. - FILE *get() const FMT_NOEXCEPT - { - return file_; - } - - // We place parentheses around fileno to workaround a bug in some versions - // of MinGW that define fileno as a macro. - FMT_API int (fileno)() const; - - void print(CStringRef format_str, const ArgList &args) - { - fmt::print(file_, format_str, args); - } - FMT_VARIADIC(void, print, CStringRef) -}; - -// A file. Closed file is represented by a File object with descriptor -1. -// Methods that are not declared with FMT_NOEXCEPT may throw -// fmt::SystemError in case of failure. Note that some errors such as -// closing the file multiple times will cause a crash on Windows rather -// than an exception. You can get standard behavior by overriding the -// invalid parameter handler with _set_invalid_parameter_handler. -class File -{ -private: - int fd_; // File descriptor. - - // Constructs a File object with a given descriptor. - explicit File(int fd) : fd_(fd) {} - -public: - // Possible values for the oflag argument to the constructor. - enum - { - RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only. - WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only. - RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing. - }; - - // Constructs a File object which doesn't represent any file. -File() FMT_NOEXCEPT : - fd_(-1) {} - - // Opens a file and constructs a File object representing this file. - FMT_API File(CStringRef path, int oflag); - -#if !FMT_USE_RVALUE_REFERENCES - // Emulate a move constructor and a move assignment operator if rvalue - // references are not supported. - -private: - // A proxy object to emulate a move constructor. - // It is private to make it impossible call operator Proxy directly. - struct Proxy - { - int fd; - }; - -public: - // A "move constructor" for moving from a temporary. -File(Proxy p) FMT_NOEXCEPT : - fd_(p.fd) {} - - // A "move constructor" for moving from an lvalue. -File(File &other) FMT_NOEXCEPT : - fd_(other.fd_) - { - other.fd_ = -1; - } - - // A "move assignment operator" for moving from a temporary. - File &operator=(Proxy p) - { - close(); - fd_ = p.fd; - return *this; - } - - // A "move assignment operator" for moving from an lvalue. - File &operator=(File &other) - { - close(); - fd_ = other.fd_; - other.fd_ = -1; - return *this; - } - - // Returns a proxy object for moving from a temporary: - // File file = File(...); - operator Proxy() FMT_NOEXCEPT - { - Proxy p = {fd_}; - fd_ = -1; - return p; - } - -#else -private: - FMT_DISALLOW_COPY_AND_ASSIGN(File); - -public: -File(File &&other) FMT_NOEXCEPT : - fd_(other.fd_) - { - other.fd_ = -1; - } - - File& operator=(File &&other) - { - close(); - fd_ = other.fd_; - other.fd_ = -1; - return *this; - } -#endif - - // Destroys the object closing the file it represents if any. - FMT_API ~File() FMT_NOEXCEPT; - - // Returns the file descriptor. - int descriptor() const FMT_NOEXCEPT - { - return fd_; - } - - // Closes the file. - FMT_API void close(); - - // Returns the file size. The size has signed type for consistency with - // stat::st_size. - FMT_API LongLong size() const; - - // Attempts to read count bytes from the file into the specified buffer. - FMT_API std::size_t read(void *buffer, std::size_t count); - - // Attempts to write count bytes from the specified buffer to the file. - FMT_API std::size_t write(const void *buffer, std::size_t count); - - // Duplicates a file descriptor with the dup function and returns - // the duplicate as a file object. - FMT_API static File dup(int fd); - - // Makes fd be the copy of this file descriptor, closing fd first if - // necessary. - FMT_API void dup2(int fd); - - // Makes fd be the copy of this file descriptor, closing fd first if - // necessary. - FMT_API void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT; - - // Creates a pipe setting up read_end and write_end file objects for reading - // and writing respectively. - FMT_API static void pipe(File &read_end, File &write_end); - - // Creates a BufferedFile object associated with this file and detaches - // this File object from the file. - FMT_API BufferedFile fdopen(const char *mode); -}; - -// Returns the memory page size. -long getpagesize(); - -#if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \ - !defined(__ANDROID__) && !defined(__CYGWIN__) -# define FMT_LOCALE -#endif - -#ifdef FMT_LOCALE -// A "C" numeric locale. -class Locale -{ -private: -# ifdef _MSC_VER - typedef _locale_t locale_t; - - enum { LC_NUMERIC_MASK = LC_NUMERIC }; - - static locale_t newlocale(int category_mask, const char *locale, locale_t) - { - return _create_locale(category_mask, locale); - } - - static void freelocale(locale_t locale) - { - _free_locale(locale); - } - - static double strtod_l(const char *nptr, char **endptr, _locale_t locale) - { - return _strtod_l(nptr, endptr, locale); - } -# endif - - locale_t locale_; - - FMT_DISALLOW_COPY_AND_ASSIGN(Locale); - -public: - typedef locale_t Type; - - Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", FMT_NULL)) - { - if (!locale_) - FMT_THROW(fmt::SystemError(errno, "cannot create locale")); - } - ~Locale() - { - freelocale(locale_); - } - - Type get() const - { - return locale_; - } - - // Converts string to floating-point number and advances str past the end - // of the parsed input. - double strtod(const char *&str) const - { - char *end = FMT_NULL; - double result = strtod_l(str, &end, locale_); - str = end; - return result; - } -}; -#endif // FMT_LOCALE -} // namespace fmt - -#if !FMT_USE_RVALUE_REFERENCES -namespace std -{ -// For compatibility with C++98. -inline fmt::BufferedFile &move(fmt::BufferedFile &f) -{ - return f; -} -inline fmt::File &move(fmt::File &f) -{ - return f; -} -} -#endif - -#endif // FMT_POSIX_H_ diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.cc b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.cc deleted file mode 100644 index 95d7a36ab..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* - Formatting library for C++ - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - For the license information refer to format.h. - */ - -#include "format.h" -#include "printf.h" - -namespace fmt { - -template -void printf(BasicWriter &w, BasicCStringRef format, ArgList args); - -FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) { - MemoryWriter w; - printf(w, format, args); - std::size_t size = w.size(); - return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast(size); -} - -#ifndef FMT_HEADER_ONLY - -template void PrintfFormatter::format(CStringRef format); -template void PrintfFormatter::format(WCStringRef format); - -#endif // FMT_HEADER_ONLY - -} // namespace fmt diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.h b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.h deleted file mode 100644 index 7861b460e..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/printf.h +++ /dev/null @@ -1,712 +0,0 @@ -/* - Formatting library for C++ - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - For the license information refer to format.h. - */ - -#ifndef FMT_PRINTF_H_ -#define FMT_PRINTF_H_ - -#include // std::fill_n -#include // std::numeric_limits - -#include "ostream.h" - -namespace fmt -{ -namespace internal -{ - -// Checks if a value fits in int - used to avoid warnings about comparing -// signed and unsigned integers. -template -struct IntChecker -{ - template - static bool fits_in_int(T value) - { - unsigned max = std::numeric_limits::max(); - return value <= max; - } - static bool fits_in_int(bool) - { - return true; - } -}; - -template <> -struct IntChecker -{ - template - static bool fits_in_int(T value) - { - return value >= std::numeric_limits::min() && - value <= std::numeric_limits::max(); - } - static bool fits_in_int(int) - { - return true; - } -}; - -class PrecisionHandler : public ArgVisitor -{ -public: - void report_unhandled_arg() - { - FMT_THROW(FormatError("precision is not integer")); - } - - template - int visit_any_int(T value) - { - if (!IntChecker::is_signed>::fits_in_int(value)) - FMT_THROW(FormatError("number is too big")); - return static_cast(value); - } -}; - -// IsZeroInt::visit(arg) returns true iff arg is a zero integer. -class IsZeroInt : public ArgVisitor -{ -public: - template - bool visit_any_int(T value) - { - return value == 0; - } -}; - -// returns the default type for format specific "%s" -class DefaultType : public ArgVisitor -{ -public: - char visit_char(int) - { - return 'c'; - } - - char visit_bool(bool) - { - return 's'; - } - - char visit_pointer(const void *) - { - return 'p'; - } - - template - char visit_any_int(T) - { - return 'd'; - } - - template - char visit_any_double(T) - { - return 'g'; - } - - char visit_unhandled_arg() - { - return 's'; - } -}; - -template -struct is_same -{ - enum { value = 0 }; -}; - -template -struct is_same -{ - enum { value = 1 }; -}; - -// An argument visitor that converts an integer argument to T for printf, -// if T is an integral type. If T is void, the argument is converted to -// corresponding signed or unsigned type depending on the type specifier: -// 'd' and 'i' - signed, other - unsigned) -template -class ArgConverter : public ArgVisitor, void> -{ -private: - internal::Arg &arg_; - wchar_t type_; - - FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter); - -public: - ArgConverter(internal::Arg &arg, wchar_t type) - : arg_(arg), type_(type) {} - - void visit_bool(bool value) - { - if (type_ != 's') - visit_any_int(value); - } - - void visit_char(char value) - { - if (type_ != 's') - visit_any_int(value); - } - - template - void visit_any_int(U value) - { - bool is_signed = type_ == 'd' || type_ == 'i'; - if (type_ == 's') - { - is_signed = std::numeric_limits::is_signed; - } - - using internal::Arg; - typedef typename internal::Conditional< - is_same::value, U, T>::type TargetType; - if (sizeof(TargetType) <= sizeof(int)) - { - // Extra casts are used to silence warnings. - if (is_signed) - { - arg_.type = Arg::INT; - arg_.int_value = static_cast(static_cast(value)); - } - else - { - arg_.type = Arg::UINT; - typedef typename internal::MakeUnsigned::Type Unsigned; - arg_.uint_value = static_cast(static_cast(value)); - } - } - else - { - if (is_signed) - { - arg_.type = Arg::LONG_LONG; - // glibc's printf doesn't sign extend arguments of smaller types: - // std::printf("%lld", -42); // prints "4294967254" - // but we don't have to do the same because it's a UB. - arg_.long_long_value = static_cast(value); - } - else - { - arg_.type = Arg::ULONG_LONG; - arg_.ulong_long_value = - static_cast::Type>(value); - } - } - } -}; - -// Converts an integer argument to char for printf. -class CharConverter : public ArgVisitor -{ -private: - internal::Arg &arg_; - - FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter); - -public: - explicit CharConverter(internal::Arg &arg) : arg_(arg) {} - - template - void visit_any_int(T value) - { - arg_.type = internal::Arg::CHAR; - arg_.int_value = static_cast(value); - } -}; - -// Checks if an argument is a valid printf width specifier and sets -// left alignment if it is negative. -class WidthHandler : public ArgVisitor -{ -private: - FormatSpec &spec_; - - FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler); - -public: - explicit WidthHandler(FormatSpec &spec) : spec_(spec) {} - - void report_unhandled_arg() - { - FMT_THROW(FormatError("width is not integer")); - } - - template - unsigned visit_any_int(T value) - { - typedef typename internal::IntTraits::MainType UnsignedType; - UnsignedType width = static_cast(value); - if (internal::is_negative(value)) - { - spec_.align_ = ALIGN_LEFT; - width = 0 - width; - } - unsigned int_max = std::numeric_limits::max(); - if (width > int_max) - FMT_THROW(FormatError("number is too big")); - return static_cast(width); - } -}; -} // namespace internal - -/** - \rst - A ``printf`` argument formatter based on the `curiously recurring template - pattern `_. - - To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some - or all of the visit methods with the same signatures as the methods in - `~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`. - Pass the subclass as the *Impl* template parameter. When a formatting - function processes an argument, it will dispatch to a visit method - specific to the argument type. For example, if the argument type is - ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass - will be called. If the subclass doesn't contain a method with this signature, - then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its - superclass will be called. - \endrst - */ -template -class BasicPrintfArgFormatter : - public internal::ArgFormatterBase -{ -private: - void write_null_pointer() - { - this->spec().type_ = 0; - this->write("(nil)"); - } - - typedef internal::ArgFormatterBase Base; - -public: - /** - \rst - Constructs an argument formatter object. - *writer* is a reference to the output writer and *spec* contains format - specifier information for standard argument types. - \endrst - */ - BasicPrintfArgFormatter(BasicWriter &w, Spec &s) - : internal::ArgFormatterBase(w, s) {} - - /** Formats an argument of type ``bool``. */ - void visit_bool(bool value) - { - Spec &fmt_spec = this->spec(); - if (fmt_spec.type_ != 's') - return this->visit_any_int(value); - fmt_spec.type_ = 0; - this->write(value); - } - - /** Formats a character. */ - void visit_char(int value) - { - const Spec &fmt_spec = this->spec(); - BasicWriter &w = this->writer(); - if (fmt_spec.type_ && fmt_spec.type_ != 'c') - w.write_int(value, fmt_spec); - typedef typename BasicWriter::CharPtr CharPtr; - CharPtr out = CharPtr(); - if (fmt_spec.width_ > 1) - { - Char fill = ' '; - out = w.grow_buffer(fmt_spec.width_); - if (fmt_spec.align_ != ALIGN_LEFT) - { - std::fill_n(out, fmt_spec.width_ - 1, fill); - out += fmt_spec.width_ - 1; - } - else - { - std::fill_n(out + 1, fmt_spec.width_ - 1, fill); - } - } - else - { - out = w.grow_buffer(1); - } - *out = static_cast(value); - } - - /** Formats a null-terminated C string. */ - void visit_cstring(const char *value) - { - if (value) - Base::visit_cstring(value); - else if (this->spec().type_ == 'p') - write_null_pointer(); - else - this->write("(null)"); - } - - /** Formats a pointer. */ - void visit_pointer(const void *value) - { - if (value) - return Base::visit_pointer(value); - this->spec().type_ = 0; - write_null_pointer(); - } - - /** Formats an argument of a custom (user-defined) type. */ - void visit_custom(internal::Arg::CustomValue c) - { - BasicFormatter formatter(ArgList(), this->writer()); - const Char format_str[] = {'}', 0}; - const Char *format = format_str; - c.format(&formatter, c.value, &format); - } -}; - -/** The default printf argument formatter. */ -template -class PrintfArgFormatter : - public BasicPrintfArgFormatter, Char, FormatSpec> -{ -public: - /** Constructs an argument formatter object. */ - PrintfArgFormatter(BasicWriter &w, FormatSpec &s) - : BasicPrintfArgFormatter, Char, FormatSpec>(w, s) {} -}; - -/** This template formats data and writes the output to a writer. */ -template > -class PrintfFormatter : private internal::FormatterBase -{ -private: - BasicWriter &writer_; - - void parse_flags(FormatSpec &spec, const Char *&s); - - // Returns the argument with specified index or, if arg_index is equal - // to the maximum unsigned value, the next argument. - internal::Arg get_arg( - const Char *s, - unsigned arg_index = (std::numeric_limits::max)()); - - // Parses argument index, flags and width and returns the argument index. - unsigned parse_header(const Char *&s, FormatSpec &spec); - -public: - /** - \rst - Constructs a ``PrintfFormatter`` object. References to the arguments and - the writer are stored in the formatter object so make sure they have - appropriate lifetimes. - \endrst - */ - explicit PrintfFormatter(const ArgList &al, BasicWriter &w) - : FormatterBase(al), writer_(w) {} - - /** Formats stored arguments and writes the output to the writer. */ - void format(BasicCStringRef format_str); -}; - -template -void PrintfFormatter::parse_flags(FormatSpec &spec, const Char *&s) -{ - for (;;) - { - switch (*s++) - { - case '-': - spec.align_ = ALIGN_LEFT; - break; - case '+': - spec.flags_ |= SIGN_FLAG | PLUS_FLAG; - break; - case '0': - spec.fill_ = '0'; - break; - case ' ': - spec.flags_ |= SIGN_FLAG; - break; - case '#': - spec.flags_ |= HASH_FLAG; - break; - default: - --s; - return; - } - } -} - -template -internal::Arg PrintfFormatter::get_arg(const Char *s, - unsigned arg_index) -{ - (void)s; - const char *error = FMT_NULL; - internal::Arg arg = arg_index == std::numeric_limits::max() ? - next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); - if (error) - FMT_THROW(FormatError(!*s ? "invalid format string" : error)); - return arg; -} - -template -unsigned PrintfFormatter::parse_header( - const Char *&s, FormatSpec &spec) -{ - unsigned arg_index = std::numeric_limits::max(); - Char c = *s; - if (c >= '0' && c <= '9') - { - // Parse an argument index (if followed by '$') or a width possibly - // preceded with '0' flag(s). - unsigned value = internal::parse_nonnegative_int(s); - if (*s == '$') // value is an argument index - { - ++s; - arg_index = value; - } - else - { - if (c == '0') - spec.fill_ = '0'; - if (value != 0) - { - // Nonzero value means that we parsed width and don't need to - // parse it or flags again, so return now. - spec.width_ = value; - return arg_index; - } - } - } - parse_flags(spec, s); - // Parse width. - if (*s >= '0' && *s <= '9') - { - spec.width_ = internal::parse_nonnegative_int(s); - } - else if (*s == '*') - { - ++s; - spec.width_ = internal::WidthHandler(spec).visit(get_arg(s)); - } - return arg_index; -} - -template -void PrintfFormatter::format(BasicCStringRef format_str) -{ - const Char *start = format_str.c_str(); - const Char *s = start; - while (*s) - { - Char c = *s++; - if (c != '%') continue; - if (*s == c) - { - write(writer_, start, s); - start = ++s; - continue; - } - write(writer_, start, s - 1); - - FormatSpec spec; - spec.align_ = ALIGN_RIGHT; - - // Parse argument index, flags and width. - unsigned arg_index = parse_header(s, spec); - - // Parse precision. - if (*s == '.') - { - ++s; - if ('0' <= *s && *s <= '9') - { - spec.precision_ = static_cast(internal::parse_nonnegative_int(s)); - } - else if (*s == '*') - { - ++s; - spec.precision_ = internal::PrecisionHandler().visit(get_arg(s)); - } - else - { - spec.precision_ = 0; - } - } - - using internal::Arg; - Arg arg = get_arg(s, arg_index); - if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg)) - spec.flags_ &= ~internal::to_unsigned(HASH_FLAG); - if (spec.fill_ == '0') - { - if (arg.type <= Arg::LAST_NUMERIC_TYPE) - spec.align_ = ALIGN_NUMERIC; - else - spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. - } - - // Parse length and convert the argument to the required type. - using internal::ArgConverter; - switch (*s++) - { - case 'h': - if (*s == 'h') - ArgConverter(arg, *++s).visit(arg); - else - ArgConverter(arg, *s).visit(arg); - break; - case 'l': - if (*s == 'l') - ArgConverter(arg, *++s).visit(arg); - else - ArgConverter(arg, *s).visit(arg); - break; - case 'j': - ArgConverter(arg, *s).visit(arg); - break; - case 'z': - ArgConverter(arg, *s).visit(arg); - break; - case 't': - ArgConverter(arg, *s).visit(arg); - break; - case 'L': - // printf produces garbage when 'L' is omitted for long double, no - // need to do the same. - break; - default: - --s; - ArgConverter(arg, *s).visit(arg); - } - - // Parse type. - if (!*s) - FMT_THROW(FormatError("invalid format string")); - spec.type_ = static_cast(*s++); - - if (spec.type_ == 's') - { - // set the format type to the default if 's' is specified - spec.type_ = internal::DefaultType().visit(arg); - } - - if (arg.type <= Arg::LAST_INTEGER_TYPE) - { - // Normalize type. - switch (spec.type_) - { - case 'i': - case 'u': - spec.type_ = 'd'; - break; - case 'c': - // TODO: handle wchar_t - internal::CharConverter(arg).visit(arg); - break; - } - } - - start = s; - - // Format argument. - AF(writer_, spec).visit(arg); - } - write(writer_, start, s); -} - -inline void printf(Writer &w, CStringRef format, ArgList args) -{ - PrintfFormatter(args, w).format(format); -} -FMT_VARIADIC(void, printf, Writer &, CStringRef) - -inline void printf(WWriter &w, WCStringRef format, ArgList args) -{ - PrintfFormatter(args, w).format(format); -} -FMT_VARIADIC(void, printf, WWriter &, WCStringRef) - -/** - \rst - Formats arguments and returns the result as a string. - - **Example**:: - - std::string message = fmt::sprintf("The answer is %d", 42); - \endrst -*/ -inline std::string sprintf(CStringRef format, ArgList args) -{ - MemoryWriter w; - printf(w, format, args); - return w.str(); -} -FMT_VARIADIC(std::string, sprintf, CStringRef) - -inline std::wstring sprintf(WCStringRef format, ArgList args) -{ - WMemoryWriter w; - printf(w, format, args); - return w.str(); -} -FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) - -/** - \rst - Prints formatted data to the file *f*. - - **Example**:: - - fmt::fprintf(stderr, "Don't %s!", "panic"); - \endrst - */ -FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args); -FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) - -/** - \rst - Prints formatted data to ``stdout``. - - **Example**:: - - fmt::printf("Elapsed time: %.2f seconds", 1.23); - \endrst - */ -inline int printf(CStringRef format, ArgList args) -{ - return fprintf(stdout, format, args); -} -FMT_VARIADIC(int, printf, CStringRef) - -/** - \rst - Prints formatted data to the stream *os*. - - **Example**:: - - fprintf(cerr, "Don't %s!", "panic"); - \endrst - */ -inline int fprintf(std::ostream &os, CStringRef format_str, ArgList args) -{ - MemoryWriter w; - printf(w, format_str, args); - internal::write(os, w); - return static_cast(w.size()); -} -FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef) -} // namespace fmt - -#ifdef FMT_HEADER_ONLY -# include "printf.cc" -#endif - -#endif // FMT_PRINTF_H_ diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/time.h b/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/time.h deleted file mode 100644 index 206d09209..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/bundled/time.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - Formatting library for C++ - time formatting - - Copyright (c) 2012 - 2016, Victor Zverovich - All rights reserved. - - For the license information refer to format.h. - */ - -#ifndef FMT_TIME_H_ -#define FMT_TIME_H_ - -#include "format.h" -#include - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4702) // unreachable code -# pragma warning(disable: 4996) // "deprecated" functions -#endif - -namespace fmt -{ -template -void format_arg(BasicFormatter &f, - const char *&format_str, const std::tm &tm) -{ - if (*format_str == ':') - ++format_str; - const char *end = format_str; - while (*end && *end != '}') - ++end; - if (*end != '}') - FMT_THROW(FormatError("missing '}' in format string")); - internal::MemoryBuffer format; - format.append(format_str, end + 1); - format[format.size() - 1] = '\0'; - Buffer &buffer = f.writer().buffer(); - std::size_t start = buffer.size(); - for (;;) - { - std::size_t size = buffer.capacity() - start; - std::size_t count = std::strftime(&buffer[start], size, &format[0], &tm); - if (count != 0) - { - buffer.resize(start + count); - break; - } - if (size >= format.size() * 256) - { - // If the buffer is 256 times larger than the format string, assume - // that `strftime` gives an empty result. There doesn't seem to be a - // better way to distinguish the two cases: - // https://github.com/fmtlib/fmt/issues/367 - break; - } - const std::size_t MIN_GROWTH = 10; - buffer.reserve(buffer.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH)); - } - format_str = end + 1; -} - -namespace internal -{ -inline Null<> localtime_r(...) -{ - return Null<>(); -} -inline Null<> localtime_s(...) -{ - return Null<>(); -} -inline Null<> gmtime_r(...) -{ - return Null<>(); -} -inline Null<> gmtime_s(...) -{ - return Null<>(); -} -} - -// Thread-safe replacement for std::localtime -inline std::tm localtime(std::time_t time) -{ - struct LocalTime - { - std::time_t time_; - std::tm tm_; - - LocalTime(std::time_t t): time_(t) {} - - bool run() - { - using namespace fmt::internal; - return handle(localtime_r(&time_, &tm_)); - } - - bool handle(std::tm *tm) - { - return tm != FMT_NULL; - } - - bool handle(internal::Null<>) - { - using namespace fmt::internal; - return fallback(localtime_s(&tm_, &time_)); - } - - bool fallback(int res) - { - return res == 0; - } - - bool fallback(internal::Null<>) - { - using namespace fmt::internal; - std::tm *tm = std::localtime(&time_); - if (tm) tm_ = *tm; - return tm != FMT_NULL; - } - }; - LocalTime lt(time); - if (lt.run()) - return lt.tm_; - // Too big time values may be unsupported. - FMT_THROW(fmt::FormatError("time_t value out of range")); - return std::tm(); -} - -// Thread-safe replacement for std::gmtime -inline std::tm gmtime(std::time_t time) -{ - struct GMTime - { - std::time_t time_; - std::tm tm_; - - GMTime(std::time_t t): time_(t) {} - - bool run() - { - using namespace fmt::internal; - return handle(gmtime_r(&time_, &tm_)); - } - - bool handle(std::tm *tm) - { - return tm != FMT_NULL; - } - - bool handle(internal::Null<>) - { - using namespace fmt::internal; - return fallback(gmtime_s(&tm_, &time_)); - } - - bool fallback(int res) - { - return res == 0; - } - - bool fallback(internal::Null<>) - { - std::tm *tm = std::gmtime(&time_); - if (tm != FMT_NULL) tm_ = *tm; - return tm != FMT_NULL; - } - }; - GMTime gt(time); - if (gt.run()) - return gt.tm_; - // Too big time values may be unsupported. - FMT_THROW(fmt::FormatError("time_t value out of range")); - return std::tm(); -} -} //namespace fmt - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -#endif // FMT_TIME_H_ diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/fmt.h b/fpga/thirdparty/spdlog/include/spdlog/fmt/fmt.h deleted file mode 100644 index 92ca4e50f..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/fmt.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright(c) 2016 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// -// Include a bundled header-only copy of fmtlib or an external one. -// By default spdlog include its own copy. -// - -#if !defined(SPDLOG_FMT_EXTERNAL) - -#ifndef FMT_HEADER_ONLY -#define FMT_HEADER_ONLY -#endif -#ifndef FMT_USE_WINDOWS_H -#define FMT_USE_WINDOWS_H 0 -#endif -#include "bundled/format.h" -#if defined(SPDLOG_FMT_PRINTF) -#include "bundled/printf.h" -#endif - -#else //external fmtlib - -#include -#if defined(SPDLOG_FMT_PRINTF) -#include -#endif - -#endif - diff --git a/fpga/thirdparty/spdlog/include/spdlog/fmt/ostr.h b/fpga/thirdparty/spdlog/include/spdlog/fmt/ostr.h deleted file mode 100644 index 5cdd5cd00..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/fmt/ostr.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright(c) 2016 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// include external or bundled copy of fmtlib's ostream support -// -#if !defined(SPDLOG_FMT_EXTERNAL) -#include "fmt.h" -#include "bundled/ostream.h" -#else -#include -#endif - - diff --git a/fpga/thirdparty/spdlog/include/spdlog/formatter.h b/fpga/thirdparty/spdlog/include/spdlog/formatter.h deleted file mode 100644 index 8bf0f43f8..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/formatter.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "details/log_msg.h" - -#include -#include -#include - -namespace spdlog -{ -namespace details -{ -class flag_formatter; -} - -class formatter -{ -public: - virtual ~formatter() {} - virtual void format(details::log_msg& msg) = 0; -}; - -class pattern_formatter SPDLOG_FINAL : public formatter -{ - -public: - explicit pattern_formatter(const std::string& pattern, pattern_time_type pattern_time = pattern_time_type::local); - pattern_formatter(const pattern_formatter&) = delete; - pattern_formatter& operator=(const pattern_formatter&) = delete; - void format(details::log_msg& msg) override; -private: - const std::string _pattern; - const pattern_time_type _pattern_time; - std::vector> _formatters; - std::tm get_time(details::log_msg& msg); - void handle_flag(char flag); - void compile_pattern(const std::string& pattern); -}; -} - -#include "details/pattern_formatter_impl.h" - diff --git a/fpga/thirdparty/spdlog/include/spdlog/logger.h b/fpga/thirdparty/spdlog/include/spdlog/logger.h deleted file mode 100644 index 742f667f1..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/logger.h +++ /dev/null @@ -1,110 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// Thread safe logger (except for set_pattern(..), set_formatter(..) and set_error_handler()) -// Has name, log level, vector of std::shared sink pointers and formatter -// Upon each log write the logger: -// 1. Checks if its log level is enough to log the message -// 2. Format the message using the formatter function -// 3. Pass the formatted message to its sinks to performa the actual logging - -#include "sinks/base_sink.h" -#include "common.h" - -#include -#include -#include - -namespace spdlog -{ - -class logger -{ -public: - logger(const std::string& logger_name, sink_ptr single_sink); - logger(const std::string& name, sinks_init_list); - template - logger(const std::string& name, const It& begin, const It& end); - - virtual ~logger(); - logger(const logger&) = delete; - logger& operator=(const logger&) = delete; - - - template void log(level::level_enum lvl, const char* fmt, const Args&... args); - template void log(level::level_enum lvl, const char* msg); - template void trace(const char* fmt, const Arg1&, const Args&... args); - template void debug(const char* fmt, const Arg1&, const Args&... args); - template void info(const char* fmt, const Arg1&, const Args&... args); - template void warn(const char* fmt, const Arg1&, const Args&... args); - template void error(const char* fmt, const Arg1&, const Args&... args); - template void critical(const char* fmt, const Arg1&, const Args&... args); - - -#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT - template void log(level::level_enum lvl, const wchar_t* msg); - template void log(level::level_enum lvl, const wchar_t* fmt, const Args&... args); - template void trace(const wchar_t* fmt, const Args&... args); - template void debug(const wchar_t* fmt, const Args&... args); - template void info(const wchar_t* fmt, const Args&... args); - template void warn(const wchar_t* fmt, const Args&... args); - template void error(const wchar_t* fmt, const Args&... args); - template void critical(const wchar_t* fmt, const Args&... args); -#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT - - template void log(level::level_enum lvl, const T&); - template void trace(const T&); - template void debug(const T&); - template void info(const T&); - template void warn(const T&); - template void error(const T&); - template void critical(const T&); - - bool should_log(level::level_enum) const; - void set_level(level::level_enum); - level::level_enum level() const; - const std::string& name() const; - void set_pattern(const std::string&, pattern_time_type = pattern_time_type::local); - void set_formatter(formatter_ptr); - - // automatically call flush() if message level >= log_level - void flush_on(level::level_enum log_level); - - virtual void flush(); - - const std::vector& sinks() const; - - // error handler - virtual void set_error_handler(log_err_handler); - virtual log_err_handler error_handler(); - -protected: - virtual void _sink_it(details::log_msg&); - virtual void _set_pattern(const std::string&, pattern_time_type); - virtual void _set_formatter(formatter_ptr); - - // default error handler: print the error to stderr with the max rate of 1 message/minute - virtual void _default_err_handler(const std::string &msg); - - // return true if the given message level should trigger a flush - bool _should_flush_on(const details::log_msg&); - - // increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)) - void _incr_msg_counter(details::log_msg &msg); - - const std::string _name; - std::vector _sinks; - formatter_ptr _formatter; - spdlog::level_t _level; - spdlog::level_t _flush_level; - log_err_handler _err_handler; - std::atomic _last_err_time; - std::atomic _msg_counter; -}; -} - -#include "details/logger_impl.h" diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/android_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/android_sink.h deleted file mode 100644 index 63f6d8745..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/android_sink.h +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#if defined(__ANDROID__) - -#include "sink.h" - -#include -#include -#include -#include -#include - -#if !defined(SPDLOG_ANDROID_RETRIES) -#define SPDLOG_ANDROID_RETRIES 2 -#endif - -namespace spdlog -{ -namespace sinks -{ - -/* -* Android sink (logging using __android_log_write) -* __android_log_write is thread-safe. No lock is needed. -*/ -class android_sink : public sink -{ -public: - explicit android_sink(const std::string& tag = "spdlog", bool use_raw_msg = false): _tag(tag), _use_raw_msg(use_raw_msg) {} - - void log(const details::log_msg& msg) override - { - const android_LogPriority priority = convert_to_android(msg.level); - const char *msg_output = (_use_raw_msg ? msg.raw.c_str() : msg.formatted.c_str()); - - // See system/core/liblog/logger_write.c for explanation of return value - int ret = __android_log_write(priority, _tag.c_str(), msg_output); - int retry_count = 0; - while ((ret == -11/*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES)) - { - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - ret = __android_log_write(priority, _tag.c_str(), msg_output); - retry_count++; - } - - if (ret < 0) - { - throw spdlog_ex("__android_log_write() failed", ret); - } - } - - void flush() override - { - } - -private: - static android_LogPriority convert_to_android(spdlog::level::level_enum level) - { - switch(level) - { - case spdlog::level::trace: - return ANDROID_LOG_VERBOSE; - case spdlog::level::debug: - return ANDROID_LOG_DEBUG; - case spdlog::level::info: - return ANDROID_LOG_INFO; - case spdlog::level::warn: - return ANDROID_LOG_WARN; - case spdlog::level::err: - return ANDROID_LOG_ERROR; - case spdlog::level::critical: - return ANDROID_LOG_FATAL; - default: - return ANDROID_LOG_DEFAULT; - } - } - - std::string _tag; - bool _use_raw_msg; -}; - -} -} - -#endif diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/ansicolor_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/ansicolor_sink.h deleted file mode 100644 index 290973133..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/ansicolor_sink.h +++ /dev/null @@ -1,133 +0,0 @@ -// -// Copyright(c) 2017 spdlog authors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "base_sink.h" -#include "../common.h" -#include "../details/os.h" - -#include -#include - -namespace spdlog -{ -namespace sinks -{ - -/** - * This sink prefixes the output with an ANSI escape sequence color code depending on the severity - * of the message. - * If no color terminal detected, omit the escape codes. - */ -template -class ansicolor_sink: public base_sink -{ -public: - ansicolor_sink(FILE* file): target_file_(file) - { - should_do_colors_ = details::os::in_terminal(file) && details::os::is_color_terminal(); - colors_[level::trace] = cyan; - colors_[level::debug] = cyan; - colors_[level::info] = reset; - colors_[level::warn] = yellow + bold; - colors_[level::err] = red + bold; - colors_[level::critical] = bold + on_red; - colors_[level::off] = reset; - } - virtual ~ansicolor_sink() - { - _flush(); - } - - void set_color(level::level_enum color_level, const std::string& color) - { - std::lock_guard lock(base_sink::_mutex); - colors_[color_level] = color; - } - - /// Formatting codes - const std::string reset = "\033[00m"; - const std::string bold = "\033[1m"; - const std::string dark = "\033[2m"; - const std::string underline = "\033[4m"; - const std::string blink = "\033[5m"; - const std::string reverse = "\033[7m"; - const std::string concealed = "\033[8m"; - - // Foreground colors - const std::string grey = "\033[30m"; - const std::string red = "\033[31m"; - const std::string green = "\033[32m"; - const std::string yellow = "\033[33m"; - const std::string blue = "\033[34m"; - const std::string magenta = "\033[35m"; - const std::string cyan = "\033[36m"; - const std::string white = "\033[37m"; - - /// Background colors - const std::string on_grey = "\033[40m"; - const std::string on_red = "\033[41m"; - const std::string on_green = "\033[42m"; - const std::string on_yellow = "\033[43m"; - const std::string on_blue = "\033[44m"; - const std::string on_magenta = "\033[45m"; - const std::string on_cyan = "\033[46m"; - const std::string on_white = "\033[47m"; - -protected: - virtual void _sink_it(const details::log_msg& msg) override - { - // Wrap the originally formatted message in color codes. - // If color is not supported in the terminal, log as is instead. - if (should_do_colors_) - { - const std::string& prefix = colors_[msg.level]; - fwrite(prefix.data(), sizeof(char), prefix.size(), target_file_); - fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), target_file_); - fwrite(reset.data(), sizeof(char), reset.size(), target_file_); - } - else - { - fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), target_file_); - } - _flush(); - } - - void _flush() override - { - fflush(target_file_); - } - FILE* target_file_; - bool should_do_colors_; - std::map colors_; -}; - - -template -class ansicolor_stdout_sink: public ansicolor_sink -{ -public: - ansicolor_stdout_sink(): ansicolor_sink(stdout) - {} -}; - -template -class ansicolor_stderr_sink: public ansicolor_sink -{ -public: - ansicolor_stderr_sink(): ansicolor_sink(stderr) - {} -}; - -typedef ansicolor_stdout_sink ansicolor_stdout_sink_mt; -typedef ansicolor_stdout_sink ansicolor_stdout_sink_st; - -typedef ansicolor_stderr_sink ansicolor_stderr_sink_mt; -typedef ansicolor_stderr_sink ansicolor_stderr_sink_st; - -} // namespace sinks -} // namespace spdlog - diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/base_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/base_sink.h deleted file mode 100644 index 23c856530..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/base_sink.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once -// -// base sink templated over a mutex (either dummy or real) -// concrete implementation should only override the _sink_it method. -// all locking is taken care of here so no locking needed by the implementers.. -// - -#include "sink.h" -#include "../formatter.h" -#include "../common.h" -#include "../details/log_msg.h" - -#include - -namespace spdlog -{ -namespace sinks -{ -template -class base_sink:public sink -{ -public: - base_sink():_mutex() {} - virtual ~base_sink() = default; - - base_sink(const base_sink&) = delete; - base_sink& operator=(const base_sink&) = delete; - - void log(const details::log_msg& msg) SPDLOG_FINAL override - { - std::lock_guard lock(_mutex); - _sink_it(msg); - } - void flush() SPDLOG_FINAL override - { - std::lock_guard lock(_mutex); - _flush(); - } - -protected: - virtual void _sink_it(const details::log_msg& msg) = 0; - virtual void _flush() = 0; - Mutex _mutex; -}; -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/dist_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/dist_sink.h deleted file mode 100644 index 537efe1d1..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/dist_sink.h +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) 2015 David Schury, Gabi Melman -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "../details/log_msg.h" -#include "../details/null_mutex.h" -#include "base_sink.h" -#include "sink.h" - -#include -#include -#include -#include - -// Distribution sink (mux). Stores a vector of sinks which get called when log is called - -namespace spdlog -{ -namespace sinks -{ -template -class dist_sink: public base_sink -{ -public: - explicit dist_sink() :_sinks() {} - dist_sink(const dist_sink&) = delete; - dist_sink& operator=(const dist_sink&) = delete; - virtual ~dist_sink() = default; - -protected: - std::vector> _sinks; - - void _sink_it(const details::log_msg& msg) override - { - for (auto &sink : _sinks) - { - if( sink->should_log( msg.level)) - { - sink->log(msg); - } - } - } - - void _flush() override - { - for (auto &sink : _sinks) - sink->flush(); - } - -public: - - - void add_sink(std::shared_ptr sink) - { - std::lock_guard lock(base_sink::_mutex); - _sinks.push_back(sink); - } - - void remove_sink(std::shared_ptr sink) - { - std::lock_guard lock(base_sink::_mutex); - _sinks.erase(std::remove(_sinks.begin(), _sinks.end(), sink), _sinks.end()); - } -}; - -typedef dist_sink dist_sink_mt; -typedef dist_sink dist_sink_st; -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/file_sinks.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/file_sinks.h deleted file mode 100644 index e78561722..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/file_sinks.h +++ /dev/null @@ -1,253 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "base_sink.h" -#include "../details/null_mutex.h" -#include "../details/file_helper.h" -#include "../fmt/fmt.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace spdlog -{ -namespace sinks -{ -/* - * Trivial file sink with single file as target - */ -template -class simple_file_sink SPDLOG_FINAL : public base_sink < Mutex > -{ -public: - explicit simple_file_sink(const filename_t &filename, bool truncate = false):_force_flush(false) - { - _file_helper.open(filename, truncate); - } - - void set_force_flush(bool force_flush) - { - _force_flush = force_flush; - } - -protected: - void _sink_it(const details::log_msg& msg) override - { - _file_helper.write(msg); - if(_force_flush) - _file_helper.flush(); - } - void _flush() override - { - _file_helper.flush(); - } -private: - details::file_helper _file_helper; - bool _force_flush; -}; - -typedef simple_file_sink simple_file_sink_mt; -typedef simple_file_sink simple_file_sink_st; - -/* - * Rotating file sink based on size - */ -template -class rotating_file_sink SPDLOG_FINAL : public base_sink < Mutex > -{ -public: - rotating_file_sink(const filename_t &base_filename, - std::size_t max_size, std::size_t max_files) : - _base_filename(base_filename), - _max_size(max_size), - _max_files(max_files), - _current_size(0), - _file_helper() - { - _file_helper.open(calc_filename(_base_filename, 0)); - _current_size = _file_helper.size(); //expensive. called only once - } - - // calc filename according to index and file extension if exists. - // e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt". - static filename_t calc_filename(const filename_t& filename, std::size_t index) - { - std::conditional::value, fmt::MemoryWriter, fmt::WMemoryWriter>::type w; - if (index) - { - filename_t basename, ext; - std::tie(basename, ext) = details::file_helper::split_by_extenstion(filename); - w.write(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext); - } - else - { - w.write(SPDLOG_FILENAME_T("{}"), filename); - } - return w.str(); - } - -protected: - void _sink_it(const details::log_msg& msg) override - { - _current_size += msg.formatted.size(); - if (_current_size > _max_size) - { - _rotate(); - _current_size = msg.formatted.size(); - } - _file_helper.write(msg); - } - - void _flush() override - { - _file_helper.flush(); - } - - -private: - // Rotate files: - // log.txt -> log.1.txt - // log.1.txt -> log.2.txt - // log.2.txt -> log.3.txt - // log.3.txt -> delete - void _rotate() - { - using details::os::filename_to_str; - _file_helper.close(); - for (auto i = _max_files; i > 0; --i) - { - filename_t src = calc_filename(_base_filename, i - 1); - filename_t target = calc_filename(_base_filename, i); - - if (details::file_helper::file_exists(target)) - { - if (details::os::remove(target) != 0) - { - throw spdlog_ex("rotating_file_sink: failed removing " + filename_to_str(target), errno); - } - } - if (details::file_helper::file_exists(src) && details::os::rename(src, target)) - { - throw spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno); - } - } - _file_helper.reopen(true); - } - filename_t _base_filename; - std::size_t _max_size; - std::size_t _max_files; - std::size_t _current_size; - details::file_helper _file_helper; -}; - -typedef rotating_file_sink rotating_file_sink_mt; -typedef rotating_file_sinkrotating_file_sink_st; - -/* - * Default generator of daily log file names. - */ -struct default_daily_file_name_calculator -{ - // Create filename for the form filename.YYYY-MM-DD_hh-mm.ext - static filename_t calc_filename(const filename_t& filename) - { - std::tm tm = spdlog::details::os::localtime(); - filename_t basename, ext; - std::tie(basename, ext) = details::file_helper::split_by_extenstion(filename); - std::conditional::value, fmt::MemoryWriter, fmt::WMemoryWriter>::type w; - w.write(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}{}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, ext); - return w.str(); - } -}; - -/* - * Generator of daily log file names in format basename.YYYY-MM-DD.ext - */ -struct dateonly_daily_file_name_calculator -{ - // Create filename for the form basename.YYYY-MM-DD - static filename_t calc_filename(const filename_t& filename) - { - std::tm tm = spdlog::details::os::localtime(); - filename_t basename, ext; - std::tie(basename, ext) = details::file_helper::split_by_extenstion(filename); - std::conditional::value, fmt::MemoryWriter, fmt::WMemoryWriter>::type w; - w.write(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}{}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ext); - return w.str(); - } -}; - -/* - * Rotating file sink based on date. rotates at midnight - */ -template -class daily_file_sink SPDLOG_FINAL :public base_sink < Mutex > -{ -public: - //create daily file sink which rotates on given time - daily_file_sink( - const filename_t& base_filename, - int rotation_hour, - int rotation_minute) : _base_filename(base_filename), - _rotation_h(rotation_hour), - _rotation_m(rotation_minute) - { - if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59) - throw spdlog_ex("daily_file_sink: Invalid rotation time in ctor"); - _rotation_tp = _next_rotation_tp(); - _file_helper.open(FileNameCalc::calc_filename(_base_filename)); - } - - -protected: - void _sink_it(const details::log_msg& msg) override - { - if (std::chrono::system_clock::now() >= _rotation_tp) - { - _file_helper.open(FileNameCalc::calc_filename(_base_filename)); - _rotation_tp = _next_rotation_tp(); - } - _file_helper.write(msg); - } - - void _flush() override - { - _file_helper.flush(); - } - -private: - std::chrono::system_clock::time_point _next_rotation_tp() - { - auto now = std::chrono::system_clock::now(); - time_t tnow = std::chrono::system_clock::to_time_t(now); - tm date = spdlog::details::os::localtime(tnow); - date.tm_hour = _rotation_h; - date.tm_min = _rotation_m; - date.tm_sec = 0; - auto rotation_time = std::chrono::system_clock::from_time_t(std::mktime(&date)); - if (rotation_time > now) - return rotation_time; - else - return std::chrono::system_clock::time_point(rotation_time + std::chrono::hours(24)); - } - - filename_t _base_filename; - int _rotation_h; - int _rotation_m; - std::chrono::system_clock::time_point _rotation_tp; - details::file_helper _file_helper; -}; - -typedef daily_file_sink daily_file_sink_mt; -typedef daily_file_sink daily_file_sink_st; -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/msvc_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/msvc_sink.h deleted file mode 100644 index 22b52c8fe..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/msvc_sink.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright(c) 2016 Alexander Dalshov. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#if defined(_WIN32) - -#include "base_sink.h" -#include "../details/null_mutex.h" - -#include - -#include -#include - -namespace spdlog -{ -namespace sinks -{ -/* -* MSVC sink (logging using OutputDebugStringA) -*/ -template -class msvc_sink : public base_sink < Mutex > -{ -public: - explicit msvc_sink() - { - } - - - -protected: - void _sink_it(const details::log_msg& msg) override - { - OutputDebugStringA(msg.formatted.c_str()); - } - - void _flush() override - {} -}; - -typedef msvc_sink msvc_sink_mt; -typedef msvc_sink msvc_sink_st; - -} -} - -#endif diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/null_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/null_sink.h deleted file mode 100644 index 7605ac68c..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/null_sink.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "base_sink.h" -#include "../details/null_mutex.h" - -#include - -namespace spdlog -{ -namespace sinks -{ - -template -class null_sink : public base_sink < Mutex > -{ -protected: - void _sink_it(const details::log_msg&) override - {} - - void _flush() override - {} - -}; -typedef null_sink null_sink_st; -typedef null_sink null_sink_mt; - -} -} - diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/ostream_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/ostream_sink.h deleted file mode 100644 index 1e5b261c0..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/ostream_sink.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "../details/null_mutex.h" -#include "base_sink.h" - -#include -#include - -namespace spdlog -{ -namespace sinks -{ -template -class ostream_sink: public base_sink -{ -public: - explicit ostream_sink(std::ostream& os, bool force_flush=false) :_ostream(os), _force_flush(force_flush) {} - ostream_sink(const ostream_sink&) = delete; - ostream_sink& operator=(const ostream_sink&) = delete; - virtual ~ostream_sink() = default; - -protected: - void _sink_it(const details::log_msg& msg) override - { - _ostream.write(msg.formatted.data(), msg.formatted.size()); - if (_force_flush) - _ostream.flush(); - } - - void _flush() override - { - _ostream.flush(); - } - - std::ostream& _ostream; - bool _force_flush; -}; - -typedef ostream_sink ostream_sink_mt; -typedef ostream_sink ostream_sink_st; -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/sink.h deleted file mode 100644 index af61b54c6..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/sink.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - - -#pragma once - -#include "../details/log_msg.h" - -namespace spdlog -{ -namespace sinks -{ -class sink -{ -public: - sink() - { - _level = level::trace; - } - - virtual ~sink() {} - virtual void log(const details::log_msg& msg) = 0; - virtual void flush() = 0; - - bool should_log(level::level_enum msg_level) const; - void set_level(level::level_enum log_level); - level::level_enum level() const; - -private: - level_t _level; - -}; - -inline bool sink::should_log(level::level_enum msg_level) const -{ - return msg_level >= _level.load(std::memory_order_relaxed); -} - -inline void sink::set_level(level::level_enum log_level) -{ - _level.store(log_level); -} - -inline level::level_enum sink::level() const -{ - return static_cast(_level.load(std::memory_order_relaxed)); -} - -} -} - diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/stdout_sinks.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/stdout_sinks.h deleted file mode 100644 index dfbfccd51..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/stdout_sinks.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "../details/null_mutex.h" -#include "base_sink.h" - -#include -#include -#include - -namespace spdlog -{ -namespace sinks -{ - -template -class stdout_sink SPDLOG_FINAL : public base_sink -{ - using MyType = stdout_sink; -public: - stdout_sink() - {} - static std::shared_ptr instance() - { - static std::shared_ptr instance = std::make_shared(); - return instance; - } -protected: - void _sink_it(const details::log_msg& msg) override - { - fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stdout); - _flush(); - } - - void _flush() override - { - fflush(stdout); - } -}; - -typedef stdout_sink stdout_sink_st; -typedef stdout_sink stdout_sink_mt; - - -template -class stderr_sink SPDLOG_FINAL : public base_sink -{ - using MyType = stderr_sink; -public: - stderr_sink() - {} - static std::shared_ptr instance() - { - static std::shared_ptr instance = std::make_shared(); - return instance; - } -protected: - void _sink_it(const details::log_msg& msg) override - { - fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stderr); - _flush(); - } - - void _flush() override - { - fflush(stderr); - } -}; - -typedef stderr_sink stderr_sink_mt; -typedef stderr_sink stderr_sink_st; -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/syslog_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/syslog_sink.h deleted file mode 100644 index c4a726a8f..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/syslog_sink.h +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "../common.h" - -#ifdef SPDLOG_ENABLE_SYSLOG - -#include "sink.h" -#include "../details/log_msg.h" - -#include -#include -#include - - -namespace spdlog -{ -namespace sinks -{ -/** - * Sink that write to syslog using the `syscall()` library call. - * - * Locking is not needed, as `syslog()` itself is thread-safe. - */ -class syslog_sink : public sink -{ -public: - // - syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER): - _ident(ident) - { - _priorities[static_cast(level::trace)] = LOG_DEBUG; - _priorities[static_cast(level::debug)] = LOG_DEBUG; - _priorities[static_cast(level::info)] = LOG_INFO; - _priorities[static_cast(level::warn)] = LOG_WARNING; - _priorities[static_cast(level::err)] = LOG_ERR; - _priorities[static_cast(level::critical)] = LOG_CRIT; - _priorities[static_cast(level::off)] = LOG_INFO; - - //set ident to be program name if empty - ::openlog(_ident.empty()? nullptr:_ident.c_str(), syslog_option, syslog_facility); - } - ~syslog_sink() - { - ::closelog(); - } - - syslog_sink(const syslog_sink&) = delete; - syslog_sink& operator=(const syslog_sink&) = delete; - - void log(const details::log_msg &msg) override - { - ::syslog(syslog_prio_from_level(msg), "%s", msg.raw.str().c_str()); - } - - void flush() override - { - } - - -private: - std::array _priorities; - //must store the ident because the man says openlog might use the pointer as is and not a string copy - const std::string _ident; - - // - // Simply maps spdlog's log level to syslog priority level. - // - int syslog_prio_from_level(const details::log_msg &msg) const - { - return _priorities[static_cast(msg.level)]; - } -}; -} -} - -#endif diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/wincolor_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/wincolor_sink.h deleted file mode 100644 index 8ee3d894c..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/wincolor_sink.h +++ /dev/null @@ -1,121 +0,0 @@ -// -// Copyright(c) 2016 spdlog -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include "base_sink.h" -#include "../details/null_mutex.h" -#include "../common.h" - -#include -#include -#include -#include - -namespace spdlog -{ -namespace sinks -{ -/* - * Windows color console sink. Uses WriteConsoleA to write to the console with colors - */ -template -class wincolor_sink: public base_sink -{ -public: - const WORD BOLD = FOREGROUND_INTENSITY; - const WORD RED = FOREGROUND_RED; - const WORD CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE; - const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN; - - wincolor_sink(HANDLE std_handle): out_handle_(std_handle) - { - colors_[level::trace] = CYAN; - colors_[level::debug] = CYAN; - colors_[level::info] = WHITE | BOLD; - colors_[level::warn] = YELLOW | BOLD; - colors_[level::err] = RED | BOLD; // red bold - colors_[level::critical] = BACKGROUND_RED | WHITE | BOLD; // white bold on red background - colors_[level::off] = 0; - } - - virtual ~wincolor_sink() - { - this->flush(); - } - - wincolor_sink(const wincolor_sink& other) = delete; - wincolor_sink& operator=(const wincolor_sink& other) = delete; - -protected: - virtual void _sink_it(const details::log_msg& msg) override - { - auto color = colors_[msg.level]; - auto orig_attribs = set_console_attribs(color); - WriteConsoleA(out_handle_, msg.formatted.data(), static_cast(msg.formatted.size()), nullptr, nullptr); - SetConsoleTextAttribute(out_handle_, orig_attribs); //reset to orig colors - } - - virtual void _flush() override - { - // windows console always flushed? - } - - // change the color for the given level - void set_color(level::level_enum level, WORD color) - { - std::lock_guard lock(base_sink::_mutex); - colors_[level] = color; - } - -private: - HANDLE out_handle_; - std::map colors_; - - // set color and return the orig console attributes (for resetting later) - WORD set_console_attribs(WORD attribs) - { - CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info; - GetConsoleScreenBufferInfo(out_handle_, &orig_buffer_info); - WORD back_color = orig_buffer_info.wAttributes; - // retrieve the current background color - back_color &= static_cast(~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)); - // keep the background color unchanged - SetConsoleTextAttribute(out_handle_, attribs | back_color); - return orig_buffer_info.wAttributes; //return orig attribs - } -}; - -// -// windows color console to stdout -// -template -class wincolor_stdout_sink: public wincolor_sink -{ -public: - wincolor_stdout_sink() : wincolor_sink(GetStdHandle(STD_OUTPUT_HANDLE)) - {} -}; - -typedef wincolor_stdout_sink wincolor_stdout_sink_mt; -typedef wincolor_stdout_sink wincolor_stdout_sink_st; - -// -// windows color console to stderr -// -template -class wincolor_stderr_sink: public wincolor_sink -{ -public: - wincolor_stderr_sink() : wincolor_sink(GetStdHandle(STD_ERROR_HANDLE)) - {} -}; - -typedef wincolor_stderr_sink wincolor_stderr_sink_mt; -typedef wincolor_stderr_sink wincolor_stderr_sink_st; - -} -} diff --git a/fpga/thirdparty/spdlog/include/spdlog/sinks/windebug_sink.h b/fpga/thirdparty/spdlog/include/spdlog/sinks/windebug_sink.h deleted file mode 100644 index c22e9522e..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/sinks/windebug_sink.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright(c) 2017 Alexander Dalshov. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#if defined(_WIN32) - -#include "msvc_sink.h" - -namespace spdlog -{ -namespace sinks -{ - -/* -* Windows debug sink (logging using OutputDebugStringA, synonym for msvc_sink) -*/ -template -using windebug_sink = msvc_sink; - -typedef msvc_sink_mt windebug_sink_mt; -typedef msvc_sink_st windebug_sink_st; - -} -} - -#endif diff --git a/fpga/thirdparty/spdlog/include/spdlog/spdlog.h b/fpga/thirdparty/spdlog/include/spdlog/spdlog.h deleted file mode 100644 index c7af2c795..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/spdlog.h +++ /dev/null @@ -1,192 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// -// spdlog main header file. -// see example.cpp for usage example - -#pragma once - -#define SPDLOG_VERSION "0.16.2" - -#include "tweakme.h" -#include "common.h" -#include "logger.h" - -#include -#include -#include -#include - -namespace spdlog -{ - -// -// Return an existing logger or nullptr if a logger with such name doesn't exist. -// example: spdlog::get("my_logger")->info("hello {}", "world"); -// -std::shared_ptr get(const std::string& name); - - -// -// Set global formatting -// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); -// -void set_pattern(const std::string& format_string); -void set_formatter(formatter_ptr f); - -// -// Set global logging level -// -void set_level(level::level_enum log_level); - -// -// Set global flush level -// -void flush_on(level::level_enum log_level); - -// -// Set global error handler -// -void set_error_handler(log_err_handler); - -// -// Turn on async mode (off by default) and set the queue size for each async_logger. -// effective only for loggers created after this call. -// queue_size: size of queue (must be power of 2): -// Each logger will pre-allocate a dedicated queue with queue_size entries upon construction. -// -// async_overflow_policy (optional, block_retry by default): -// async_overflow_policy::block_retry - if queue is full, block until queue has room for the new log entry. -// async_overflow_policy::discard_log_msg - never block and discard any new messages when queue overflows. -// -// worker_warmup_cb (optional): -// callback function that will be called in worker thread upon start (can be used to init stuff like thread affinity) -// -// worker_teardown_cb (optional): -// callback function that will be called in worker thread upon exit -// -void set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function& worker_teardown_cb = nullptr); - -// Turn off async mode -void set_sync_mode(); - - -// -// Create and register multi/single threaded basic file logger. -// Basic logger simply writes to given file without any limitations or rotations. -// -std::shared_ptr basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate = false); -std::shared_ptr basic_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate = false); - -// -// Create and register multi/single threaded rotating file logger -// -std::shared_ptr rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files); -std::shared_ptr rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files); - -// -// Create file logger which creates new file on the given time (default in midnight): -// -std::shared_ptr daily_logger_mt(const std::string& logger_name, const filename_t& filename, int hour=0, int minute=0); -std::shared_ptr daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour=0, int minute=0); - -// -// Create and register stdout/stderr loggers -// -std::shared_ptr stdout_logger_mt(const std::string& logger_name); -std::shared_ptr stdout_logger_st(const std::string& logger_name); -std::shared_ptr stderr_logger_mt(const std::string& logger_name); -std::shared_ptr stderr_logger_st(const std::string& logger_name); -// -// Create and register colored stdout/stderr loggers -// -std::shared_ptr stdout_color_mt(const std::string& logger_name); -std::shared_ptr stdout_color_st(const std::string& logger_name); -std::shared_ptr stderr_color_mt(const std::string& logger_name); -std::shared_ptr stderr_color_st(const std::string& logger_name); - - -// -// Create and register a syslog logger -// -#ifdef SPDLOG_ENABLE_SYSLOG -std::shared_ptr syslog_logger(const std::string& logger_name, const std::string& ident = "", int syslog_option = 0, int syslog_facilty = (1<<3)); -#endif - -#if defined(__ANDROID__) -std::shared_ptr android_logger(const std::string& logger_name, const std::string& tag = "spdlog"); -#endif - -// Create and register a logger with a single sink -std::shared_ptr create(const std::string& logger_name, const sink_ptr& sink); - -// Create and register a logger with multiple sinks -std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks); -template -std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end); - - -// Create and register a logger with templated sink type -// Example: -// spdlog::create("mylog", "dailylog_filename"); -template -std::shared_ptr create(const std::string& logger_name, Args...); - -// Create and register an async logger with a single sink -std::shared_ptr create_async(const std::string& logger_name, const sink_ptr& sink, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function& worker_teardown_cb = nullptr); - -// Create and register an async logger with multiple sinks -std::shared_ptr create_async(const std::string& logger_name, sinks_init_list sinks, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function& worker_teardown_cb = nullptr); -template -std::shared_ptr create_async(const std::string& logger_name, const It& sinks_begin, const It& sinks_end, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function& worker_teardown_cb = nullptr); - -// Register the given logger with the given name -void register_logger(std::shared_ptr logger); - -// Apply a user defined function on all registered loggers -// Example: -// spdlog::apply_all([&](std::shared_ptr l) {l->flush();}); -void apply_all(std::function)> fun); - -// Drop the reference to the given logger -void drop(const std::string &name); - -// Drop all references from the registry -void drop_all(); - - -/////////////////////////////////////////////////////////////////////////////// -// -// Trace & Debug can be switched on/off at compile time for zero cost debug statements. -// Uncomment SPDLOG_DEBUG_ON/SPDLOG_TRACE_ON in tweakme.h to enable. -// SPDLOG_TRACE(..) will also print current file and line. -// -// Example: -// spdlog::set_level(spdlog::level::trace); -// SPDLOG_TRACE(my_logger, "some trace message"); -// SPDLOG_TRACE(my_logger, "another trace message {} {}", 1, 2); -// SPDLOG_DEBUG(my_logger, "some debug message {} {}", 3, 4); -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SPDLOG_TRACE_ON -# define SPDLOG_STR_H(x) #x -# define SPDLOG_STR_HELPER(x) SPDLOG_STR_H(x) -# ifdef _MSC_VER -# define SPDLOG_TRACE(logger, ...) logger->trace("[ " __FILE__ "(" SPDLOG_STR_HELPER(__LINE__) ") ] " __VA_ARGS__) -# else -# define SPDLOG_TRACE(logger, ...) logger->trace("[ " __FILE__ ":" SPDLOG_STR_HELPER(__LINE__) " ] " __VA_ARGS__) -# endif -#else -# define SPDLOG_TRACE(logger, ...) (void)0 -#endif - -#ifdef SPDLOG_DEBUG_ON -# define SPDLOG_DEBUG(logger, ...) logger->debug(__VA_ARGS__) -#else -# define SPDLOG_DEBUG(logger, ...) (void)0 -#endif - -} - -#include "details/spdlog_impl.h" diff --git a/fpga/thirdparty/spdlog/include/spdlog/tweakme.h b/fpga/thirdparty/spdlog/include/spdlog/tweakme.h deleted file mode 100644 index ad01a09c0..000000000 --- a/fpga/thirdparty/spdlog/include/spdlog/tweakme.h +++ /dev/null @@ -1,160 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -/////////////////////////////////////////////////////////////////////////////// -// -// Edit this file to squeeze more performance, and to customize supported features -// -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Under Linux, the much faster CLOCK_REALTIME_COARSE clock can be used. -// This clock is less accurate - can be off by dozens of millis - depending on the kernel HZ. -// Uncomment to use it instead of the regular clock. -// -// #define SPDLOG_CLOCK_COARSE -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment if date/time logging is not needed and never appear in the log pattern. -// This will prevent spdlog from querying the clock on each log call. -// -// WARNING: If the log pattern contains any date/time while this flag is on, the result is undefined. -// You must set new pattern(spdlog::set_pattern(..") without any date/time in it -// -// #define SPDLOG_NO_DATETIME -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment if thread id logging is not needed (i.e. no %t in the log pattern). -// This will prevent spdlog from querying the thread id on each log call. -// -// WARNING: If the log pattern contains thread id (i.e, %t) while this flag is on, the result is undefined. -// -// #define SPDLOG_NO_THREAD_ID -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to prevent spdlog from caching thread ids in thread local storage. -// By default spdlog saves thread ids in tls to gain a few micros for each call. -// -// WARNING: if your program forks, UNCOMMENT this flag to prevent undefined thread ids in the children logs. -// -// #define SPDLOG_DISABLE_TID_CACHING -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment if logger name logging is not needed. -// This will prevent spdlog from copying the logger name on each log call. -// -// #define SPDLOG_NO_NAME -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to enable the SPDLOG_DEBUG/SPDLOG_TRACE macros. -// -// #define SPDLOG_DEBUG_ON -// #define SPDLOG_TRACE_ON -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to avoid locking in the registry operations (spdlog::get(), spdlog::drop() spdlog::register()). -// Use only if your code never modifies concurrently the registry. -// Note that upon creating a logger the registry is modified by spdlog.. -// -// #define SPDLOG_NO_REGISTRY_MUTEX -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to avoid spdlog's usage of atomic log levels -// Use only if your code never modifies a logger's log levels concurrently by different threads. -// -// #define SPDLOG_NO_ATOMIC_LEVELS -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to enable usage of wchar_t for file names on Windows. -// -// #define SPDLOG_WCHAR_FILENAMES -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to override default eol ("\n" or "\r\n" under Linux/Windows) -// -// #define SPDLOG_EOL ";-)\n" -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to use your own copy of the fmt library instead of spdlog's copy. -// In this case spdlog will try to include so set your -I flag accordingly. -// -// #define SPDLOG_FMT_EXTERNAL -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to use printf-style messages in your logs instead of the usual -// format-style used by default. -// -// #define SPDLOG_FMT_PRINTF -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to enable syslog (disabled by default) -// -// #define SPDLOG_ENABLE_SYSLOG -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to enable wchar_t support (convert to utf8) -// -// #define SPDLOG_WCHAR_TO_UTF8_SUPPORT -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to prevent child processes from inheriting log file descriptors -// -// #define SPDLOG_PREVENT_CHILD_FD -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment if your compiler doesn't support the "final" keyword. -// The final keyword allows more optimizations in release -// mode with recent compilers. See GCC's documentation for -Wsuggest-final-types -// for instance. -// -// #define SPDLOG_NO_FINAL -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to enable message counting feature. -// Use the %i in the logger pattern to display log message sequence id. -// -// #define SPDLOG_ENABLE_MESSAGE_COUNTER -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to customize level names (e.g. "MT TRACE") -// -// #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", "MY ERROR", "MY CRITICAL", "OFF" } -/////////////////////////////////////////////////////////////////////////////// diff --git a/fpga/thirdparty/spdlog/tests/CMakeLists.txt b/fpga/thirdparty/spdlog/tests/CMakeLists.txt deleted file mode 100644 index 22329b4e6..000000000 --- a/fpga/thirdparty/spdlog/tests/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# -# Tests -# - -enable_testing() - -find_package(Threads) - -# Build Catch unit tests -add_library(catch INTERFACE) -target_include_directories(catch INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) - -file(GLOB catch_tests LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h *.hpp) - -add_executable(catch_tests ${catch_tests}) -target_link_libraries(catch_tests spdlog ${CMAKE_THREAD_LIBS_INIT}) -add_test(NAME catch_tests COMMAND catch_tests) -file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs") - diff --git a/fpga/thirdparty/spdlog/tests/Makefile b/fpga/thirdparty/spdlog/tests/Makefile deleted file mode 100644 index b1935e751..000000000 --- a/fpga/thirdparty/spdlog/tests/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -CXX ?= g++ -ifeq ($(STYLE),printf) - $(info *** PRINTF STYLE ***) - CXXFLAGS = -DSPDLOG_FMT_PRINTF -Wall -pedantic -std=c++11 -pthread -O2 -I../include -else - $(info *** FORMAT STYLE ***) - CXXFLAGS = -Wall -pedantic -std=c++11 -pthread -O2 -I../include -endif -LDPFALGS = -pthread - -CPP_FILES := $(wildcard *.cpp) -OBJ_FILES := $(addprefix ./,$(notdir $(CPP_FILES:.cpp=.o))) - - -tests: $(OBJ_FILES) - $(CXX) $(CXXFLAGS) $(LDPFALGS) -o $@ $^ - mkdir -p logs - -%.o: %.cpp - $(CXX) $(CXXFLAGS) -c -o $@ $< - -clean: - rm -f tests *.o logs/*.txt - -rebuild: clean tests - - - diff --git a/fpga/thirdparty/spdlog/tests/catch.hpp b/fpga/thirdparty/spdlog/tests/catch.hpp deleted file mode 100644 index 925c6bffa..000000000 --- a/fpga/thirdparty/spdlog/tests/catch.hpp +++ /dev/null @@ -1,9427 +0,0 @@ -/* - * CATCH v1.1 build 1 (master branch) - * Generated: 2015-03-27 18:00:16.346230 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED - -#define TWOBLUECUBES_CATCH_HPP_INCLUDED - -// #included from: internal/catch_suppress_warnings.h - -#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic ignored "-Wglobal-constructors" -# pragma clang diagnostic ignored "-Wvariadic-macros" -# pragma clang diagnostic ignored "-Wc99-extensions" -# pragma clang diagnostic ignored "-Wunused-variable" -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wc++98-compat" -# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic ignored "-Wvariadic-macros" -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpadded" -#endif - -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -#endif - -#ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif -#endif - -// #included from: internal/catch_notimplemented_exception.h -#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED - -// #included from: catch_common.h -#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED - -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) - -#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr -#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) - -#include -#include -#include - -// #included from: catch_compiler_capabilities.h -#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED - -// Much of the following code is based on Boost (1.53) - -#ifdef __clang__ - -# if __has_feature(cxx_nullptr) -# define CATCH_CONFIG_CPP11_NULLPTR -# endif - -# if __has_feature(cxx_noexcept) -# define CATCH_CONFIG_CPP11_NOEXCEPT -# endif - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// Borland -#ifdef __BORLANDC__ - -#if (__BORLANDC__ > 0x582 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#endif // __BORLANDC__ - -//////////////////////////////////////////////////////////////////////////////// -// EDG -#ifdef __EDG_VERSION__ - -#if (__EDG_VERSION__ > 238 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#endif // __EDG_VERSION__ - -//////////////////////////////////////////////////////////////////////////////// -// Digital Mars -#ifdef __DMC__ - -#if (__DMC__ > 0x840 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#endif // __DMC__ - -//////////////////////////////////////////////////////////////////////////////// -// GCC -#ifdef __GNUC__ - -#if __GNUC__ < 3 - -#if (__GNUC_MINOR__ >= 96 ) -//#define CATCH_CONFIG_SFINAE -#endif - -#elif __GNUC__ >= 3 - -// #define CATCH_CONFIG_SFINAE // Taking this out completely for now - -#endif // __GNUC__ < 3 - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) ) - -#define CATCH_CONFIG_CPP11_NULLPTR -#endif - -#endif // __GNUC__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#ifdef _MSC_VER - -#if (_MSC_VER >= 1600) -#define CATCH_CONFIG_CPP11_NULLPTR -#endif - -#if (_MSC_VER >= 1310 ) // (VC++ 7.0+) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#endif // _MSC_VER - -// Use variadic macros if the compiler supports them -#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ - ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ - ( defined __GNUC__ && __GNUC__ >= 3 ) || \ - ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) - -#ifndef CATCH_CONFIG_NO_VARIADIC_MACROS -#define CATCH_CONFIG_VARIADIC_MACROS -#endif - -#endif - -//////////////////////////////////////////////////////////////////////////////// -// C++ language feature support - -// detect language version: -#if (__cplusplus == 201103L) -# define CATCH_CPP11 -# define CATCH_CPP11_OR_GREATER -#elif (__cplusplus >= 201103L) -# define CATCH_CPP11_OR_GREATER -#endif - -// noexcept support: -#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) -# define CATCH_NOEXCEPT noexcept -# define CATCH_NOEXCEPT_IS(x) noexcept(x) -#else -# define CATCH_NOEXCEPT throw() -# define CATCH_NOEXCEPT_IS(x) -#endif - -namespace Catch { - - class NonCopyable { -#ifdef CATCH_CPP11_OR_GREATER - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; -#else - NonCopyable( NonCopyable const& info ); - NonCopyable& operator = ( NonCopyable const& ); -#endif - - protected: - NonCopyable() {} - virtual ~NonCopyable(); - }; - - class SafeBool { - public: - typedef void (SafeBool::*type)() const; - - static type makeSafe( bool value ) { - return value ? &SafeBool::trueValue : 0; - } - private: - void trueValue() const {} - }; - - template - inline void deleteAll( ContainerT& container ) { - typename ContainerT::const_iterator it = container.begin(); - typename ContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete *it; - } - template - inline void deleteAllValues( AssociativeContainerT& container ) { - typename AssociativeContainerT::const_iterator it = container.begin(); - typename AssociativeContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete it->second; - } - - bool startsWith( std::string const& s, std::string const& prefix ); - bool endsWith( std::string const& s, std::string const& suffix ); - bool contains( std::string const& s, std::string const& infix ); - void toLowerInPlace( std::string& s ); - std::string toLower( std::string const& s ); - std::string trim( std::string const& str ); - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); - - struct pluralise { - pluralise( std::size_t count, std::string const& label ); - - friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); - - std::size_t m_count; - std::string m_label; - }; - - struct SourceLineInfo { - - SourceLineInfo(); - SourceLineInfo( char const* _file, std::size_t _line ); - SourceLineInfo( SourceLineInfo const& other ); -# ifdef CATCH_CPP11_OR_GREATER - SourceLineInfo( SourceLineInfo && ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo& operator = ( SourceLineInfo && ) = default; -# endif - bool empty() const; - bool operator == ( SourceLineInfo const& other ) const; - bool operator < ( SourceLineInfo const& other ) const; - - std::string file; - std::size_t line; - }; - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - - // This is just here to avoid compiler warnings with macro constants and boolean literals - inline bool isTrue( bool value ){ return value; } - inline bool alwaysTrue() { return true; } - inline bool alwaysFalse() { return false; } - - void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() { - return std::string(); - } - }; - template - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } -} - -#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) -#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); - -#include - -namespace Catch { - - class NotImplementedException : public std::exception - { - public: - NotImplementedException( SourceLineInfo const& lineInfo ); - NotImplementedException( NotImplementedException const& ) {} - - virtual ~NotImplementedException() CATCH_NOEXCEPT {} - - virtual const char* what() const CATCH_NOEXCEPT; - - private: - std::string m_what; - SourceLineInfo m_lineInfo; - }; - -} // end namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) - -// #included from: internal/catch_context.h -#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED - -// #included from: catch_interfaces_generators.h -#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED - -#include - -namespace Catch { - - struct IGeneratorInfo { - virtual ~IGeneratorInfo(); - virtual bool moveNext() = 0; - virtual std::size_t getCurrentIndex() const = 0; - }; - - struct IGeneratorsForTest { - virtual ~IGeneratorsForTest(); - - virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; - virtual bool moveNext() = 0; - }; - - IGeneratorsForTest* createGeneratorsForTest(); - -} // end namespace Catch - -// #included from: catch_ptr.hpp -#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - // An intrusive reference counting smart pointer. - // T must implement addRef() and release() methods - // typically implementing the IShared interface - template - class Ptr { - public: - Ptr() : m_p( NULL ){} - Ptr( T* p ) : m_p( p ){ - if( m_p ) - m_p->addRef(); - } - Ptr( Ptr const& other ) : m_p( other.m_p ){ - if( m_p ) - m_p->addRef(); - } - ~Ptr(){ - if( m_p ) - m_p->release(); - } - void reset() { - if( m_p ) - m_p->release(); - m_p = NULL; - } - Ptr& operator = ( T* p ){ - Ptr temp( p ); - swap( temp ); - return *this; - } - Ptr& operator = ( Ptr const& other ){ - Ptr temp( other ); - swap( temp ); - return *this; - } - void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } - T* get() { return m_p; } - const T* get() const{ return m_p; } - T& operator*() const { return *m_p; } - T* operator->() const { return m_p; } - bool operator !() const { return m_p == NULL; } - operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); } - - private: - T* m_p; - }; - - struct IShared : NonCopyable { - virtual ~IShared(); - virtual void addRef() const = 0; - virtual void release() const = 0; - }; - - template - struct SharedImpl : T { - - SharedImpl() : m_rc( 0 ){} - - virtual void addRef() const { - ++m_rc; - } - virtual void release() const { - if( --m_rc == 0 ) - delete this; - } - - mutable unsigned int m_rc; - }; - -} // end namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include - -namespace Catch { - - class TestCase; - class Stream; - struct IResultCapture; - struct IRunner; - struct IGeneratorsForTest; - struct IConfig; - - struct IContext - { - virtual ~IContext(); - - virtual IResultCapture* getResultCapture() = 0; - virtual IRunner* getRunner() = 0; - virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; - virtual bool advanceGeneratorsForCurrentTest() = 0; - virtual Ptr getConfig() const = 0; - }; - - struct IMutableContext : IContext - { - virtual ~IMutableContext(); - virtual void setResultCapture( IResultCapture* resultCapture ) = 0; - virtual void setRunner( IRunner* runner ) = 0; - virtual void setConfig( Ptr const& config ) = 0; - }; - - IContext& getCurrentContext(); - IMutableContext& getCurrentMutableContext(); - void cleanUpContext(); - Stream createStream( std::string const& streamName ); - -} - -// #included from: internal/catch_test_registry.hpp -#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED - -// #included from: catch_interfaces_testcase.h -#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED - -#include - -namespace Catch { - - class TestSpec; - - struct ITestCase : IShared { - virtual void invoke () const = 0; - protected: - virtual ~ITestCase(); - }; - - class TestCase; - struct IConfig; - - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector& matchingTestCases, bool negated = false ) const = 0; - - }; -} - -namespace Catch { - -template -class MethodTestCase : public SharedImpl { - -public: - MethodTestCase( void (C::*method)() ) : m_method( method ) {} - - virtual void invoke() const { - C obj; - (obj.*m_method)(); - } - -private: - virtual ~MethodTestCase() {} - - void (C::*m_method)(); -}; - -typedef void(*TestFunction)(); - -struct NameAndDesc { - NameAndDesc( const char* _name = "", const char* _description= "" ) - : name( _name ), description( _description ) - {} - - const char* name; - const char* description; -}; - -struct AutoReg { - - AutoReg( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ); - - template - AutoReg( void (C::*method)(), - char const* className, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ) { - registerTestCase( new MethodTestCase( method ), - className, - nameAndDesc, - lineInfo ); - } - - void registerTestCase( ITestCase* testCase, - char const* className, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ); - - ~AutoReg(); - -private: - AutoReg( AutoReg const& ); - void operator= ( AutoReg const& ); -}; - -} // end namespace Catch - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TESTCASE( ... ) \ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\ - namespace{ \ - struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ - void test(); \ - }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ - } \ - void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() - -#else - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ - namespace{ \ - struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ - void test(); \ - }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ - } \ - void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() - -#endif - -// #included from: internal/catch_capture.hpp -#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED - -// #included from: catch_result_builder.h -#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED - -// #included from: catch_result_type.h -#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED - -namespace Catch { - - // ResultWas::OfType enum - struct ResultWas { enum OfType { - Unknown = -1, - Ok = 0, - Info = 1, - Warning = 2, - - FailureBit = 0x10, - - ExpressionFailed = FailureBit | 1, - ExplicitFailure = FailureBit | 2, - - Exception = 0x100 | FailureBit, - - ThrewException = Exception | 1, - DidntThrowException = Exception | 2, - - FatalErrorCondition = 0x200 | FailureBit - - }; }; - - inline bool isOk( ResultWas::OfType resultType ) { - return ( resultType & ResultWas::FailureBit ) == 0; - } - inline bool isJustInfo( int flags ) { - return flags == ResultWas::Info; - } - - // ResultDisposition::Flags enum - struct ResultDisposition { enum Flags { - Normal = 0x00, - - ContinueOnFailure = 0x01, // Failures fail test, but execution continues - FalseTest = 0x02, // Prefix expression with ! - SuppressFail = 0x04 // Failures are reported but do not fail the test - }; }; - - inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { - return static_cast( static_cast( lhs ) | static_cast( rhs ) ); - } - - inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } - inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } - inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } - -} // end namespace Catch - -// #included from: catch_assertionresult.h -#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED - -#include - -namespace Catch { - - struct AssertionInfo - { - AssertionInfo() {} - AssertionInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - std::string const& _capturedExpression, - ResultDisposition::Flags _resultDisposition ); - - std::string macroName; - SourceLineInfo lineInfo; - std::string capturedExpression; - ResultDisposition::Flags resultDisposition; - }; - - struct AssertionResultData - { - AssertionResultData() : resultType( ResultWas::Unknown ) {} - - std::string reconstructedExpression; - std::string message; - ResultWas::OfType resultType; - }; - - class AssertionResult { - public: - AssertionResult(); - AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); - ~AssertionResult(); -# ifdef CATCH_CPP11_OR_GREATER - AssertionResult( AssertionResult const& ) = default; - AssertionResult( AssertionResult && ) = default; - AssertionResult& operator = ( AssertionResult const& ) = default; - AssertionResult& operator = ( AssertionResult && ) = default; -# endif - - bool isOk() const; - bool succeeded() const; - ResultWas::OfType getResultType() const; - bool hasExpression() const; - bool hasMessage() const; - std::string getExpression() const; - std::string getExpressionInMacro() const; - bool hasExpandedExpression() const; - std::string getExpandedExpression() const; - std::string getMessage() const; - SourceLineInfo getSourceInfo() const; - std::string getTestMacroName() const; - - protected: - AssertionInfo m_info; - AssertionResultData m_resultData; - }; - -} // end namespace Catch - -namespace Catch { - - struct TestFailureException{}; - - template class ExpressionLhs; - - struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; - - struct CopyableStream { - CopyableStream() {} - CopyableStream( CopyableStream const& other ) { - oss << other.oss.str(); - } - CopyableStream& operator=( CopyableStream const& other ) { - oss.str(""); - oss << other.oss.str(); - return *this; - } - std::ostringstream oss; - }; - - class ResultBuilder { - public: - ResultBuilder( char const* macroName, - SourceLineInfo const& lineInfo, - char const* capturedExpression, - ResultDisposition::Flags resultDisposition ); - - template - ExpressionLhs operator->* ( T const& operand ); - ExpressionLhs operator->* ( bool value ); - - template - ResultBuilder& operator << ( T const& value ) { - m_stream.oss << value; - return *this; - } - - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); - - ResultBuilder& setResultType( ResultWas::OfType result ); - ResultBuilder& setResultType( bool result ); - ResultBuilder& setLhs( std::string const& lhs ); - ResultBuilder& setRhs( std::string const& rhs ); - ResultBuilder& setOp( std::string const& op ); - - void endExpression(); - - std::string reconstructExpression() const; - AssertionResult build() const; - - void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); - void captureResult( ResultWas::OfType resultType ); - void captureExpression(); - void react(); - bool shouldDebugBreak() const; - bool allowThrows() const; - - private: - AssertionInfo m_assertionInfo; - AssertionResultData m_data; - struct ExprComponents { - ExprComponents() : testFalse( false ) {} - bool testFalse; - std::string lhs, rhs, op; - } m_exprComponents; - CopyableStream m_stream; - - bool m_shouldDebugBreak; - bool m_shouldThrow; - }; - -} // namespace Catch - -// Include after due to circular dependency: -// #included from: catch_expression_lhs.hpp -#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED - -// #included from: catch_evaluate.hpp -#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4389) // '==' : signed/unsigned mismatch -#endif - -#include - -namespace Catch { -namespace Internal { - - enum Operator { - IsEqualTo, - IsNotEqualTo, - IsLessThan, - IsGreaterThan, - IsLessThanOrEqualTo, - IsGreaterThanOrEqualTo - }; - - template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; - template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; - template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; - template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; - template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; - template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; - template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; - - template - inline T& opCast(T const& t) { return const_cast(t); } - -// nullptr_t support based on pull request #154 from Konstantin Baumann -#ifdef CATCH_CONFIG_CPP11_NULLPTR - inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } -#endif // CATCH_CONFIG_CPP11_NULLPTR - - // So the compare overloads can be operator agnostic we convey the operator as a template - // enum, which is used to specialise an Evaluator for doing the comparison. - template - class Evaluator{}; - - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs) { - return opCast( lhs ) == opCast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) != opCast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) < opCast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) > opCast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) >= opCast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) <= opCast( rhs ); - } - }; - - template - bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { - return Evaluator::evaluate( lhs, rhs ); - } - - // This level of indirection allows us to specialise for integer types - // to avoid signed/ unsigned warnings - - // "base" overload - template - bool compare( T1 const& lhs, T2 const& rhs ) { - return Evaluator::evaluate( lhs, rhs ); - } - - // unsigned X to int - template bool compare( unsigned int lhs, int rhs ) { - return applyEvaluator( lhs, static_cast( rhs ) ); - } - template bool compare( unsigned long lhs, int rhs ) { - return applyEvaluator( lhs, static_cast( rhs ) ); - } - template bool compare( unsigned char lhs, int rhs ) { - return applyEvaluator( lhs, static_cast( rhs ) ); - } - - // unsigned X to long - template bool compare( unsigned int lhs, long rhs ) { - return applyEvaluator( lhs, static_cast( rhs ) ); - } - template bool compare( unsigned long lhs, long rhs ) { - return applyEvaluator( lhs, static_cast( rhs ) ); - } - template bool compare( unsigned char lhs, long rhs ) { - return applyEvaluator( lhs, static_cast( rhs ) ); - } - - // int to unsigned X - template bool compare( int lhs, unsigned int rhs ) { - return applyEvaluator( static_cast( lhs ), rhs ); - } - template bool compare( int lhs, unsigned long rhs ) { - return applyEvaluator( static_cast( lhs ), rhs ); - } - template bool compare( int lhs, unsigned char rhs ) { - return applyEvaluator( static_cast( lhs ), rhs ); - } - - // long to unsigned X - template bool compare( long lhs, unsigned int rhs ) { - return applyEvaluator( static_cast( lhs ), rhs ); - } - template bool compare( long lhs, unsigned long rhs ) { - return applyEvaluator( static_cast( lhs ), rhs ); - } - template bool compare( long lhs, unsigned char rhs ) { - return applyEvaluator( static_cast( lhs ), rhs ); - } - - // pointer to long (when comparing against NULL) - template bool compare( long lhs, T* rhs ) { - return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); - } - template bool compare( T* lhs, long rhs ) { - return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); - } - - // pointer to int (when comparing against NULL) - template bool compare( int lhs, T* rhs ) { - return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); - } - template bool compare( T* lhs, int rhs ) { - return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); - } - -#ifdef CATCH_CONFIG_CPP11_NULLPTR - // pointer to nullptr_t (when comparing against nullptr) - template bool compare( std::nullptr_t, T* rhs ) { - return Evaluator::evaluate( NULL, rhs ); - } - template bool compare( T* lhs, std::nullptr_t ) { - return Evaluator::evaluate( lhs, NULL ); - } -#endif // CATCH_CONFIG_CPP11_NULLPTR - -} // end of namespace Internal -} // end of namespace Catch - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -// #included from: catch_tostring.h -#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED - -// #included from: catch_sfinae.hpp -#define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED - -// Try to detect if the current compiler supports SFINAE - -namespace Catch { - - struct TrueType { - static const bool value = true; - typedef void Enable; - char sizer[1]; - }; - struct FalseType { - static const bool value = false; - typedef void Disable; - char sizer[2]; - }; - -#ifdef CATCH_CONFIG_SFINAE - - template struct NotABooleanExpression; - - template struct If : NotABooleanExpression {}; - template<> struct If : TrueType {}; - template<> struct If : FalseType {}; - - template struct SizedIf; - template<> struct SizedIf : TrueType {}; - template<> struct SizedIf : FalseType {}; - -#endif // CATCH_CONFIG_SFINAE - -} // end namespace Catch - -#include -#include -#include -#include -#include - -#ifdef __OBJC__ -// #included from: catch_objc_arc.hpp -#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED - -#import - -#ifdef __has_feature -#define CATCH_ARC_ENABLED __has_feature(objc_arc) -#else -#define CATCH_ARC_ENABLED 0 -#endif - -void arcSafeRelease( NSObject* obj ); -id performOptionalSelector( id obj, SEL sel ); - -#if !CATCH_ARC_ENABLED -inline void arcSafeRelease( NSObject* obj ) { - [obj release]; -} -inline id performOptionalSelector( id obj, SEL sel ) { - if( [obj respondsToSelector: sel] ) - return [obj performSelector: sel]; - return nil; -} -#define CATCH_UNSAFE_UNRETAINED -#define CATCH_ARC_STRONG -#else -inline void arcSafeRelease( NSObject* ){} -inline id performOptionalSelector( id obj, SEL sel ) { -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" -#endif - if( [obj respondsToSelector: sel] ) - return [obj performSelector: sel]; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - return nil; -} -#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained -#define CATCH_ARC_STRONG __strong -#endif - -#endif - -#ifdef CATCH_CPP11_OR_GREATER -#include -#include -#endif - -namespace Catch { - -// Why we're here. -template -std::string toString( T const& value ); - -// Built in overloads - -std::string toString( std::string const& value ); -std::string toString( std::wstring const& value ); -std::string toString( const char* const value ); -std::string toString( char* const value ); -std::string toString( const wchar_t* const value ); -std::string toString( wchar_t* const value ); -std::string toString( int value ); -std::string toString( unsigned long value ); -std::string toString( unsigned int value ); -std::string toString( const double value ); -std::string toString( const float value ); -std::string toString( bool value ); -std::string toString( char value ); -std::string toString( signed char value ); -std::string toString( unsigned char value ); - -#ifdef CATCH_CONFIG_CPP11_NULLPTR -std::string toString( std::nullptr_t ); -#endif - -#ifdef __OBJC__ - std::string toString( NSString const * const& nsstring ); - std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); - std::string toString( NSObject* const& nsObject ); -#endif - -namespace Detail { - - extern std::string unprintableString; - -// SFINAE is currently disabled by default for all compilers. -// If the non SFINAE version of IsStreamInsertable is ambiguous for you -// and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE -#ifdef CATCH_CONFIG_SFINAE - - template - class IsStreamInsertableHelper { - template struct TrueIfSizeable : TrueType {}; - - template - static TrueIfSizeable dummy(T2*); - static FalseType dummy(...); - - public: - typedef SizedIf type; - }; - - template - struct IsStreamInsertable : IsStreamInsertableHelper::type {}; - -#else - - struct BorgType { - template BorgType( T const& ); - }; - - TrueType& testStreamable( std::ostream& ); - FalseType testStreamable( FalseType ); - - FalseType operator<<( std::ostream const&, BorgType const& ); - - template - struct IsStreamInsertable { - static std::ostream &s; - static T const&t; - enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; - }; - -#endif - -#if defined(CATCH_CPP11_OR_GREATER) - template::value - > - struct EnumStringMaker - { - static std::string convert( T const& ) { return unprintableString; } - }; - - template - struct EnumStringMaker - { - static std::string convert( T const& v ) - { - return ::Catch::toString( - static_cast::type>(v) - ); - } - }; -#endif - template - struct StringMakerBase { -#if defined(CATCH_CPP11_OR_GREATER) - template - static std::string convert( T const& v ) - { - return EnumStringMaker::convert( v ); - } -#else - template - static std::string convert( T const& ) { return unprintableString; } -#endif - }; - - template<> - struct StringMakerBase { - template - static std::string convert( T const& _value ) { - std::ostringstream oss; - oss << _value; - return oss.str(); - } - }; - - std::string rawMemoryToString( const void *object, std::size_t size ); - - template - inline std::string rawMemoryToString( const T& object ) { - return rawMemoryToString( &object, sizeof(object) ); - } - -} // end namespace Detail - -template -struct StringMaker : - Detail::StringMakerBase::value> {}; - -template -struct StringMaker { - template - static std::string convert( U* p ) { - if( !p ) - return INTERNAL_CATCH_STRINGIFY( NULL ); - else - return Detail::rawMemoryToString( p ); - } -}; - -template -struct StringMaker { - static std::string convert( R C::* p ) { - if( !p ) - return INTERNAL_CATCH_STRINGIFY( NULL ); - else - return Detail::rawMemoryToString( p ); - } -}; - -namespace Detail { - template - std::string rangeToString( InputIterator first, InputIterator last ); -} - -//template -//struct StringMaker > { -// static std::string convert( std::vector const& v ) { -// return Detail::rangeToString( v.begin(), v.end() ); -// } -//}; - -template -std::string toString( std::vector const& v ) { - return Detail::rangeToString( v.begin(), v.end() ); -} - -#ifdef CATCH_CPP11_OR_GREATER - -// toString for tuples -namespace TupleDetail { - template< - typename Tuple, - std::size_t N = 0, - bool = (N < std::tuple_size::value) - > - struct ElementPrinter { - static void print( const Tuple& tuple, std::ostream& os ) - { - os << ( N ? ", " : " " ) - << Catch::toString(std::get(tuple)); - ElementPrinter::print(tuple,os); - } - }; - - template< - typename Tuple, - std::size_t N - > - struct ElementPrinter { - static void print( const Tuple&, std::ostream& ) {} - }; - -} - -template -struct StringMaker> { - - static std::string convert( const std::tuple& tuple ) - { - std::ostringstream os; - os << '{'; - TupleDetail::ElementPrinter>::print( tuple, os ); - os << " }"; - return os.str(); - } -}; -#endif - -namespace Detail { - template - std::string makeString( T const& value ) { - return StringMaker::convert( value ); - } -} // end namespace Detail - -/// \brief converts any type to a string -/// -/// The default template forwards on to ostringstream - except when an -/// ostringstream overload does not exist - in which case it attempts to detect -/// that and writes {?}. -/// Overload (not specialise) this template for custom typs that you don't want -/// to provide an ostream overload for. -template -std::string toString( T const& value ) { - return StringMaker::convert( value ); -} - - namespace Detail { - template - std::string rangeToString( InputIterator first, InputIterator last ) { - std::ostringstream oss; - oss << "{ "; - if( first != last ) { - oss << Catch::toString( *first ); - for( ++first ; first != last ; ++first ) - oss << ", " << Catch::toString( *first ); - } - oss << " }"; - return oss.str(); - } -} - -} // end namespace Catch - -namespace Catch { - -// Wraps the LHS of an expression and captures the operator and RHS (if any) - -// wrapping them all in a ResultBuilder object -template -class ExpressionLhs { - ExpressionLhs& operator = ( ExpressionLhs const& ); -# ifdef CATCH_CPP11_OR_GREATER - ExpressionLhs& operator = ( ExpressionLhs && ) = delete; -# endif - -public: - ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {} -# ifdef CATCH_CPP11_OR_GREATER - ExpressionLhs( ExpressionLhs const& ) = default; - ExpressionLhs( ExpressionLhs && ) = default; -# endif - - template - ResultBuilder& operator == ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - ResultBuilder& operator != ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - ResultBuilder& operator < ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - ResultBuilder& operator > ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - ResultBuilder& operator <= ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - ResultBuilder& operator >= ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - ResultBuilder& operator == ( bool rhs ) { - return captureExpression( rhs ); - } - - ResultBuilder& operator != ( bool rhs ) { - return captureExpression( rhs ); - } - - void endExpression() { - bool value = m_lhs ? true : false; - m_rb - .setLhs( Catch::toString( value ) ) - .setResultType( value ) - .endExpression(); - } - - // Only simple binary expressions are allowed on the LHS. - // If more complex compositions are required then place the sub expression in parentheses - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); - -private: - template - ResultBuilder& captureExpression( RhsT const& rhs ) { - return m_rb - .setResultType( Internal::compare( m_lhs, rhs ) ) - .setLhs( Catch::toString( m_lhs ) ) - .setRhs( Catch::toString( rhs ) ) - .setOp( Internal::OperatorTraits::getName() ); - } - -private: - ResultBuilder& m_rb; - T m_lhs; -}; - -} // end namespace Catch - - -namespace Catch { - - template - inline ExpressionLhs ResultBuilder::operator->* ( T const& operand ) { - return ExpressionLhs( *this, operand ); - } - - inline ExpressionLhs ResultBuilder::operator->* ( bool value ) { - return ExpressionLhs( *this, value ); - } - -} // namespace Catch - -// #included from: catch_message.h -#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED - -#include - -namespace Catch { - - struct MessageInfo { - MessageInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ); - - std::string macroName; - SourceLineInfo lineInfo; - ResultWas::OfType type; - std::string message; - unsigned int sequence; - - bool operator == ( MessageInfo const& other ) const { - return sequence == other.sequence; - } - bool operator < ( MessageInfo const& other ) const { - return sequence < other.sequence; - } - private: - static unsigned int globalCount; - }; - - struct MessageBuilder { - MessageBuilder( std::string const& macroName, - SourceLineInfo const& lineInfo, - ResultWas::OfType type ) - : m_info( macroName, lineInfo, type ) - {} - - template - MessageBuilder& operator << ( T const& value ) { - m_stream << value; - return *this; - } - - MessageInfo m_info; - std::ostringstream m_stream; - }; - - class ScopedMessage { - public: - ScopedMessage( MessageBuilder const& builder ); - ScopedMessage( ScopedMessage const& other ); - ~ScopedMessage(); - - MessageInfo m_info; - }; - -} // end namespace Catch - -// #included from: catch_interfaces_capture.h -#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED - -#include - -namespace Catch { - - class TestCase; - class AssertionResult; - struct AssertionInfo; - struct SectionInfo; - struct MessageInfo; - class ScopedMessageBuilder; - struct Counts; - - struct IResultCapture { - - virtual ~IResultCapture(); - - virtual void assertionEnded( AssertionResult const& result ) = 0; - virtual bool sectionStarted( SectionInfo const& sectionInfo, - Counts& assertions ) = 0; - virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0; - virtual void pushScopedMessage( MessageInfo const& message ) = 0; - virtual void popScopedMessage( MessageInfo const& message ) = 0; - - virtual std::string getCurrentTestName() const = 0; - virtual const AssertionResult* getLastResult() const = 0; - - virtual void handleFatalErrorCondition( std::string const& message ) = 0; - }; - - IResultCapture& getResultCapture(); -} - -// #included from: catch_debugger.h -#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED - -// #included from: catch_platform.h -#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED - -#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) -#define CATCH_PLATFORM_MAC -#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -#define CATCH_PLATFORM_IPHONE -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) -#define CATCH_PLATFORM_WINDOWS -#endif - -#include - -namespace Catch{ - - bool isDebuggerActive(); - void writeToDebugConsole( std::string const& text ); -} - -#ifdef CATCH_PLATFORM_MAC - - // The following code snippet based on: - // http://cocoawithlove.com/2008/03/break-into-debugger.html - #ifdef DEBUG - #if defined(__ppc64__) || defined(__ppc__) - #define CATCH_BREAK_INTO_DEBUGGER() \ - if( Catch::isDebuggerActive() ) { \ - __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ - : : : "memory","r0","r3","r4" ); \ - } - #else - #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );} - #endif - #endif - -#elif defined(_MSC_VER) - #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); } -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) void __stdcall DebugBreak(); - #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); } -#endif - -#ifndef CATCH_BREAK_INTO_DEBUGGER -#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); -#endif - -// #included from: catch_interfaces_runner.h -#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED - -namespace Catch { - class TestCase; - - struct IRunner { - virtual ~IRunner(); - virtual bool aborting() const = 0; - }; -} - -/////////////////////////////////////////////////////////////////////////////// -// In the event of a failure works out if the debugger needs to be invoked -// and/or an exception thrown and takes appropriate action. -// This needs to be done as a macro so the debugger will stop in the user -// source code rather than in Catch library code -#define INTERNAL_CATCH_REACT( resultBuilder ) \ - if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ - resultBuilder.react(); - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - try { \ - ( __catchResult->*expr ).endExpression(); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ - INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ - if( Catch::getResultCapture().getLastResult()->succeeded() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ - INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ - if( !Catch::getResultCapture().getLastResult()->succeeded() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - try { \ - expr; \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( resultDisposition ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - if( __catchResult.allowThrows() ) \ - try { \ - expr; \ - __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ - } \ - catch( ... ) { \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - else \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - if( __catchResult.allowThrows() ) \ - try { \ - expr; \ - __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ - } \ - catch( exceptionType ) { \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( resultDisposition ); \ - } \ - else \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ - __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ - __catchResult.captureResult( messageType ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) -#else - #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ - __catchResult << log + ::Catch::StreamEndStop(); \ - __catchResult.captureResult( messageType ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) -#endif - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_INFO( log, macroName ) \ - Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \ - try { \ - std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \ - __catchResult \ - .setLhs( Catch::toString( arg ) ) \ - .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ - .setOp( "matches" ) \ - .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \ - __catchResult.captureExpression(); \ - } catch( ... ) { \ - __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -// #included from: internal/catch_section.h -#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED - -// #included from: catch_section_info.h -#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED - -namespace Catch { - - struct SectionInfo { - SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name, - std::string const& _description = std::string() ); - - std::string name; - std::string description; - SourceLineInfo lineInfo; - }; - -} // end namespace Catch - -// #included from: catch_totals.hpp -#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED - -#include - -namespace Catch { - - struct Counts { - Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} - - Counts operator - ( Counts const& other ) const { - Counts diff; - diff.passed = passed - other.passed; - diff.failed = failed - other.failed; - diff.failedButOk = failedButOk - other.failedButOk; - return diff; - } - Counts& operator += ( Counts const& other ) { - passed += other.passed; - failed += other.failed; - failedButOk += other.failedButOk; - return *this; - } - - std::size_t total() const { - return passed + failed + failedButOk; - } - bool allPassed() const { - return failed == 0 && failedButOk == 0; - } - bool allOk() const { - return failed == 0; - } - - std::size_t passed; - std::size_t failed; - std::size_t failedButOk; - }; - - struct Totals { - - Totals operator - ( Totals const& other ) const { - Totals diff; - diff.assertions = assertions - other.assertions; - diff.testCases = testCases - other.testCases; - return diff; - } - - Totals delta( Totals const& prevTotals ) const { - Totals diff = *this - prevTotals; - if( diff.assertions.failed > 0 ) - ++diff.testCases.failed; - else if( diff.assertions.failedButOk > 0 ) - ++diff.testCases.failedButOk; - else - ++diff.testCases.passed; - return diff; - } - - Totals& operator += ( Totals const& other ) { - assertions += other.assertions; - testCases += other.testCases; - return *this; - } - - Counts assertions; - Counts testCases; - }; -} - -// #included from: catch_timer.h -#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED - -#ifdef CATCH_PLATFORM_WINDOWS -typedef unsigned long long uint64_t; -#else -#include -#endif - -namespace Catch { - - class Timer { - public: - Timer() : m_ticks( 0 ) {} - void start(); - unsigned int getElapsedMicroseconds() const; - unsigned int getElapsedMilliseconds() const; - double getElapsedSeconds() const; - - private: - uint64_t m_ticks; - }; - -} // namespace Catch - -#include - -namespace Catch { - - class Section : NonCopyable { - public: - Section( SectionInfo const& info ); - ~Section(); - - // This indicates whether the section should be executed or not - operator bool() const; - - private: - SectionInfo m_info; - - std::string m_name; - Counts m_assertions; - bool m_sectionIncluded; - Timer m_timer; - }; - -} // end namespace Catch - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define INTERNAL_CATCH_SECTION( ... ) \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) -#else - #define INTERNAL_CATCH_SECTION( name, desc ) \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) -#endif - -// #included from: internal/catch_generators.hpp -#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED - -#include -#include -#include -#include - -namespace Catch { - -template -struct IGenerator { - virtual ~IGenerator() {} - virtual T getValue( std::size_t index ) const = 0; - virtual std::size_t size () const = 0; -}; - -template -class BetweenGenerator : public IGenerator { -public: - BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} - - virtual T getValue( std::size_t index ) const { - return m_from+static_cast( index ); - } - - virtual std::size_t size() const { - return static_cast( 1+m_to-m_from ); - } - -private: - - T m_from; - T m_to; -}; - -template -class ValuesGenerator : public IGenerator { -public: - ValuesGenerator(){} - - void add( T value ) { - m_values.push_back( value ); - } - - virtual T getValue( std::size_t index ) const { - return m_values[index]; - } - - virtual std::size_t size() const { - return m_values.size(); - } - -private: - std::vector m_values; -}; - -template -class CompositeGenerator { -public: - CompositeGenerator() : m_totalSize( 0 ) {} - - // *** Move semantics, similar to auto_ptr *** - CompositeGenerator( CompositeGenerator& other ) - : m_fileInfo( other.m_fileInfo ), - m_totalSize( 0 ) - { - move( other ); - } - - CompositeGenerator& setFileInfo( const char* fileInfo ) { - m_fileInfo = fileInfo; - return *this; - } - - ~CompositeGenerator() { - deleteAll( m_composed ); - } - - operator T () const { - size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); - - typename std::vector*>::const_iterator it = m_composed.begin(); - typename std::vector*>::const_iterator itEnd = m_composed.end(); - for( size_t index = 0; it != itEnd; ++it ) - { - const IGenerator* generator = *it; - if( overallIndex >= index && overallIndex < index + generator->size() ) - { - return generator->getValue( overallIndex-index ); - } - index += generator->size(); - } - CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); - return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so - } - - void add( const IGenerator* generator ) { - m_totalSize += generator->size(); - m_composed.push_back( generator ); - } - - CompositeGenerator& then( CompositeGenerator& other ) { - move( other ); - return *this; - } - - CompositeGenerator& then( T value ) { - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( value ); - add( valuesGen ); - return *this; - } - -private: - - void move( CompositeGenerator& other ) { - std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); - m_totalSize += other.m_totalSize; - other.m_composed.clear(); - } - - std::vector*> m_composed; - std::string m_fileInfo; - size_t m_totalSize; -}; - -namespace Generators -{ - template - CompositeGenerator between( T from, T to ) { - CompositeGenerator generators; - generators.add( new BetweenGenerator( from, to ) ); - return generators; - } - - template - CompositeGenerator values( T val1, T val2 ) { - CompositeGenerator generators; - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - generators.add( valuesGen ); - return generators; - } - - template - CompositeGenerator values( T val1, T val2, T val3 ){ - CompositeGenerator generators; - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - valuesGen->add( val3 ); - generators.add( valuesGen ); - return generators; - } - - template - CompositeGenerator values( T val1, T val2, T val3, T val4 ) { - CompositeGenerator generators; - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - valuesGen->add( val3 ); - valuesGen->add( val4 ); - generators.add( valuesGen ); - return generators; - } - -} // end namespace Generators - -using namespace Generators; - -} // end namespace Catch - -#define INTERNAL_CATCH_LINESTR2( line ) #line -#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) - -#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) - -// #included from: internal/catch_interfaces_exception.h -#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED - -#include -// #included from: catch_interfaces_registry_hub.h -#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED - -#include - -namespace Catch { - - class TestCase; - struct ITestCaseRegistry; - struct IExceptionTranslatorRegistry; - struct IExceptionTranslator; - struct IReporterRegistry; - struct IReporterFactory; - - struct IRegistryHub { - virtual ~IRegistryHub(); - - virtual IReporterRegistry const& getReporterRegistry() const = 0; - virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; - virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; - }; - - struct IMutableRegistryHub { - virtual ~IMutableRegistryHub(); - virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0; - virtual void registerTest( TestCase const& testInfo ) = 0; - virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; - }; - - IRegistryHub& getRegistryHub(); - IMutableRegistryHub& getMutableRegistryHub(); - void cleanUp(); - std::string translateActiveException(); - -} - - -namespace Catch { - - typedef std::string(*exceptionTranslateFunction)(); - - struct IExceptionTranslator { - virtual ~IExceptionTranslator(); - virtual std::string translate() const = 0; - }; - - struct IExceptionTranslatorRegistry { - virtual ~IExceptionTranslatorRegistry(); - - virtual std::string translateActiveException() const = 0; - }; - - class ExceptionTranslatorRegistrar { - template - class ExceptionTranslator : public IExceptionTranslator { - public: - - ExceptionTranslator( std::string(*translateFunction)( T& ) ) - : m_translateFunction( translateFunction ) - {} - - virtual std::string translate() const { - try { - throw; - } - catch( T& ex ) { - return m_translateFunction( ex ); - } - } - - protected: - std::string(*m_translateFunction)( T& ); - }; - - public: - template - ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { - getMutableRegistryHub().registerTranslator - ( new ExceptionTranslator( translateFunction ) ); - } - }; -} - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \ - static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \ - namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\ - static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ) - -// #included from: internal/catch_approx.hpp -#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED - -#include -#include - -namespace Catch { -namespace Detail { - - class Approx { - public: - explicit Approx ( double value ) - : m_epsilon( std::numeric_limits::epsilon()*100 ), - m_scale( 1.0 ), - m_value( value ) - {} - - Approx( Approx const& other ) - : m_epsilon( other.m_epsilon ), - m_scale( other.m_scale ), - m_value( other.m_value ) - {} - - static Approx custom() { - return Approx( 0 ); - } - - Approx operator()( double value ) { - Approx approx( value ); - approx.epsilon( m_epsilon ); - approx.scale( m_scale ); - return approx; - } - - friend bool operator == ( double lhs, Approx const& rhs ) { - // Thanks to Richard Harris for his help refining this formula - return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) ); - } - - friend bool operator == ( Approx const& lhs, double rhs ) { - return operator==( rhs, lhs ); - } - - friend bool operator != ( double lhs, Approx const& rhs ) { - return !operator==( lhs, rhs ); - } - - friend bool operator != ( Approx const& lhs, double rhs ) { - return !operator==( rhs, lhs ); - } - - Approx& epsilon( double newEpsilon ) { - m_epsilon = newEpsilon; - return *this; - } - - Approx& scale( double newScale ) { - m_scale = newScale; - return *this; - } - - std::string toString() const { - std::ostringstream oss; - oss << "Approx( " << Catch::toString( m_value ) << " )"; - return oss.str(); - } - - private: - double m_epsilon; - double m_scale; - double m_value; - }; -} - -template<> -inline std::string toString( Detail::Approx const& value ) { - return value.toString(); -} - -} // end namespace Catch - -// #included from: internal/catch_matchers.hpp -#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED - -namespace Catch { -namespace Matchers { - namespace Impl { - - template - struct Matcher : SharedImpl - { - typedef ExpressionT ExpressionType; - - virtual ~Matcher() {} - virtual Ptr clone() const = 0; - virtual bool match( ExpressionT const& expr ) const = 0; - virtual std::string toString() const = 0; - }; - - template - struct MatcherImpl : Matcher { - - virtual Ptr > clone() const { - return Ptr >( new DerivedT( static_cast( *this ) ) ); - } - }; - - namespace Generic { - - template - class AllOf : public MatcherImpl, ExpressionT> { - public: - - AllOf() {} - AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {} - - AllOf& add( Matcher const& matcher ) { - m_matchers.push_back( matcher.clone() ); - return *this; - } - virtual bool match( ExpressionT const& expr ) const - { - for( std::size_t i = 0; i < m_matchers.size(); ++i ) - if( !m_matchers[i]->match( expr ) ) - return false; - return true; - } - virtual std::string toString() const { - std::ostringstream oss; - oss << "( "; - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if( i != 0 ) - oss << " and "; - oss << m_matchers[i]->toString(); - } - oss << " )"; - return oss.str(); - } - - private: - std::vector > > m_matchers; - }; - - template - class AnyOf : public MatcherImpl, ExpressionT> { - public: - - AnyOf() {} - AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {} - - AnyOf& add( Matcher const& matcher ) { - m_matchers.push_back( matcher.clone() ); - return *this; - } - virtual bool match( ExpressionT const& expr ) const - { - for( std::size_t i = 0; i < m_matchers.size(); ++i ) - if( m_matchers[i]->match( expr ) ) - return true; - return false; - } - virtual std::string toString() const { - std::ostringstream oss; - oss << "( "; - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if( i != 0 ) - oss << " or "; - oss << m_matchers[i]->toString(); - } - oss << " )"; - return oss.str(); - } - - private: - std::vector > > m_matchers; - }; - - } - - namespace StdString { - - inline std::string makeString( std::string const& str ) { return str; } - inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); } - - struct Equals : MatcherImpl { - Equals( std::string const& str ) : m_str( str ){} - Equals( Equals const& other ) : m_str( other.m_str ){} - - virtual ~Equals(); - - virtual bool match( std::string const& expr ) const { - return m_str == expr; - } - virtual std::string toString() const { - return "equals: \"" + m_str + "\""; - } - - std::string m_str; - }; - - struct Contains : MatcherImpl { - Contains( std::string const& substr ) : m_substr( substr ){} - Contains( Contains const& other ) : m_substr( other.m_substr ){} - - virtual ~Contains(); - - virtual bool match( std::string const& expr ) const { - return expr.find( m_substr ) != std::string::npos; - } - virtual std::string toString() const { - return "contains: \"" + m_substr + "\""; - } - - std::string m_substr; - }; - - struct StartsWith : MatcherImpl { - StartsWith( std::string const& substr ) : m_substr( substr ){} - StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){} - - virtual ~StartsWith(); - - virtual bool match( std::string const& expr ) const { - return expr.find( m_substr ) == 0; - } - virtual std::string toString() const { - return "starts with: \"" + m_substr + "\""; - } - - std::string m_substr; - }; - - struct EndsWith : MatcherImpl { - EndsWith( std::string const& substr ) : m_substr( substr ){} - EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){} - - virtual ~EndsWith(); - - virtual bool match( std::string const& expr ) const { - return expr.find( m_substr ) == expr.size() - m_substr.size(); - } - virtual std::string toString() const { - return "ends with: \"" + m_substr + "\""; - } - - std::string m_substr; - }; - } // namespace StdString - } // namespace Impl - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - template - inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1, - Impl::Matcher const& m2 ) { - return Impl::Generic::AllOf().add( m1 ).add( m2 ); - } - template - inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1, - Impl::Matcher const& m2, - Impl::Matcher const& m3 ) { - return Impl::Generic::AllOf().add( m1 ).add( m2 ).add( m3 ); - } - template - inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1, - Impl::Matcher const& m2 ) { - return Impl::Generic::AnyOf().add( m1 ).add( m2 ); - } - template - inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1, - Impl::Matcher const& m2, - Impl::Matcher const& m3 ) { - return Impl::Generic::AnyOf().add( m1 ).add( m2 ).add( m3 ); - } - - inline Impl::StdString::Equals Equals( std::string const& str ) { - return Impl::StdString::Equals( str ); - } - inline Impl::StdString::Equals Equals( const char* str ) { - return Impl::StdString::Equals( Impl::StdString::makeString( str ) ); - } - inline Impl::StdString::Contains Contains( std::string const& substr ) { - return Impl::StdString::Contains( substr ); - } - inline Impl::StdString::Contains Contains( const char* substr ) { - return Impl::StdString::Contains( Impl::StdString::makeString( substr ) ); - } - inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) { - return Impl::StdString::StartsWith( substr ); - } - inline Impl::StdString::StartsWith StartsWith( const char* substr ) { - return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) ); - } - inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) { - return Impl::StdString::EndsWith( substr ); - } - inline Impl::StdString::EndsWith EndsWith( const char* substr ) { - return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) ); - } - -} // namespace Matchers - -using namespace Matchers; - -} // namespace Catch - -// #included from: internal/catch_interfaces_tag_alias_registry.h -#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED - -// #included from: catch_tag_alias.h -#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED - -#include - -namespace Catch { - - struct TagAlias { - TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} - - std::string tag; - SourceLineInfo lineInfo; - }; - - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } -// #included from: catch_option.hpp -#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED - -namespace Catch { - - // An optional type - template - class Option { - public: - Option() : nullableValue( NULL ) {} - Option( T const& _value ) - : nullableValue( new( storage ) T( _value ) ) - {} - Option( Option const& _other ) - : nullableValue( _other ? new( storage ) T( *_other ) : NULL ) - {} - - ~Option() { - reset(); - } - - Option& operator= ( Option const& _other ) { - if( &_other != this ) { - reset(); - if( _other ) - nullableValue = new( storage ) T( *_other ); - } - return *this; - } - Option& operator = ( T const& _value ) { - reset(); - nullableValue = new( storage ) T( _value ); - return *this; - } - - void reset() { - if( nullableValue ) - nullableValue->~T(); - nullableValue = NULL; - } - - T& operator*() { return *nullableValue; } - T const& operator*() const { return *nullableValue; } - T* operator->() { return nullableValue; } - const T* operator->() const { return nullableValue; } - - T valueOr( T const& defaultValue ) const { - return nullableValue ? *nullableValue : defaultValue; - } - - bool some() const { return nullableValue != NULL; } - bool none() const { return nullableValue == NULL; } - - bool operator !() const { return nullableValue == NULL; } - operator SafeBool::type() const { - return SafeBool::makeSafe( some() ); - } - - private: - T* nullableValue; - char storage[sizeof(T)]; - }; - -} // end namespace Catch - -namespace Catch { - - struct ITagAliasRegistry { - virtual ~ITagAliasRegistry(); - virtual Option find( std::string const& alias ) const = 0; - virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; - - static ITagAliasRegistry const& get(); - }; - -} // end namespace Catch - -// These files are included here so the single_include script doesn't put them -// in the conditionally compiled sections -// #included from: internal/catch_test_case_info.h -#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED - -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - struct ITestCase; - - struct TestCaseInfo { - enum SpecialProperties{ - None = 0, - IsHidden = 1 << 1, - ShouldFail = 1 << 2, - MayFail = 1 << 3, - Throws = 1 << 4 - }; - - TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::set const& _tags, - SourceLineInfo const& _lineInfo ); - - TestCaseInfo( TestCaseInfo const& other ); - - bool isHidden() const; - bool throws() const; - bool okToFail() const; - bool expectedToFail() const; - - std::string name; - std::string className; - std::string description; - std::set tags; - std::set lcaseTags; - std::string tagsAsString; - SourceLineInfo lineInfo; - SpecialProperties properties; - }; - - class TestCase : public TestCaseInfo { - public: - - TestCase( ITestCase* testCase, TestCaseInfo const& info ); - TestCase( TestCase const& other ); - - TestCase withName( std::string const& _newName ) const; - - void invoke() const; - - TestCaseInfo const& getTestCaseInfo() const; - - void swap( TestCase& other ); - bool operator == ( TestCase const& other ) const; - bool operator < ( TestCase const& other ) const; - TestCase& operator = ( TestCase const& other ); - - private: - Ptr test; - }; - - TestCase makeTestCase( ITestCase* testCase, - std::string const& className, - std::string const& name, - std::string const& description, - SourceLineInfo const& lineInfo ); -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - - -#ifdef __OBJC__ -// #included from: internal/catch_objc.hpp -#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED - -#import - -#include - -// NB. Any general catch headers included here must be included -// in catch.hpp first to make sure they are included by the single -// header for non obj-usage - -/////////////////////////////////////////////////////////////////////////////// -// This protocol is really only here for (self) documenting purposes, since -// all its methods are optional. -@protocol OcFixture - -@optional - --(void) setUp; --(void) tearDown; - -@end - -namespace Catch { - - class OcMethod : public SharedImpl { - - public: - OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} - - virtual void invoke() const { - id obj = [[m_cls alloc] init]; - - performOptionalSelector( obj, @selector(setUp) ); - performOptionalSelector( obj, m_sel ); - performOptionalSelector( obj, @selector(tearDown) ); - - arcSafeRelease( obj ); - } - private: - virtual ~OcMethod() {} - - Class m_cls; - SEL m_sel; - }; - - namespace Detail{ - - inline std::string getAnnotation( Class cls, - std::string const& annotationName, - std::string const& testCaseName ) { - NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; - SEL sel = NSSelectorFromString( selStr ); - arcSafeRelease( selStr ); - id value = performOptionalSelector( cls, sel ); - if( value ) - return [(NSString*)value UTF8String]; - return ""; - } - } - - inline size_t registerTestMethods() { - size_t noTestMethods = 0; - int noClasses = objc_getClassList( NULL, 0 ); - - Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); - objc_getClassList( classes, noClasses ); - - for( int c = 0; c < noClasses; c++ ) { - Class cls = classes[c]; - { - u_int count; - Method* methods = class_copyMethodList( cls, &count ); - for( u_int m = 0; m < count ; m++ ) { - SEL selector = method_getName(methods[m]); - std::string methodName = sel_getName(selector); - if( startsWith( methodName, "Catch_TestCase_" ) ) { - std::string testCaseName = methodName.substr( 15 ); - std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); - std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); - const char* className = class_getName( cls ); - - getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); - noTestMethods++; - } - } - free(methods); - } - } - return noTestMethods; - } - - namespace Matchers { - namespace Impl { - namespace NSStringMatchers { - - template - struct StringHolder : MatcherImpl{ - StringHolder( NSString* substr ) : m_substr( [substr copy] ){} - StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} - StringHolder() { - arcSafeRelease( m_substr ); - } - - NSString* m_substr; - }; - - struct Equals : StringHolder { - Equals( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str isEqualToString:m_substr]; - } - - virtual std::string toString() const { - return "equals string: " + Catch::toString( m_substr ); - } - }; - - struct Contains : StringHolder { - Contains( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location != NSNotFound; - } - - virtual std::string toString() const { - return "contains string: " + Catch::toString( m_substr ); - } - }; - - struct StartsWith : StringHolder { - StartsWith( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == 0; - } - - virtual std::string toString() const { - return "starts with: " + Catch::toString( m_substr ); - } - }; - struct EndsWith : StringHolder { - EndsWith( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == [str length] - [m_substr length]; - } - - virtual std::string toString() const { - return "ends with: " + Catch::toString( m_substr ); - } - }; - - } // namespace NSStringMatchers - } // namespace Impl - - inline Impl::NSStringMatchers::Equals - Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } - - inline Impl::NSStringMatchers::Contains - Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } - - inline Impl::NSStringMatchers::StartsWith - StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } - - inline Impl::NSStringMatchers::EndsWith - EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } - - } // namespace Matchers - - using namespace Matchers; - -} // namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define OC_TEST_CASE( name, desc )\ -+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ -{\ -return @ name; \ -}\ -+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ -{ \ -return @ desc; \ -} \ --(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) - -#endif - -#ifdef CATCH_IMPL -// #included from: internal/catch_impl.hpp -#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED - -// Collect all the implementation files together here -// These are the equivalent of what would usually be cpp files - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wweak-vtables" -#endif - -// #included from: ../catch_runner.hpp -#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED - -// #included from: internal/catch_commandline.hpp -#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED - -// #included from: catch_config.hpp -#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED - -// #included from: catch_test_spec_parser.hpp -#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -// #included from: catch_test_spec.hpp -#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -#include -#include - -namespace Catch { - - class TestSpec { - struct Pattern : SharedImpl<> { - virtual ~Pattern(); - virtual bool matches( TestCaseInfo const& testCase ) const = 0; - }; - class NamePattern : public Pattern { - enum WildcardPosition { - NoWildcard = 0, - WildcardAtStart = 1, - WildcardAtEnd = 2, - WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd - }; - - public: - NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) { - if( startsWith( m_name, "*" ) ) { - m_name = m_name.substr( 1 ); - m_wildcard = WildcardAtStart; - } - if( endsWith( m_name, "*" ) ) { - m_name = m_name.substr( 0, m_name.size()-1 ); - m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); - } - } - virtual ~NamePattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { - switch( m_wildcard ) { - case NoWildcard: - return m_name == toLower( testCase.name ); - case WildcardAtStart: - return endsWith( toLower( testCase.name ), m_name ); - case WildcardAtEnd: - return startsWith( toLower( testCase.name ), m_name ); - case WildcardAtBothEnds: - return contains( toLower( testCase.name ), m_name ); - } - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunreachable-code" -#endif - throw std::logic_error( "Unknown enum" ); -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - } - private: - std::string m_name; - WildcardPosition m_wildcard; - }; - class TagPattern : public Pattern { - public: - TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} - virtual ~TagPattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { - return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); - } - private: - std::string m_tag; - }; - class ExcludedPattern : public Pattern { - public: - ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} - virtual ~ExcludedPattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } - private: - Ptr m_underlyingPattern; - }; - - struct Filter { - std::vector > m_patterns; - - bool matches( TestCaseInfo const& testCase ) const { - // All patterns in a filter must match for the filter to be a match - for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) - if( !(*it)->matches( testCase ) ) - return false; - return true; - } - }; - - public: - bool hasFilters() const { - return !m_filters.empty(); - } - bool matches( TestCaseInfo const& testCase ) const { - // A TestSpec matches if any filter matches - for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) - if( it->matches( testCase ) ) - return true; - return false; - } - - private: - std::vector m_filters; - - friend class TestSpecParser; - }; -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -namespace Catch { - - class TestSpecParser { - enum Mode{ None, Name, QuotedName, Tag }; - Mode m_mode; - bool m_exclusion; - std::size_t m_start, m_pos; - std::string m_arg; - TestSpec::Filter m_currentFilter; - TestSpec m_testSpec; - ITagAliasRegistry const* m_tagAliases; - - public: - TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} - - TestSpecParser& parse( std::string const& arg ) { - m_mode = None; - m_exclusion = false; - m_start = std::string::npos; - m_arg = m_tagAliases->expandAliases( arg ); - for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) - visitChar( m_arg[m_pos] ); - if( m_mode == Name ) - addPattern(); - return *this; - } - TestSpec testSpec() { - addFilter(); - return m_testSpec; - } - private: - void visitChar( char c ) { - if( m_mode == None ) { - switch( c ) { - case ' ': return; - case '~': m_exclusion = true; return; - case '[': return startNewMode( Tag, ++m_pos ); - case '"': return startNewMode( QuotedName, ++m_pos ); - default: startNewMode( Name, m_pos ); break; - } - } - if( m_mode == Name ) { - if( c == ',' ) { - addPattern(); - addFilter(); - } - else if( c == '[' ) { - if( subString() == "exclude:" ) - m_exclusion = true; - else - addPattern(); - startNewMode( Tag, ++m_pos ); - } - } - else if( m_mode == QuotedName && c == '"' ) - addPattern(); - else if( m_mode == Tag && c == ']' ) - addPattern(); - } - void startNewMode( Mode mode, std::size_t start ) { - m_mode = mode; - m_start = start; - } - std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } - template - void addPattern() { - std::string token = subString(); - if( startsWith( token, "exclude:" ) ) { - m_exclusion = true; - token = token.substr( 8 ); - } - if( !token.empty() ) { - Ptr pattern = new T( token ); - if( m_exclusion ) - pattern = new TestSpec::ExcludedPattern( pattern ); - m_currentFilter.m_patterns.push_back( pattern ); - } - m_exclusion = false; - m_mode = None; - } - void addFilter() { - if( !m_currentFilter.m_patterns.empty() ) { - m_testSpec.m_filters.push_back( m_currentFilter ); - m_currentFilter = TestSpec::Filter(); - } - } - }; - inline TestSpec parseTestSpec( std::string const& arg ) { - return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); - } - -} // namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// #included from: catch_interfaces_config.h -#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED - -#include -#include -#include - -namespace Catch { - - struct Verbosity { enum Level { - NoOutput = 0, - Quiet, - Normal - }; }; - - struct WarnAbout { enum What { - Nothing = 0x00, - NoAssertions = 0x01 - }; }; - - struct ShowDurations { enum OrNot { - DefaultForReporter, - Always, - Never - }; }; - struct RunTests { enum InWhatOrder { - InDeclarationOrder, - InLexicographicalOrder, - InRandomOrder - }; }; - - class TestSpec; - - struct IConfig : IShared { - - virtual ~IConfig(); - - virtual bool allowThrows() const = 0; - virtual std::ostream& stream() const = 0; - virtual std::string name() const = 0; - virtual bool includeSuccessfulResults() const = 0; - virtual bool shouldDebugBreak() const = 0; - virtual bool warnAboutMissingAssertions() const = 0; - virtual int abortAfter() const = 0; - virtual bool showInvisibles() const = 0; - virtual ShowDurations::OrNot showDurations() const = 0; - virtual TestSpec const& testSpec() const = 0; - virtual RunTests::InWhatOrder runOrder() const = 0; - virtual unsigned int rngSeed() const = 0; - virtual bool forceColour() const = 0; - }; -} - -// #included from: catch_stream.h -#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED - -#include - -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - class Stream { - public: - Stream(); - Stream( std::streambuf* _streamBuf, bool _isOwned ); - void release(); - - std::streambuf* streamBuf; - - private: - bool isOwned; - }; - - std::ostream& cout(); - std::ostream& cerr(); -} - -#include -#include -#include -#include -#include - -#ifndef CATCH_CONFIG_CONSOLE_WIDTH -#define CATCH_CONFIG_CONSOLE_WIDTH 80 -#endif - -namespace Catch { - - struct ConfigData { - - ConfigData() - : listTests( false ), - listTags( false ), - listReporters( false ), - listTestNamesOnly( false ), - showSuccessfulTests( false ), - shouldDebugBreak( false ), - noThrow( false ), - showHelp( false ), - showInvisibles( false ), - forceColour( false ), - abortAfter( -1 ), - rngSeed( 0 ), - verbosity( Verbosity::Normal ), - warnings( WarnAbout::Nothing ), - showDurations( ShowDurations::DefaultForReporter ), - runOrder( RunTests::InDeclarationOrder ) - {} - - bool listTests; - bool listTags; - bool listReporters; - bool listTestNamesOnly; - - bool showSuccessfulTests; - bool shouldDebugBreak; - bool noThrow; - bool showHelp; - bool showInvisibles; - bool forceColour; - - int abortAfter; - unsigned int rngSeed; - - Verbosity::Level verbosity; - WarnAbout::What warnings; - ShowDurations::OrNot showDurations; - RunTests::InWhatOrder runOrder; - - std::string reporterName; - std::string outputFilename; - std::string name; - std::string processName; - - std::vector testsOrTags; - }; - - class Config : public SharedImpl { - private: - Config( Config const& other ); - Config& operator = ( Config const& other ); - virtual void dummy(); - public: - - Config() - : m_os( Catch::cout().rdbuf() ) - {} - - Config( ConfigData const& data ) - : m_data( data ), - m_os( Catch::cout().rdbuf() ) - { - if( !data.testsOrTags.empty() ) { - TestSpecParser parser( ITagAliasRegistry::get() ); - for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) - parser.parse( data.testsOrTags[i] ); - m_testSpec = parser.testSpec(); - } - } - - virtual ~Config() { - m_os.rdbuf( Catch::cout().rdbuf() ); - m_stream.release(); - } - - void setFilename( std::string const& filename ) { - m_data.outputFilename = filename; - } - - std::string const& getFilename() const { - return m_data.outputFilename ; - } - - bool listTests() const { return m_data.listTests; } - bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } - bool listTags() const { return m_data.listTags; } - bool listReporters() const { return m_data.listReporters; } - - std::string getProcessName() const { return m_data.processName; } - - bool shouldDebugBreak() const { return m_data.shouldDebugBreak; } - - void setStreamBuf( std::streambuf* buf ) { - m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() ); - } - - void useStream( std::string const& streamName ) { - Stream stream = createStream( streamName ); - setStreamBuf( stream.streamBuf ); - m_stream.release(); - m_stream = stream; - } - - std::string getReporterName() const { return m_data.reporterName; } - - int abortAfter() const { return m_data.abortAfter; } - - TestSpec const& testSpec() const { return m_testSpec; } - - bool showHelp() const { return m_data.showHelp; } - bool showInvisibles() const { return m_data.showInvisibles; } - - // IConfig interface - virtual bool allowThrows() const { return !m_data.noThrow; } - virtual std::ostream& stream() const { return m_os; } - virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } - virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; } - virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; } - virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; } - virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; } - virtual unsigned int rngSeed() const { return m_data.rngSeed; } - virtual bool forceColour() const { return m_data.forceColour; } - - private: - ConfigData m_data; - - Stream m_stream; - mutable std::ostream m_os; - TestSpec m_testSpec; - }; - -} // end namespace Catch - -// #included from: catch_clara.h -#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED - -// Use Catch's value for console width (store Clara's off to the side, if present) -#ifdef CLARA_CONFIG_CONSOLE_WIDTH -#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH -#undef CLARA_CONFIG_CONSOLE_WIDTH -#endif -#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - -// Declare Clara inside the Catch namespace -#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { -// #included from: ../external/clara.h - -// Only use header guard if we are not using an outer namespace -#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) - -#ifndef STITCH_CLARA_OPEN_NAMESPACE -#define TWOBLUECUBES_CLARA_H_INCLUDED -#define STITCH_CLARA_OPEN_NAMESPACE -#define STITCH_CLARA_CLOSE_NAMESPACE -#else -#define STITCH_CLARA_CLOSE_NAMESPACE } -#endif - -#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE - -// ----------- #included from tbc_text_format.h ----------- - -// Only use header guard if we are not using an outer namespace -#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) -#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -#define TBC_TEXT_FORMAT_H_INCLUDED -#endif - -#include -#include -#include - -// Use optional outer namespace -#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { -#endif - -namespace Tbc { - -#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH - const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - struct TextAttributes { - TextAttributes() - : initialIndent( std::string::npos ), - indent( 0 ), - width( consoleWidth-1 ), - tabChar( '\t' ) - {} - - TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } - TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } - TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } - TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } - - std::size_t initialIndent; // indent of first line, or npos - std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos - std::size_t width; // maximum width of text, including indent. Longer text will wrap - char tabChar; // If this char is seen the indent is changed to current pos - }; - - class Text { - public: - Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) - : attr( _attr ) - { - std::string wrappableChars = " [({.,/|\\-"; - std::size_t indent = _attr.initialIndent != std::string::npos - ? _attr.initialIndent - : _attr.indent; - std::string remainder = _str; - - while( !remainder.empty() ) { - if( lines.size() >= 1000 ) { - lines.push_back( "... message truncated due to excessive size" ); - return; - } - std::size_t tabPos = std::string::npos; - std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); - std::size_t pos = remainder.find_first_of( '\n' ); - if( pos <= width ) { - width = pos; - } - pos = remainder.find_last_of( _attr.tabChar, width ); - if( pos != std::string::npos ) { - tabPos = pos; - if( remainder[width] == '\n' ) - width--; - remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); - } - - if( width == remainder.size() ) { - spliceLine( indent, remainder, width ); - } - else if( remainder[width] == '\n' ) { - spliceLine( indent, remainder, width ); - if( width <= 1 || remainder.size() != 1 ) - remainder = remainder.substr( 1 ); - indent = _attr.indent; - } - else { - pos = remainder.find_last_of( wrappableChars, width ); - if( pos != std::string::npos && pos > 0 ) { - spliceLine( indent, remainder, pos ); - if( remainder[0] == ' ' ) - remainder = remainder.substr( 1 ); - } - else { - spliceLine( indent, remainder, width-1 ); - lines.back() += "-"; - } - if( lines.size() == 1 ) - indent = _attr.indent; - if( tabPos != std::string::npos ) - indent += tabPos; - } - } - } - - void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { - lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); - _remainder = _remainder.substr( _pos ); - } - - typedef std::vector::const_iterator const_iterator; - - const_iterator begin() const { return lines.begin(); } - const_iterator end() const { return lines.end(); } - std::string const& last() const { return lines.back(); } - std::size_t size() const { return lines.size(); } - std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } - std::string toString() const { - std::ostringstream oss; - oss << *this; - return oss.str(); - } - - inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { - for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); - it != itEnd; ++it ) { - if( it != _text.begin() ) - _stream << "\n"; - _stream << *it; - } - return _stream; - } - - private: - std::string str; - TextAttributes attr; - std::vector lines; - }; - -} // end namespace Tbc - -#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -} // end outer namespace -#endif - -#endif // TBC_TEXT_FORMAT_H_INCLUDED - -// ----------- end of #include from tbc_text_format.h ----------- -// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h - -#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE - -#include -#include -#include -#include - -// Use optional outer namespace -#ifdef STITCH_CLARA_OPEN_NAMESPACE -STITCH_CLARA_OPEN_NAMESPACE -#endif - -namespace Clara { - - struct UnpositionalTag {}; - - extern UnpositionalTag _; - -#ifdef CLARA_CONFIG_MAIN - UnpositionalTag _; -#endif - - namespace Detail { - -#ifdef CLARA_CONSOLE_WIDTH - const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - using namespace Tbc; - - inline bool startsWith( std::string const& str, std::string const& prefix ) { - return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; - } - - template struct RemoveConstRef{ typedef T type; }; - template struct RemoveConstRef{ typedef T type; }; - template struct RemoveConstRef{ typedef T type; }; - template struct RemoveConstRef{ typedef T type; }; - - template struct IsBool { static const bool value = false; }; - template<> struct IsBool { static const bool value = true; }; - - template - void convertInto( std::string const& _source, T& _dest ) { - std::stringstream ss; - ss << _source; - ss >> _dest; - if( ss.fail() ) - throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); - } - inline void convertInto( std::string const& _source, std::string& _dest ) { - _dest = _source; - } - inline void convertInto( std::string const& _source, bool& _dest ) { - std::string sourceLC = _source; - std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower ); - if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) - _dest = true; - else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) - _dest = false; - else - throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); - } - inline void convertInto( bool _source, bool& _dest ) { - _dest = _source; - } - template - inline void convertInto( bool, T& ) { - throw std::runtime_error( "Invalid conversion" ); - } - - template - struct IArgFunction { - virtual ~IArgFunction() {} -# ifdef CATCH_CPP11_OR_GREATER - IArgFunction() = default; - IArgFunction( IArgFunction const& ) = default; -# endif - virtual void set( ConfigT& config, std::string const& value ) const = 0; - virtual void setFlag( ConfigT& config ) const = 0; - virtual bool takesArg() const = 0; - virtual IArgFunction* clone() const = 0; - }; - - template - class BoundArgFunction { - public: - BoundArgFunction() : functionObj( NULL ) {} - BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} - BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {} - BoundArgFunction& operator = ( BoundArgFunction const& other ) { - IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL; - delete functionObj; - functionObj = newFunctionObj; - return *this; - } - ~BoundArgFunction() { delete functionObj; } - - void set( ConfigT& config, std::string const& value ) const { - functionObj->set( config, value ); - } - void setFlag( ConfigT& config ) const { - functionObj->setFlag( config ); - } - bool takesArg() const { return functionObj->takesArg(); } - - bool isSet() const { - return functionObj != NULL; - } - private: - IArgFunction* functionObj; - }; - - template - struct NullBinder : IArgFunction{ - virtual void set( C&, std::string const& ) const {} - virtual void setFlag( C& ) const {} - virtual bool takesArg() const { return true; } - virtual IArgFunction* clone() const { return new NullBinder( *this ); } - }; - - template - struct BoundDataMember : IArgFunction{ - BoundDataMember( M C::* _member ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - convertInto( stringValue, p.*member ); - } - virtual void setFlag( C& p ) const { - convertInto( true, p.*member ); - } - virtual bool takesArg() const { return !IsBool::value; } - virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } - M C::* member; - }; - template - struct BoundUnaryMethod : IArgFunction{ - BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - typename RemoveConstRef::type value; - convertInto( stringValue, value ); - (p.*member)( value ); - } - virtual void setFlag( C& p ) const { - typename RemoveConstRef::type value; - convertInto( true, value ); - (p.*member)( value ); - } - virtual bool takesArg() const { return !IsBool::value; } - virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } - void (C::*member)( M ); - }; - template - struct BoundNullaryMethod : IArgFunction{ - BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - bool value; - convertInto( stringValue, value ); - if( value ) - (p.*member)(); - } - virtual void setFlag( C& p ) const { - (p.*member)(); - } - virtual bool takesArg() const { return false; } - virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } - void (C::*member)(); - }; - - template - struct BoundUnaryFunction : IArgFunction{ - BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} - virtual void set( C& obj, std::string const& stringValue ) const { - bool value; - convertInto( stringValue, value ); - if( value ) - function( obj ); - } - virtual void setFlag( C& p ) const { - function( p ); - } - virtual bool takesArg() const { return false; } - virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } - void (*function)( C& ); - }; - - template - struct BoundBinaryFunction : IArgFunction{ - BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} - virtual void set( C& obj, std::string const& stringValue ) const { - typename RemoveConstRef::type value; - convertInto( stringValue, value ); - function( obj, value ); - } - virtual void setFlag( C& obj ) const { - typename RemoveConstRef::type value; - convertInto( true, value ); - function( obj, value ); - } - virtual bool takesArg() const { return !IsBool::value; } - virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } - void (*function)( C&, T ); - }; - - } // namespace Detail - - struct Parser { - Parser() : separators( " \t=:" ) {} - - struct Token { - enum Type { Positional, ShortOpt, LongOpt }; - Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} - Type type; - std::string data; - }; - - void parseIntoTokens( int argc, char const * const * argv, std::vector& tokens ) const { - const std::string doubleDash = "--"; - for( int i = 1; i < argc && argv[i] != doubleDash; ++i ) - parseIntoTokens( argv[i] , tokens); - } - void parseIntoTokens( std::string arg, std::vector& tokens ) const { - while( !arg.empty() ) { - Parser::Token token( Parser::Token::Positional, arg ); - arg = ""; - if( token.data[0] == '-' ) { - if( token.data.size() > 1 && token.data[1] == '-' ) { - token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) ); - } - else { - token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) ); - if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) { - arg = "-" + token.data.substr( 1 ); - token.data = token.data.substr( 0, 1 ); - } - } - } - if( token.type != Parser::Token::Positional ) { - std::size_t pos = token.data.find_first_of( separators ); - if( pos != std::string::npos ) { - arg = token.data.substr( pos+1 ); - token.data = token.data.substr( 0, pos ); - } - } - tokens.push_back( token ); - } - } - std::string separators; - }; - - template - struct CommonArgProperties { - CommonArgProperties() {} - CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} - - Detail::BoundArgFunction boundField; - std::string description; - std::string detail; - std::string placeholder; // Only value if boundField takes an arg - - bool takesArg() const { - return !placeholder.empty(); - } - void validate() const { - if( !boundField.isSet() ) - throw std::logic_error( "option not bound" ); - } - }; - struct OptionArgProperties { - std::vector shortNames; - std::string longName; - - bool hasShortName( std::string const& shortName ) const { - return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); - } - bool hasLongName( std::string const& _longName ) const { - return _longName == longName; - } - }; - struct PositionalArgProperties { - PositionalArgProperties() : position( -1 ) {} - int position; // -1 means non-positional (floating) - - bool isFixedPositional() const { - return position != -1; - } - }; - - template - class CommandLine { - - struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { - Arg() {} - Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} - - using CommonArgProperties::placeholder; // !TBD - - std::string dbgName() const { - if( !longName.empty() ) - return "--" + longName; - if( !shortNames.empty() ) - return "-" + shortNames[0]; - return "positional args"; - } - std::string commands() const { - std::ostringstream oss; - bool first = true; - std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); - for(; it != itEnd; ++it ) { - if( first ) - first = false; - else - oss << ", "; - oss << "-" << *it; - } - if( !longName.empty() ) { - if( !first ) - oss << ", "; - oss << "--" << longName; - } - if( !placeholder.empty() ) - oss << " <" << placeholder << ">"; - return oss.str(); - } - }; - - // NOTE: std::auto_ptr is deprecated in c++11/c++0x -#if defined(__cplusplus) && __cplusplus > 199711L - typedef std::unique_ptr ArgAutoPtr; -#else - typedef std::auto_ptr ArgAutoPtr; -#endif - - friend void addOptName( Arg& arg, std::string const& optName ) - { - if( optName.empty() ) - return; - if( Detail::startsWith( optName, "--" ) ) { - if( !arg.longName.empty() ) - throw std::logic_error( "Only one long opt may be specified. '" - + arg.longName - + "' already specified, now attempting to add '" - + optName + "'" ); - arg.longName = optName.substr( 2 ); - } - else if( Detail::startsWith( optName, "-" ) ) - arg.shortNames.push_back( optName.substr( 1 ) ); - else - throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); - } - friend void setPositionalArg( Arg& arg, int position ) - { - arg.position = position; - } - - class ArgBuilder { - public: - ArgBuilder( Arg* arg ) : m_arg( arg ) {} - - // Bind a non-boolean data member (requires placeholder string) - template - void bind( M C::* field, std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundDataMember( field ); - m_arg->placeholder = placeholder; - } - // Bind a boolean data member (no placeholder required) - template - void bind( bool C::* field ) { - m_arg->boundField = new Detail::BoundDataMember( field ); - } - - // Bind a method taking a single, non-boolean argument (requires a placeholder string) - template - void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); - m_arg->placeholder = placeholder; - } - - // Bind a method taking a single, boolean argument (no placeholder string required) - template - void bind( void (C::* unaryMethod)( bool ) ) { - m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); - } - - // Bind a method that takes no arguments (will be called if opt is present) - template - void bind( void (C::* nullaryMethod)() ) { - m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); - } - - // Bind a free function taking a single argument - the object to operate on (no placeholder string required) - template - void bind( void (* unaryFunction)( C& ) ) { - m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); - } - - // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) - template - void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); - m_arg->placeholder = placeholder; - } - - ArgBuilder& describe( std::string const& description ) { - m_arg->description = description; - return *this; - } - ArgBuilder& detail( std::string const& detail ) { - m_arg->detail = detail; - return *this; - } - - protected: - Arg* m_arg; - }; - - class OptBuilder : public ArgBuilder { - public: - OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} - OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} - - OptBuilder& operator[]( std::string const& optName ) { - addOptName( *ArgBuilder::m_arg, optName ); - return *this; - } - }; - - public: - - CommandLine() - : m_boundProcessName( new Detail::NullBinder() ), - m_highestSpecifiedArgPosition( 0 ), - m_throwOnUnrecognisedTokens( false ) - {} - CommandLine( CommandLine const& other ) - : m_boundProcessName( other.m_boundProcessName ), - m_options ( other.m_options ), - m_positionalArgs( other.m_positionalArgs ), - m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), - m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) - { - if( other.m_floatingArg.get() ) - m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); - } - - CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { - m_throwOnUnrecognisedTokens = shouldThrow; - return *this; - } - - OptBuilder operator[]( std::string const& optName ) { - m_options.push_back( Arg() ); - addOptName( m_options.back(), optName ); - OptBuilder builder( &m_options.back() ); - return builder; - } - - ArgBuilder operator[]( int position ) { - m_positionalArgs.insert( std::make_pair( position, Arg() ) ); - if( position > m_highestSpecifiedArgPosition ) - m_highestSpecifiedArgPosition = position; - setPositionalArg( m_positionalArgs[position], position ); - ArgBuilder builder( &m_positionalArgs[position] ); - return builder; - } - - // Invoke this with the _ instance - ArgBuilder operator[]( UnpositionalTag ) { - if( m_floatingArg.get() ) - throw std::logic_error( "Only one unpositional argument can be added" ); - m_floatingArg.reset( new Arg() ); - ArgBuilder builder( m_floatingArg.get() ); - return builder; - } - - template - void bindProcessName( M C::* field ) { - m_boundProcessName = new Detail::BoundDataMember( field ); - } - template - void bindProcessName( void (C::*_unaryMethod)( M ) ) { - m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); - } - - void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { - typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; - std::size_t maxWidth = 0; - for( it = itBegin; it != itEnd; ++it ) - maxWidth = (std::max)( maxWidth, it->commands().size() ); - - for( it = itBegin; it != itEnd; ++it ) { - Detail::Text usage( it->commands(), Detail::TextAttributes() - .setWidth( maxWidth+indent ) - .setIndent( indent ) ); - Detail::Text desc( it->description, Detail::TextAttributes() - .setWidth( width - maxWidth - 3 ) ); - - for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { - std::string usageCol = i < usage.size() ? usage[i] : ""; - os << usageCol; - - if( i < desc.size() && !desc[i].empty() ) - os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) - << desc[i]; - os << "\n"; - } - } - } - std::string optUsage() const { - std::ostringstream oss; - optUsage( oss ); - return oss.str(); - } - - void argSynopsis( std::ostream& os ) const { - for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { - if( i > 1 ) - os << " "; - typename std::map::const_iterator it = m_positionalArgs.find( i ); - if( it != m_positionalArgs.end() ) - os << "<" << it->second.placeholder << ">"; - else if( m_floatingArg.get() ) - os << "<" << m_floatingArg->placeholder << ">"; - else - throw std::logic_error( "non consecutive positional arguments with no floating args" ); - } - // !TBD No indication of mandatory args - if( m_floatingArg.get() ) { - if( m_highestSpecifiedArgPosition > 1 ) - os << " "; - os << "[<" << m_floatingArg->placeholder << "> ...]"; - } - } - std::string argSynopsis() const { - std::ostringstream oss; - argSynopsis( oss ); - return oss.str(); - } - - void usage( std::ostream& os, std::string const& procName ) const { - validate(); - os << "usage:\n " << procName << " "; - argSynopsis( os ); - if( !m_options.empty() ) { - os << " [options]\n\nwhere options are: \n"; - optUsage( os, 2 ); - } - os << "\n"; - } - std::string usage( std::string const& procName ) const { - std::ostringstream oss; - usage( oss, procName ); - return oss.str(); - } - - ConfigT parse( int argc, char const * const * argv ) const { - ConfigT config; - parseInto( argc, argv, config ); - return config; - } - - std::vector parseInto( int argc, char const * const * argv, ConfigT& config ) const { - std::string processName = argv[0]; - std::size_t lastSlash = processName.find_last_of( "/\\" ); - if( lastSlash != std::string::npos ) - processName = processName.substr( lastSlash+1 ); - m_boundProcessName.set( config, processName ); - std::vector tokens; - Parser parser; - parser.parseIntoTokens( argc, argv, tokens ); - return populate( tokens, config ); - } - - std::vector populate( std::vector const& tokens, ConfigT& config ) const { - validate(); - std::vector unusedTokens = populateOptions( tokens, config ); - unusedTokens = populateFixedArgs( unusedTokens, config ); - unusedTokens = populateFloatingArgs( unusedTokens, config ); - return unusedTokens; - } - - std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { - std::vector unusedTokens; - std::vector errors; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); - for(; it != itEnd; ++it ) { - Arg const& arg = *it; - - try { - if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || - ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { - if( arg.takesArg() ) { - if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) - errors.push_back( "Expected argument to option: " + token.data ); - else - arg.boundField.set( config, tokens[++i].data ); - } - else { - arg.boundField.setFlag( config ); - } - break; - } - } - catch( std::exception& ex ) { - errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); - } - } - if( it == itEnd ) { - if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) - unusedTokens.push_back( token ); - else if( errors.empty() && m_throwOnUnrecognisedTokens ) - errors.push_back( "unrecognised option: " + token.data ); - } - } - if( !errors.empty() ) { - std::ostringstream oss; - for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); - it != itEnd; - ++it ) { - if( it != errors.begin() ) - oss << "\n"; - oss << *it; - } - throw std::runtime_error( oss.str() ); - } - return unusedTokens; - } - std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { - std::vector unusedTokens; - int position = 1; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - typename std::map::const_iterator it = m_positionalArgs.find( position ); - if( it != m_positionalArgs.end() ) - it->second.boundField.set( config, token.data ); - else - unusedTokens.push_back( token ); - if( token.type == Parser::Token::Positional ) - position++; - } - return unusedTokens; - } - std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { - if( !m_floatingArg.get() ) - return tokens; - std::vector unusedTokens; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - if( token.type == Parser::Token::Positional ) - m_floatingArg->boundField.set( config, token.data ); - else - unusedTokens.push_back( token ); - } - return unusedTokens; - } - - void validate() const - { - if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) - throw std::logic_error( "No options or arguments specified" ); - - for( typename std::vector::const_iterator it = m_options.begin(), - itEnd = m_options.end(); - it != itEnd; ++it ) - it->validate(); - } - - private: - Detail::BoundArgFunction m_boundProcessName; - std::vector m_options; - std::map m_positionalArgs; - ArgAutoPtr m_floatingArg; - int m_highestSpecifiedArgPosition; - bool m_throwOnUnrecognisedTokens; - }; - -} // end namespace Clara - -STITCH_CLARA_CLOSE_NAMESPACE -#undef STITCH_CLARA_OPEN_NAMESPACE -#undef STITCH_CLARA_CLOSE_NAMESPACE - -#endif // TWOBLUECUBES_CLARA_H_INCLUDED -#undef STITCH_CLARA_OPEN_NAMESPACE - -// Restore Clara's value for console width, if present -#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#endif - -#include - -namespace Catch { - - inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } - inline void abortAfterX( ConfigData& config, int x ) { - if( x < 1 ) - throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); - config.abortAfter = x; - } - inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } - - inline void addWarning( ConfigData& config, std::string const& _warning ) { - if( _warning == "NoAssertions" ) - config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); - else - throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" ); - } - inline void setOrder( ConfigData& config, std::string const& order ) { - if( startsWith( "declared", order ) ) - config.runOrder = RunTests::InDeclarationOrder; - else if( startsWith( "lexical", order ) ) - config.runOrder = RunTests::InLexicographicalOrder; - else if( startsWith( "random", order ) ) - config.runOrder = RunTests::InRandomOrder; - else - throw std::runtime_error( "Unrecognised ordering: '" + order + "'" ); - } - inline void setRngSeed( ConfigData& config, std::string const& seed ) { - if( seed == "time" ) { - config.rngSeed = static_cast( std::time(0) ); - } - else { - std::stringstream ss; - ss << seed; - ss >> config.rngSeed; - if( ss.fail() ) - throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" ); - } - } - inline void setVerbosity( ConfigData& config, int level ) { - // !TBD: accept strings? - config.verbosity = static_cast( level ); - } - inline void setShowDurations( ConfigData& config, bool _showDurations ) { - config.showDurations = _showDurations - ? ShowDurations::Always - : ShowDurations::Never; - } - inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { - std::ifstream f( _filename.c_str() ); - if( !f.is_open() ) - throw std::domain_error( "Unable to load input file: " + _filename ); - - std::string line; - while( std::getline( f, line ) ) { - line = trim(line); - if( !line.empty() && !startsWith( line, "#" ) ) - addTestOrTags( config, "\"" + line + "\"," ); - } - } - - inline Clara::CommandLine makeCommandLineParser() { - - using namespace Clara; - CommandLine cli; - - cli.bindProcessName( &ConfigData::processName ); - - cli["-?"]["-h"]["--help"] - .describe( "display usage information" ) - .bind( &ConfigData::showHelp ); - - cli["-l"]["--list-tests"] - .describe( "list all/matching test cases" ) - .bind( &ConfigData::listTests ); - - cli["-t"]["--list-tags"] - .describe( "list all/matching tags" ) - .bind( &ConfigData::listTags ); - - cli["-s"]["--success"] - .describe( "include successful tests in output" ) - .bind( &ConfigData::showSuccessfulTests ); - - cli["-b"]["--break"] - .describe( "break into debugger on failure" ) - .bind( &ConfigData::shouldDebugBreak ); - - cli["-e"]["--nothrow"] - .describe( "skip exception tests" ) - .bind( &ConfigData::noThrow ); - - cli["-i"]["--invisibles"] - .describe( "show invisibles (tabs, newlines)" ) - .bind( &ConfigData::showInvisibles ); - - cli["-o"]["--out"] - .describe( "output filename" ) - .bind( &ConfigData::outputFilename, "filename" ); - - cli["-r"]["--reporter"] -// .placeholder( "name[:filename]" ) - .describe( "reporter to use (defaults to console)" ) - .bind( &ConfigData::reporterName, "name" ); - - cli["-n"]["--name"] - .describe( "suite name" ) - .bind( &ConfigData::name, "name" ); - - cli["-a"]["--abort"] - .describe( "abort at first failure" ) - .bind( &abortAfterFirst ); - - cli["-x"]["--abortx"] - .describe( "abort after x failures" ) - .bind( &abortAfterX, "no. failures" ); - - cli["-w"]["--warn"] - .describe( "enable warnings" ) - .bind( &addWarning, "warning name" ); - -// - needs updating if reinstated -// cli.into( &setVerbosity ) -// .describe( "level of verbosity (0=no output)" ) -// .shortOpt( "v") -// .longOpt( "verbosity" ) -// .placeholder( "level" ); - - cli[_] - .describe( "which test or tests to use" ) - .bind( &addTestOrTags, "test name, pattern or tags" ); - - cli["-d"]["--durations"] - .describe( "show test durations" ) - .bind( &setShowDurations, "yes/no" ); - - cli["-f"]["--input-file"] - .describe( "load test names to run from a file" ) - .bind( &loadTestNamesFromFile, "filename" ); - - // Less common commands which don't have a short form - cli["--list-test-names-only"] - .describe( "list all/matching test cases names only" ) - .bind( &ConfigData::listTestNamesOnly ); - - cli["--list-reporters"] - .describe( "list all reporters" ) - .bind( &ConfigData::listReporters ); - - cli["--order"] - .describe( "test case order (defaults to decl)" ) - .bind( &setOrder, "decl|lex|rand" ); - - cli["--rng-seed"] - .describe( "set a specific seed for random numbers" ) - .bind( &setRngSeed, "'time'|number" ); - - cli["--force-colour"] - .describe( "force colourised output" ) - .bind( &ConfigData::forceColour ); - - return cli; - } - -} // end namespace Catch - -// #included from: internal/catch_list.hpp -#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED - -// #included from: catch_text.h -#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED - -#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - -#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch -// #included from: ../external/tbc_text_format.h -// Only use header guard if we are not using an outer namespace -#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED -# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -# endif -# else -# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED -# endif -#endif -#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -#include -#include -#include - -// Use optional outer namespace -#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { -#endif - -namespace Tbc { - -#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH - const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - struct TextAttributes { - TextAttributes() - : initialIndent( std::string::npos ), - indent( 0 ), - width( consoleWidth-1 ), - tabChar( '\t' ) - {} - - TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } - TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } - TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } - TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } - - std::size_t initialIndent; // indent of first line, or npos - std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos - std::size_t width; // maximum width of text, including indent. Longer text will wrap - char tabChar; // If this char is seen the indent is changed to current pos - }; - - class Text { - public: - Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) - : attr( _attr ) - { - std::string wrappableChars = " [({.,/|\\-"; - std::size_t indent = _attr.initialIndent != std::string::npos - ? _attr.initialIndent - : _attr.indent; - std::string remainder = _str; - - while( !remainder.empty() ) { - if( lines.size() >= 1000 ) { - lines.push_back( "... message truncated due to excessive size" ); - return; - } - std::size_t tabPos = std::string::npos; - std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); - std::size_t pos = remainder.find_first_of( '\n' ); - if( pos <= width ) { - width = pos; - } - pos = remainder.find_last_of( _attr.tabChar, width ); - if( pos != std::string::npos ) { - tabPos = pos; - if( remainder[width] == '\n' ) - width--; - remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); - } - - if( width == remainder.size() ) { - spliceLine( indent, remainder, width ); - } - else if( remainder[width] == '\n' ) { - spliceLine( indent, remainder, width ); - if( width <= 1 || remainder.size() != 1 ) - remainder = remainder.substr( 1 ); - indent = _attr.indent; - } - else { - pos = remainder.find_last_of( wrappableChars, width ); - if( pos != std::string::npos && pos > 0 ) { - spliceLine( indent, remainder, pos ); - if( remainder[0] == ' ' ) - remainder = remainder.substr( 1 ); - } - else { - spliceLine( indent, remainder, width-1 ); - lines.back() += "-"; - } - if( lines.size() == 1 ) - indent = _attr.indent; - if( tabPos != std::string::npos ) - indent += tabPos; - } - } - } - - void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { - lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); - _remainder = _remainder.substr( _pos ); - } - - typedef std::vector::const_iterator const_iterator; - - const_iterator begin() const { return lines.begin(); } - const_iterator end() const { return lines.end(); } - std::string const& last() const { return lines.back(); } - std::size_t size() const { return lines.size(); } - std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } - std::string toString() const { - std::ostringstream oss; - oss << *this; - return oss.str(); - } - - inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { - for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); - it != itEnd; ++it ) { - if( it != _text.begin() ) - _stream << "\n"; - _stream << *it; - } - return _stream; - } - - private: - std::string str; - TextAttributes attr; - std::vector lines; - }; - -} // end namespace Tbc - -#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -} // end outer namespace -#endif - -#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE - -namespace Catch { - using Tbc::Text; - using Tbc::TextAttributes; -} - -// #included from: catch_console_colour.hpp -#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED - -namespace Catch { - - struct Colour { - enum Code { - None = 0, - - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White, - - // By intention - FileName = LightGrey, - Warning = Yellow, - ResultError = BrightRed, - ResultSuccess = BrightGreen, - ResultExpectedFailure = Warning, - - Error = BrightRed, - Success = Green, - - OriginalExpression = Cyan, - ReconstructedExpression = Yellow, - - SecondaryText = LightGrey, - Headers = White - }; - - // Use constructed object for RAII guard - Colour( Code _colourCode ); - Colour( Colour const& other ); - ~Colour(); - - // Use static method for one-shot changes - static void use( Code _colourCode ); - - private: - bool m_moved; - }; - - inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } - -} // end namespace Catch - -// #included from: catch_interfaces_reporter.h -#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED - -#include -#include -#include -#include - -namespace Catch -{ - struct ReporterConfig { - explicit ReporterConfig( Ptr const& _fullConfig ) - : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} - - ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) - : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} - - std::ostream& stream() const { return *m_stream; } - Ptr fullConfig() const { return m_fullConfig; } - - private: - std::ostream* m_stream; - Ptr m_fullConfig; - }; - - struct ReporterPreferences { - ReporterPreferences() - : shouldRedirectStdOut( false ) - {} - - bool shouldRedirectStdOut; - }; - - template - struct LazyStat : Option { - LazyStat() : used( false ) {} - LazyStat& operator=( T const& _value ) { - Option::operator=( _value ); - used = false; - return *this; - } - void reset() { - Option::reset(); - used = false; - } - bool used; - }; - - struct TestRunInfo { - TestRunInfo( std::string const& _name ) : name( _name ) {} - std::string name; - }; - struct GroupInfo { - GroupInfo( std::string const& _name, - std::size_t _groupIndex, - std::size_t _groupsCount ) - : name( _name ), - groupIndex( _groupIndex ), - groupsCounts( _groupsCount ) - {} - - std::string name; - std::size_t groupIndex; - std::size_t groupsCounts; - }; - - struct AssertionStats { - AssertionStats( AssertionResult const& _assertionResult, - std::vector const& _infoMessages, - Totals const& _totals ) - : assertionResult( _assertionResult ), - infoMessages( _infoMessages ), - totals( _totals ) - { - if( assertionResult.hasMessage() ) { - // Copy message into messages list. - // !TBD This should have been done earlier, somewhere - MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); - builder << assertionResult.getMessage(); - builder.m_info.message = builder.m_stream.str(); - - infoMessages.push_back( builder.m_info ); - } - } - virtual ~AssertionStats(); - -# ifdef CATCH_CPP11_OR_GREATER - AssertionStats( AssertionStats const& ) = default; - AssertionStats( AssertionStats && ) = default; - AssertionStats& operator = ( AssertionStats const& ) = default; - AssertionStats& operator = ( AssertionStats && ) = default; -# endif - - AssertionResult assertionResult; - std::vector infoMessages; - Totals totals; - }; - - struct SectionStats { - SectionStats( SectionInfo const& _sectionInfo, - Counts const& _assertions, - double _durationInSeconds, - bool _missingAssertions ) - : sectionInfo( _sectionInfo ), - assertions( _assertions ), - durationInSeconds( _durationInSeconds ), - missingAssertions( _missingAssertions ) - {} - virtual ~SectionStats(); -# ifdef CATCH_CPP11_OR_GREATER - SectionStats( SectionStats const& ) = default; - SectionStats( SectionStats && ) = default; - SectionStats& operator = ( SectionStats const& ) = default; - SectionStats& operator = ( SectionStats && ) = default; -# endif - - SectionInfo sectionInfo; - Counts assertions; - double durationInSeconds; - bool missingAssertions; - }; - - struct TestCaseStats { - TestCaseStats( TestCaseInfo const& _testInfo, - Totals const& _totals, - std::string const& _stdOut, - std::string const& _stdErr, - bool _aborting ) - : testInfo( _testInfo ), - totals( _totals ), - stdOut( _stdOut ), - stdErr( _stdErr ), - aborting( _aborting ) - {} - virtual ~TestCaseStats(); - -# ifdef CATCH_CPP11_OR_GREATER - TestCaseStats( TestCaseStats const& ) = default; - TestCaseStats( TestCaseStats && ) = default; - TestCaseStats& operator = ( TestCaseStats const& ) = default; - TestCaseStats& operator = ( TestCaseStats && ) = default; -# endif - - TestCaseInfo testInfo; - Totals totals; - std::string stdOut; - std::string stdErr; - bool aborting; - }; - - struct TestGroupStats { - TestGroupStats( GroupInfo const& _groupInfo, - Totals const& _totals, - bool _aborting ) - : groupInfo( _groupInfo ), - totals( _totals ), - aborting( _aborting ) - {} - TestGroupStats( GroupInfo const& _groupInfo ) - : groupInfo( _groupInfo ), - aborting( false ) - {} - virtual ~TestGroupStats(); - -# ifdef CATCH_CPP11_OR_GREATER - TestGroupStats( TestGroupStats const& ) = default; - TestGroupStats( TestGroupStats && ) = default; - TestGroupStats& operator = ( TestGroupStats const& ) = default; - TestGroupStats& operator = ( TestGroupStats && ) = default; -# endif - - GroupInfo groupInfo; - Totals totals; - bool aborting; - }; - - struct TestRunStats { - TestRunStats( TestRunInfo const& _runInfo, - Totals const& _totals, - bool _aborting ) - : runInfo( _runInfo ), - totals( _totals ), - aborting( _aborting ) - {} - virtual ~TestRunStats(); - -# ifndef CATCH_CPP11_OR_GREATER - TestRunStats( TestRunStats const& _other ) - : runInfo( _other.runInfo ), - totals( _other.totals ), - aborting( _other.aborting ) - {} -# else - TestRunStats( TestRunStats const& ) = default; - TestRunStats( TestRunStats && ) = default; - TestRunStats& operator = ( TestRunStats const& ) = default; - TestRunStats& operator = ( TestRunStats && ) = default; -# endif - - TestRunInfo runInfo; - Totals totals; - bool aborting; - }; - - struct IStreamingReporter : IShared { - virtual ~IStreamingReporter(); - - // Implementing class must also provide the following static method: - // static std::string getDescription(); - - virtual ReporterPreferences getPreferences() const = 0; - - virtual void noMatchingTestCases( std::string const& spec ) = 0; - - virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; - virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; - virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; - - virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; - - // The return value indicates if the messages buffer should be cleared: - virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; - virtual void sectionEnded( SectionStats const& sectionStats ) = 0; - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; - virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; - - virtual void skipTest( TestCaseInfo const& testInfo ) = 0; - }; - - struct IReporterFactory { - virtual ~IReporterFactory(); - virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; - virtual std::string getDescription() const = 0; - }; - - struct IReporterRegistry { - typedef std::map FactoryMap; - - virtual ~IReporterRegistry(); - virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; - virtual FactoryMap const& getFactories() const = 0; - }; - -} - -#include -#include - -namespace Catch { - - inline std::size_t listTests( Config const& config ) { - - TestSpec testSpec = config.testSpec(); - if( config.testSpec().hasFilters() ) - Catch::cout() << "Matching test cases:\n"; - else { - Catch::cout() << "All available test cases:\n"; - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - } - - std::size_t matchedTests = 0; - TextAttributes nameAttr, tagsAttr; - nameAttr.setInitialIndent( 2 ).setIndent( 4 ); - tagsAttr.setIndent( 6 ); - - std::vector matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); - for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - matchedTests++; - TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - Colour::Code colour = testCaseInfo.isHidden() - ? Colour::SecondaryText - : Colour::None; - Colour colourGuard( colour ); - - Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; - if( !testCaseInfo.tags.empty() ) - Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; - } - - if( !config.testSpec().hasFilters() ) - Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl; - else - Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl; - return matchedTests; - } - - inline std::size_t listTestsNamesOnly( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( !config.testSpec().hasFilters() ) - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - std::size_t matchedTests = 0; - std::vector matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); - for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - matchedTests++; - TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - Catch::cout() << testCaseInfo.name << std::endl; - } - return matchedTests; - } - - struct TagInfo { - TagInfo() : count ( 0 ) {} - void add( std::string const& spelling ) { - ++count; - spellings.insert( spelling ); - } - std::string all() const { - std::string out; - for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); - it != itEnd; - ++it ) - out += "[" + *it + "]"; - return out; - } - std::set spellings; - std::size_t count; - }; - - inline std::size_t listTags( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( config.testSpec().hasFilters() ) - Catch::cout() << "Tags for matching test cases:\n"; - else { - Catch::cout() << "All available tags:\n"; - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - } - - std::map tagCounts; - - std::vector matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); - for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), - tagItEnd = it->getTestCaseInfo().tags.end(); - tagIt != tagItEnd; - ++tagIt ) { - std::string tagName = *tagIt; - std::string lcaseTagName = toLower( tagName ); - std::map::iterator countIt = tagCounts.find( lcaseTagName ); - if( countIt == tagCounts.end() ) - countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; - countIt->second.add( tagName ); - } - } - - for( std::map::const_iterator countIt = tagCounts.begin(), - countItEnd = tagCounts.end(); - countIt != countItEnd; - ++countIt ) { - std::ostringstream oss; - oss << " " << std::setw(2) << countIt->second.count << " "; - Text wrapper( countIt->second.all(), TextAttributes() - .setInitialIndent( 0 ) - .setIndent( oss.str().size() ) - .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); - Catch::cout() << oss.str() << wrapper << "\n"; - } - Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl; - return tagCounts.size(); - } - - inline std::size_t listReporters( Config const& /*config*/ ) { - Catch::cout() << "Available reporters:\n"; - IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); - IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; - std::size_t maxNameLen = 0; - for(it = itBegin; it != itEnd; ++it ) - maxNameLen = (std::max)( maxNameLen, it->first.size() ); - - for(it = itBegin; it != itEnd; ++it ) { - Text wrapper( it->second->getDescription(), TextAttributes() - .setInitialIndent( 0 ) - .setIndent( 7+maxNameLen ) - .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); - Catch::cout() << " " - << it->first - << ":" - << std::string( maxNameLen - it->first.size() + 2, ' ' ) - << wrapper << "\n"; - } - Catch::cout() << std::endl; - return factories.size(); - } - - inline Option list( Config const& config ) { - Option listedCount; - if( config.listTests() ) - listedCount = listedCount.valueOr(0) + listTests( config ); - if( config.listTestNamesOnly() ) - listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); - if( config.listTags() ) - listedCount = listedCount.valueOr(0) + listTags( config ); - if( config.listReporters() ) - listedCount = listedCount.valueOr(0) + listReporters( config ); - return listedCount; - } - -} // end namespace Catch - -// #included from: internal/catch_runner_impl.hpp -#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED - -// #included from: catch_test_case_tracker.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED - -#include -#include -#include - -namespace Catch { -namespace SectionTracking { - - class TrackedSection { - - typedef std::map TrackedSections; - - public: - enum RunState { - NotStarted, - Executing, - ExecutingChildren, - Completed - }; - - TrackedSection( std::string const& name, TrackedSection* parent ) - : m_name( name ), m_runState( NotStarted ), m_parent( parent ) - {} - - RunState runState() const { return m_runState; } - - TrackedSection* findChild( std::string const& childName ) { - TrackedSections::iterator it = m_children.find( childName ); - return it != m_children.end() - ? &it->second - : NULL; - } - TrackedSection* acquireChild( std::string const& childName ) { - if( TrackedSection* child = findChild( childName ) ) - return child; - m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) ); - return findChild( childName ); - } - void enter() { - if( m_runState == NotStarted ) - m_runState = Executing; - } - void leave() { - for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end(); - it != itEnd; - ++it ) - if( it->second.runState() != Completed ) { - m_runState = ExecutingChildren; - return; - } - m_runState = Completed; - } - TrackedSection* getParent() { - return m_parent; - } - bool hasChildren() const { - return !m_children.empty(); - } - - private: - std::string m_name; - RunState m_runState; - TrackedSections m_children; - TrackedSection* m_parent; - - }; - - class TestCaseTracker { - public: - TestCaseTracker( std::string const& testCaseName ) - : m_testCase( testCaseName, NULL ), - m_currentSection( &m_testCase ), - m_completedASectionThisRun( false ) - {} - - bool enterSection( std::string const& name ) { - TrackedSection* child = m_currentSection->acquireChild( name ); - if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed ) - return false; - - m_currentSection = child; - m_currentSection->enter(); - return true; - } - void leaveSection() { - m_currentSection->leave(); - m_currentSection = m_currentSection->getParent(); - assert( m_currentSection != NULL ); - m_completedASectionThisRun = true; - } - - bool currentSectionHasChildren() const { - return m_currentSection->hasChildren(); - } - bool isCompleted() const { - return m_testCase.runState() == TrackedSection::Completed; - } - - class Guard { - public: - Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) { - m_tracker.enterTestCase(); - } - ~Guard() { - m_tracker.leaveTestCase(); - } - private: - Guard( Guard const& ); - void operator = ( Guard const& ); - TestCaseTracker& m_tracker; - }; - - private: - void enterTestCase() { - m_currentSection = &m_testCase; - m_completedASectionThisRun = false; - m_testCase.enter(); - } - void leaveTestCase() { - m_testCase.leave(); - } - - TrackedSection m_testCase; - TrackedSection* m_currentSection; - bool m_completedASectionThisRun; - }; - -} // namespace SectionTracking - -using SectionTracking::TestCaseTracker; - -} // namespace Catch - -// #included from: catch_fatal_condition.hpp -#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED - -namespace Catch { - - // Report the error condition then exit the process - inline void fatal( std::string const& message, int exitCode ) { - IContext& context = Catch::getCurrentContext(); - IResultCapture* resultCapture = context.getResultCapture(); - resultCapture->handleFatalErrorCondition( message ); - - if( Catch::alwaysTrue() ) // avoids "no return" warnings - exit( exitCode ); - } - -} // namespace Catch - -#if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// - -namespace Catch { - - struct FatalConditionHandler { - void reset() {} - }; - -} // namespace Catch - -#else // Not Windows - assumed to be POSIX compatible ////////////////////////// - -#include - -namespace Catch { - - struct SignalDefs { int id; const char* name; }; - extern SignalDefs signalDefs[]; - SignalDefs signalDefs[] = { - { SIGINT, "SIGINT - Terminal interrupt signal" }, - { SIGILL, "SIGILL - Illegal instruction signal" }, - { SIGFPE, "SIGFPE - Floating point error signal" }, - { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, - { SIGTERM, "SIGTERM - Termination request signal" }, - { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } - }; - - struct FatalConditionHandler { - - static void handleSignal( int sig ) { - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) - if( sig == signalDefs[i].id ) - fatal( signalDefs[i].name, -sig ); - fatal( "", -sig ); - } - - FatalConditionHandler() : m_isSet( true ) { - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) - signal( signalDefs[i].id, handleSignal ); - } - ~FatalConditionHandler() { - reset(); - } - void reset() { - if( m_isSet ) { - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) - signal( signalDefs[i].id, SIG_DFL ); - m_isSet = false; - } - } - - bool m_isSet; - }; - -} // namespace Catch - -#endif // not Windows - -#include -#include - -namespace Catch { - - class StreamRedirect { - - public: - StreamRedirect( std::ostream& stream, std::string& targetString ) - : m_stream( stream ), - m_prevBuf( stream.rdbuf() ), - m_targetString( targetString ) - { - stream.rdbuf( m_oss.rdbuf() ); - } - - ~StreamRedirect() { - m_targetString += m_oss.str(); - m_stream.rdbuf( m_prevBuf ); - } - - private: - std::ostream& m_stream; - std::streambuf* m_prevBuf; - std::ostringstream m_oss; - std::string& m_targetString; - }; - - /////////////////////////////////////////////////////////////////////////// - - class RunContext : public IResultCapture, public IRunner { - - RunContext( RunContext const& ); - void operator =( RunContext const& ); - - public: - - explicit RunContext( Ptr const& config, Ptr const& reporter ) - : m_runInfo( config->name() ), - m_context( getCurrentMutableContext() ), - m_activeTestCase( NULL ), - m_config( config ), - m_reporter( reporter ), - m_prevRunner( m_context.getRunner() ), - m_prevResultCapture( m_context.getResultCapture() ), - m_prevConfig( m_context.getConfig() ) - { - m_context.setRunner( this ); - m_context.setConfig( m_config ); - m_context.setResultCapture( this ); - m_reporter->testRunStarting( m_runInfo ); - } - - virtual ~RunContext() { - m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); - m_context.setRunner( m_prevRunner ); - m_context.setConfig( NULL ); - m_context.setResultCapture( m_prevResultCapture ); - m_context.setConfig( m_prevConfig ); - } - - void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { - m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); - } - void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { - m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); - } - - Totals runTest( TestCase const& testCase ) { - Totals prevTotals = m_totals; - - std::string redirectedCout; - std::string redirectedCerr; - - TestCaseInfo testInfo = testCase.getTestCaseInfo(); - - m_reporter->testCaseStarting( testInfo ); - - m_activeTestCase = &testCase; - m_testCaseTracker = TestCaseTracker( testInfo.name ); - - do { - do { - runCurrentTest( redirectedCout, redirectedCerr ); - } - while( !m_testCaseTracker->isCompleted() && !aborting() ); - } - while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); - - Totals deltaTotals = m_totals.delta( prevTotals ); - m_totals.testCases += deltaTotals.testCases; - m_reporter->testCaseEnded( TestCaseStats( testInfo, - deltaTotals, - redirectedCout, - redirectedCerr, - aborting() ) ); - - m_activeTestCase = NULL; - m_testCaseTracker.reset(); - - return deltaTotals; - } - - Ptr config() const { - return m_config; - } - - private: // IResultCapture - - virtual void assertionEnded( AssertionResult const& result ) { - if( result.getResultType() == ResultWas::Ok ) { - m_totals.assertions.passed++; - } - else if( !result.isOk() ) { - m_totals.assertions.failed++; - } - - if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) - m_messages.clear(); - - // Reset working state - m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); - m_lastResult = result; - } - - virtual bool sectionStarted ( - SectionInfo const& sectionInfo, - Counts& assertions - ) - { - std::ostringstream oss; - oss << sectionInfo.name << "@" << sectionInfo.lineInfo; - - if( !m_testCaseTracker->enterSection( oss.str() ) ) - return false; - - m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; - - m_reporter->sectionStarting( sectionInfo ); - - assertions = m_totals.assertions; - - return true; - } - bool testForMissingAssertions( Counts& assertions ) { - if( assertions.total() != 0 || - !m_config->warnAboutMissingAssertions() || - m_testCaseTracker->currentSectionHasChildren() ) - return false; - m_totals.assertions.failed++; - assertions.failed++; - return true; - } - - virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) { - if( std::uncaught_exception() ) { - m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) ); - return; - } - - Counts assertions = m_totals.assertions - prevAssertions; - bool missingAssertions = testForMissingAssertions( assertions ); - - m_testCaseTracker->leaveSection(); - - m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) ); - m_messages.clear(); - } - - virtual void pushScopedMessage( MessageInfo const& message ) { - m_messages.push_back( message ); - } - - virtual void popScopedMessage( MessageInfo const& message ) { - m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); - } - - virtual std::string getCurrentTestName() const { - return m_activeTestCase - ? m_activeTestCase->getTestCaseInfo().name - : ""; - } - - virtual const AssertionResult* getLastResult() const { - return &m_lastResult; - } - - virtual void handleFatalErrorCondition( std::string const& message ) { - ResultBuilder resultBuilder = makeUnexpectedResultBuilder(); - resultBuilder.setResultType( ResultWas::FatalErrorCondition ); - resultBuilder << message; - resultBuilder.captureExpression(); - - handleUnfinishedSections(); - - // Recreate section for test case (as we will lose the one that was in scope) - TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); - - Counts assertions; - assertions.failed = 1; - SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); - m_reporter->sectionEnded( testCaseSectionStats ); - - TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); - - Totals deltaTotals; - deltaTotals.testCases.failed = 1; - m_reporter->testCaseEnded( TestCaseStats( testInfo, - deltaTotals, - "", - "", - false ) ); - m_totals.testCases.failed++; - testGroupEnded( "", m_totals, 1, 1 ); - m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); - } - - public: - // !TBD We need to do this another way! - bool aborting() const { - return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); - } - - private: - - void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { - TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); - m_reporter->sectionStarting( testCaseSection ); - Counts prevAssertions = m_totals.assertions; - double duration = 0; - try { - m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); - TestCaseTracker::Guard guard( *m_testCaseTracker ); - - Timer timer; - timer.start(); - if( m_reporter->getPreferences().shouldRedirectStdOut ) { - StreamRedirect coutRedir( Catch::cout(), redirectedCout ); - StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); - invokeActiveTestCase(); - } - else { - invokeActiveTestCase(); - } - duration = timer.getElapsedSeconds(); - } - catch( TestFailureException& ) { - // This just means the test was aborted due to failure - } - catch(...) { - makeUnexpectedResultBuilder().useActiveException(); - } - handleUnfinishedSections(); - m_messages.clear(); - - Counts assertions = m_totals.assertions - prevAssertions; - bool missingAssertions = testForMissingAssertions( assertions ); - - if( testCaseInfo.okToFail() ) { - std::swap( assertions.failedButOk, assertions.failed ); - m_totals.assertions.failed -= assertions.failedButOk; - m_totals.assertions.failedButOk += assertions.failedButOk; - } - - SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); - m_reporter->sectionEnded( testCaseSectionStats ); - } - - void invokeActiveTestCase() { - FatalConditionHandler fatalConditionHandler; // Handle signals - m_activeTestCase->invoke(); - fatalConditionHandler.reset(); - } - - private: - - ResultBuilder makeUnexpectedResultBuilder() const { - return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), - m_lastAssertionInfo.lineInfo, - m_lastAssertionInfo.capturedExpression.c_str(), - m_lastAssertionInfo.resultDisposition ); - } - - void handleUnfinishedSections() { - // If sections ended prematurely due to an exception we stored their - // infos here so we can tear them down outside the unwind process. - for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), - itEnd = m_unfinishedSections.rend(); - it != itEnd; - ++it ) - sectionEnded( it->info, it->prevAssertions, it->durationInSeconds ); - m_unfinishedSections.clear(); - } - - struct UnfinishedSections { - UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds ) - : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) - {} - - SectionInfo info; - Counts prevAssertions; - double durationInSeconds; - }; - - TestRunInfo m_runInfo; - IMutableContext& m_context; - TestCase const* m_activeTestCase; - Option m_testCaseTracker; - AssertionResult m_lastResult; - - Ptr m_config; - Totals m_totals; - Ptr m_reporter; - std::vector m_messages; - IRunner* m_prevRunner; - IResultCapture* m_prevResultCapture; - Ptr m_prevConfig; - AssertionInfo m_lastAssertionInfo; - std::vector m_unfinishedSections; - }; - - IResultCapture& getResultCapture() { - if( IResultCapture* capture = getCurrentContext().getResultCapture() ) - return *capture; - else - throw std::logic_error( "No result capture instance" ); - } - -} // end namespace Catch - -// #included from: internal/catch_version.h -#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED - -namespace Catch { - - // Versioning information - struct Version { - Version( unsigned int _majorVersion, - unsigned int _minorVersion, - unsigned int _buildNumber, - char const* const _branchName ) - : majorVersion( _majorVersion ), - minorVersion( _minorVersion ), - buildNumber( _buildNumber ), - branchName( _branchName ) - {} - - unsigned int const majorVersion; - unsigned int const minorVersion; - unsigned int const buildNumber; - char const* const branchName; - - private: - void operator=( Version const& ); - }; - - extern Version libraryVersion; -} - -#include -#include -#include - -namespace Catch { - - class Runner { - - public: - Runner( Ptr const& config ) - : m_config( config ) - { - openStream(); - makeReporter(); - } - - Totals runTests() { - - RunContext context( m_config.get(), m_reporter ); - - Totals totals; - - context.testGroupStarting( "all tests", 1, 1 ); // deprecated? - - TestSpec testSpec = m_config->testSpec(); - if( !testSpec.hasFilters() ) - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests - - std::vector testCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases ); - - int testsRunForGroup = 0; - for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); - it != itEnd; - ++it ) { - testsRunForGroup++; - if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) { - - if( context.aborting() ) - break; - - totals += context.runTest( *it ); - m_testsAlreadyRun.insert( *it ); - } - } - std::vector skippedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true ); - - for( std::vector::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end(); - it != itEnd; - ++it ) - m_reporter->skipTest( *it ); - - context.testGroupEnded( "all tests", totals, 1, 1 ); - return totals; - } - - private: - void openStream() { - // Open output file, if specified - if( !m_config->getFilename().empty() ) { - m_ofs.open( m_config->getFilename().c_str() ); - if( m_ofs.fail() ) { - std::ostringstream oss; - oss << "Unable to open file: '" << m_config->getFilename() << "'"; - throw std::domain_error( oss.str() ); - } - m_config->setStreamBuf( m_ofs.rdbuf() ); - } - } - void makeReporter() { - std::string reporterName = m_config->getReporterName().empty() - ? "console" - : m_config->getReporterName(); - - m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() ); - if( !m_reporter ) { - std::ostringstream oss; - oss << "No reporter registered with name: '" << reporterName << "'"; - throw std::domain_error( oss.str() ); - } - } - - private: - Ptr m_config; - std::ofstream m_ofs; - Ptr m_reporter; - std::set m_testsAlreadyRun; - }; - - class Session : NonCopyable { - static bool alreadyInstantiated; - - public: - - struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; - - Session() - : m_cli( makeCommandLineParser() ) { - if( alreadyInstantiated ) { - std::string msg = "Only one instance of Catch::Session can ever be used"; - Catch::cerr() << msg << std::endl; - throw std::logic_error( msg ); - } - alreadyInstantiated = true; - } - ~Session() { - Catch::cleanUp(); - } - - void showHelp( std::string const& processName ) { - Catch::cout() << "\nCatch v" << libraryVersion.majorVersion << "." - << libraryVersion.minorVersion << " build " - << libraryVersion.buildNumber; - if( libraryVersion.branchName != std::string( "master" ) ) - Catch::cout() << " (" << libraryVersion.branchName << " branch)"; - Catch::cout() << "\n"; - - m_cli.usage( Catch::cout(), processName ); - Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; - } - - int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { - try { - m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); - m_unusedTokens = m_cli.parseInto( argc, argv, m_configData ); - if( m_configData.showHelp ) - showHelp( m_configData.processName ); - m_config.reset(); - } - catch( std::exception& ex ) { - { - Colour colourGuard( Colour::Red ); - Catch::cerr() << "\nError(s) in input:\n" - << Text( ex.what(), TextAttributes().setIndent(2) ) - << "\n\n"; - } - m_cli.usage( Catch::cout(), m_configData.processName ); - return (std::numeric_limits::max)(); - } - return 0; - } - - void useConfigData( ConfigData const& _configData ) { - m_configData = _configData; - m_config.reset(); - } - - int run( int argc, char* const argv[] ) { - - int returnCode = applyCommandLine( argc, argv ); - if( returnCode == 0 ) - returnCode = run(); - return returnCode; - } - - int run() { - if( m_configData.showHelp ) - return 0; - - try - { - config(); // Force config to be constructed - - std::srand( m_configData.rngSeed ); - - Runner runner( m_config ); - - // Handle list request - if( Option listed = list( config() ) ) - return static_cast( *listed ); - - return static_cast( runner.runTests().assertions.failed ); - } - catch( std::exception& ex ) { - Catch::cerr() << ex.what() << std::endl; - return (std::numeric_limits::max)(); - } - } - - Clara::CommandLine const& cli() const { - return m_cli; - } - std::vector const& unusedTokens() const { - return m_unusedTokens; - } - ConfigData& configData() { - return m_configData; - } - Config& config() { - if( !m_config ) - m_config = new Config( m_configData ); - return *m_config; - } - - private: - Clara::CommandLine m_cli; - std::vector m_unusedTokens; - ConfigData m_configData; - Ptr m_config; - }; - - bool Session::alreadyInstantiated = false; - -} // end namespace Catch - -// #included from: catch_registry_hub.hpp -#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED - -// #included from: catch_test_case_registry_impl.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED - -#include -#include -#include -#include -#include - -namespace Catch { - - class TestRegistry : public ITestCaseRegistry { - struct LexSort { - bool operator() (TestCase i,TestCase j) const { return (i const& getAllTests() const { - return m_functionsInOrder; - } - - virtual std::vector const& getAllNonHiddenTests() const { - return m_nonHiddenFunctions; - } - - virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector& matchingTestCases, bool negated = false ) const { - - for( std::vector::const_iterator it = m_functionsInOrder.begin(), - itEnd = m_functionsInOrder.end(); - it != itEnd; - ++it ) { - bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() ); - if( includeTest != negated ) - matchingTestCases.push_back( *it ); - } - sortTests( config, matchingTestCases ); - } - - private: - - static void sortTests( IConfig const& config, std::vector& matchingTestCases ) { - - switch( config.runOrder() ) { - case RunTests::InLexicographicalOrder: - std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() ); - break; - case RunTests::InRandomOrder: - { - RandomNumberGenerator rng; - std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng ); - } - break; - case RunTests::InDeclarationOrder: - // already in declaration order - break; - } - } - std::set m_functions; - std::vector m_functionsInOrder; - std::vector m_nonHiddenFunctions; - size_t m_unnamedCount; - }; - - /////////////////////////////////////////////////////////////////////////// - - class FreeFunctionTestCase : public SharedImpl { - public: - - FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} - - virtual void invoke() const { - m_fun(); - } - - private: - virtual ~FreeFunctionTestCase(); - - TestFunction m_fun; - }; - - inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { - std::string className = classOrQualifiedMethodName; - if( startsWith( className, "&" ) ) - { - std::size_t lastColons = className.rfind( "::" ); - std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); - if( penultimateColons == std::string::npos ) - penultimateColons = 1; - className = className.substr( penultimateColons, lastColons-penultimateColons ); - } - return className; - } - - /////////////////////////////////////////////////////////////////////////// - - AutoReg::AutoReg( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ) { - registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); - } - - AutoReg::~AutoReg() {} - - void AutoReg::registerTestCase( ITestCase* testCase, - char const* classOrQualifiedMethodName, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ) { - - getMutableRegistryHub().registerTest - ( makeTestCase( testCase, - extractClassName( classOrQualifiedMethodName ), - nameAndDesc.name, - nameAndDesc.description, - lineInfo ) ); - } - -} // end namespace Catch - -// #included from: catch_reporter_registry.hpp -#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED - -#include - -namespace Catch { - - class ReporterRegistry : public IReporterRegistry { - - public: - - virtual ~ReporterRegistry() { - deleteAllValues( m_factories ); - } - - virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const { - FactoryMap::const_iterator it = m_factories.find( name ); - if( it == m_factories.end() ) - return NULL; - return it->second->create( ReporterConfig( config ) ); - } - - void registerReporter( std::string const& name, IReporterFactory* factory ) { - m_factories.insert( std::make_pair( name, factory ) ); - } - - FactoryMap const& getFactories() const { - return m_factories; - } - - private: - FactoryMap m_factories; - }; -} - -// #included from: catch_exception_translator_registry.hpp -#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED - -#ifdef __OBJC__ -#import "Foundation/Foundation.h" -#endif - -namespace Catch { - - class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { - public: - ~ExceptionTranslatorRegistry() { - deleteAll( m_translators ); - } - - virtual void registerTranslator( const IExceptionTranslator* translator ) { - m_translators.push_back( translator ); - } - - virtual std::string translateActiveException() const { - try { -#ifdef __OBJC__ - // In Objective-C try objective-c exceptions first - @try { - throw; - } - @catch (NSException *exception) { - return Catch::toString( [exception description] ); - } -#else - throw; -#endif - } - catch( TestFailureException& ) { - throw; - } - catch( std::exception& ex ) { - return ex.what(); - } - catch( std::string& msg ) { - return msg; - } - catch( const char* msg ) { - return msg; - } - catch(...) { - return tryTranslators( m_translators.begin() ); - } - } - - std::string tryTranslators( std::vector::const_iterator it ) const { - if( it == m_translators.end() ) - return "Unknown exception"; - - try { - return (*it)->translate(); - } - catch(...) { - return tryTranslators( it+1 ); - } - } - - private: - std::vector m_translators; - }; -} - -namespace Catch { - - namespace { - - class RegistryHub : public IRegistryHub, public IMutableRegistryHub { - - RegistryHub( RegistryHub const& ); - void operator=( RegistryHub const& ); - - public: // IRegistryHub - RegistryHub() { - } - virtual IReporterRegistry const& getReporterRegistry() const { - return m_reporterRegistry; - } - virtual ITestCaseRegistry const& getTestCaseRegistry() const { - return m_testCaseRegistry; - } - virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() { - return m_exceptionTranslatorRegistry; - } - - public: // IMutableRegistryHub - virtual void registerReporter( std::string const& name, IReporterFactory* factory ) { - m_reporterRegistry.registerReporter( name, factory ); - } - virtual void registerTest( TestCase const& testInfo ) { - m_testCaseRegistry.registerTest( testInfo ); - } - virtual void registerTranslator( const IExceptionTranslator* translator ) { - m_exceptionTranslatorRegistry.registerTranslator( translator ); - } - - private: - TestRegistry m_testCaseRegistry; - ReporterRegistry m_reporterRegistry; - ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; - }; - - // Single, global, instance - inline RegistryHub*& getTheRegistryHub() { - static RegistryHub* theRegistryHub = NULL; - if( !theRegistryHub ) - theRegistryHub = new RegistryHub(); - return theRegistryHub; - } - } - - IRegistryHub& getRegistryHub() { - return *getTheRegistryHub(); - } - IMutableRegistryHub& getMutableRegistryHub() { - return *getTheRegistryHub(); - } - void cleanUp() { - delete getTheRegistryHub(); - getTheRegistryHub() = NULL; - cleanUpContext(); - } - std::string translateActiveException() { - return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); - } - -} // end namespace Catch - -// #included from: catch_notimplemented_exception.hpp -#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED - -#include - -namespace Catch { - - NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) - : m_lineInfo( lineInfo ) { - std::ostringstream oss; - oss << lineInfo << ": function "; - oss << "not implemented"; - m_what = oss.str(); - } - - const char* NotImplementedException::what() const CATCH_NOEXCEPT { - return m_what.c_str(); - } - -} // end namespace Catch - -// #included from: catch_context_impl.hpp -#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED - -// #included from: catch_stream.hpp -#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED - -// #included from: catch_streambuf.h -#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED - -#include - -namespace Catch { - - class StreamBufBase : public std::streambuf { - public: - virtual ~StreamBufBase() CATCH_NOEXCEPT; - }; -} - -#include -#include -#include - -namespace Catch { - - template - class StreamBufImpl : public StreamBufBase { - char data[bufferSize]; - WriterF m_writer; - - public: - StreamBufImpl() { - setp( data, data + sizeof(data) ); - } - - ~StreamBufImpl() CATCH_NOEXCEPT { - sync(); - } - - private: - int overflow( int c ) { - sync(); - - if( c != EOF ) { - if( pbase() == epptr() ) - m_writer( std::string( 1, static_cast( c ) ) ); - else - sputc( static_cast( c ) ); - } - return 0; - } - - int sync() { - if( pbase() != pptr() ) { - m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); - setp( pbase(), epptr() ); - } - return 0; - } - }; - - /////////////////////////////////////////////////////////////////////////// - - struct OutputDebugWriter { - - void operator()( std::string const&str ) { - writeToDebugConsole( str ); - } - }; - - Stream::Stream() - : streamBuf( NULL ), isOwned( false ) - {} - - Stream::Stream( std::streambuf* _streamBuf, bool _isOwned ) - : streamBuf( _streamBuf ), isOwned( _isOwned ) - {} - - void Stream::release() { - if( isOwned ) { - delete streamBuf; - streamBuf = NULL; - isOwned = false; - } - } - -#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions - std::ostream& cout() { - return std::cout; - } - std::ostream& cerr() { - return std::cerr; - } -#endif -} - -namespace Catch { - - class Context : public IMutableContext { - - Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {} - Context( Context const& ); - void operator=( Context const& ); - - public: // IContext - virtual IResultCapture* getResultCapture() { - return m_resultCapture; - } - virtual IRunner* getRunner() { - return m_runner; - } - virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { - return getGeneratorsForCurrentTest() - .getGeneratorInfo( fileInfo, totalSize ) - .getCurrentIndex(); - } - virtual bool advanceGeneratorsForCurrentTest() { - IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); - return generators && generators->moveNext(); - } - - virtual Ptr getConfig() const { - return m_config; - } - - public: // IMutableContext - virtual void setResultCapture( IResultCapture* resultCapture ) { - m_resultCapture = resultCapture; - } - virtual void setRunner( IRunner* runner ) { - m_runner = runner; - } - virtual void setConfig( Ptr const& config ) { - m_config = config; - } - - friend IMutableContext& getCurrentMutableContext(); - - private: - IGeneratorsForTest* findGeneratorsForCurrentTest() { - std::string testName = getResultCapture()->getCurrentTestName(); - - std::map::const_iterator it = - m_generatorsByTestName.find( testName ); - return it != m_generatorsByTestName.end() - ? it->second - : NULL; - } - - IGeneratorsForTest& getGeneratorsForCurrentTest() { - IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); - if( !generators ) { - std::string testName = getResultCapture()->getCurrentTestName(); - generators = createGeneratorsForTest(); - m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); - } - return *generators; - } - - private: - Ptr m_config; - IRunner* m_runner; - IResultCapture* m_resultCapture; - std::map m_generatorsByTestName; - }; - - namespace { - Context* currentContext = NULL; - } - IMutableContext& getCurrentMutableContext() { - if( !currentContext ) - currentContext = new Context(); - return *currentContext; - } - IContext& getCurrentContext() { - return getCurrentMutableContext(); - } - - Stream createStream( std::string const& streamName ) { - if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false ); - if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false ); - if( streamName == "debug" ) return Stream( new StreamBufImpl, true ); - - throw std::domain_error( "Unknown stream: " + streamName ); - } - - void cleanUpContext() { - delete currentContext; - currentContext = NULL; - } -} - -// #included from: catch_console_colour_impl.hpp -#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED - -namespace Catch { - namespace { - - struct IColourImpl { - virtual ~IColourImpl() {} - virtual void use( Colour::Code _colourCode ) = 0; - }; - - struct NoColourImpl : IColourImpl { - void use( Colour::Code ) {} - - static IColourImpl* instance() { - static NoColourImpl s_instance; - return &s_instance; - } - }; - - } // anon namespace -} // namespace Catch - -#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) -# ifdef CATCH_PLATFORM_WINDOWS -# define CATCH_CONFIG_COLOUR_WINDOWS -# else -# define CATCH_CONFIG_COLOUR_ANSI -# endif -#endif - -#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#ifdef __AFXDLL -#include -#else -#include -#endif - -namespace Catch { -namespace { - - class Win32ColourImpl : public IColourImpl { - public: - Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) - { - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); - originalAttributes = csbiInfo.wAttributes; - } - - virtual void use( Colour::Code _colourCode ) { - switch( _colourCode ) { - case Colour::None: return setTextAttribute( originalAttributes ); - case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - case Colour::Red: return setTextAttribute( FOREGROUND_RED ); - case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); - case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); - case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); - case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); - case Colour::Grey: return setTextAttribute( 0 ); - - case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); - case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); - case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); - case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - - case Colour::Bright: throw std::logic_error( "not a colour" ); - } - } - - private: - void setTextAttribute( WORD _textAttribute ) { - SetConsoleTextAttribute( stdoutHandle, _textAttribute ); - } - HANDLE stdoutHandle; - WORD originalAttributes; - }; - - IColourImpl* platformColourInstance() { - static Win32ColourImpl s_instance; - return &s_instance; - } - -} // end anon namespace -} // end namespace Catch - -#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// - -#include - -namespace Catch { -namespace { - - // use POSIX/ ANSI console terminal codes - // Thanks to Adam Strzelecki for original contribution - // (http://github.com/nanoant) - // https://github.com/philsquared/Catch/pull/131 - class PosixColourImpl : public IColourImpl { - public: - virtual void use( Colour::Code _colourCode ) { - switch( _colourCode ) { - case Colour::None: - case Colour::White: return setColour( "[0m" ); - case Colour::Red: return setColour( "[0;31m" ); - case Colour::Green: return setColour( "[0;32m" ); - case Colour::Blue: return setColour( "[0:34m" ); - case Colour::Cyan: return setColour( "[0;36m" ); - case Colour::Yellow: return setColour( "[0;33m" ); - case Colour::Grey: return setColour( "[1;30m" ); - - case Colour::LightGrey: return setColour( "[0;37m" ); - case Colour::BrightRed: return setColour( "[1;31m" ); - case Colour::BrightGreen: return setColour( "[1;32m" ); - case Colour::BrightWhite: return setColour( "[1;37m" ); - - case Colour::Bright: throw std::logic_error( "not a colour" ); - } - } - static IColourImpl* instance() { - static PosixColourImpl s_instance; - return &s_instance; - } - - private: - void setColour( const char* _escapeCode ) { - Catch::cout() << '\033' << _escapeCode; - } - }; - - IColourImpl* platformColourInstance() { - Ptr config = getCurrentContext().getConfig(); - return (config && config->forceColour()) || isatty(STDOUT_FILENO) - ? PosixColourImpl::instance() - : NoColourImpl::instance(); - } - -} // end anon namespace -} // end namespace Catch - -#else // not Windows or ANSI /////////////////////////////////////////////// - -namespace Catch { - - static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } - -} // end namespace Catch - -#endif // Windows/ ANSI/ None - -namespace Catch { - - Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } - Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } - Colour::~Colour(){ if( !m_moved ) use( None ); } - - void Colour::use( Code _colourCode ) { - static IColourImpl* impl = isDebuggerActive() - ? NoColourImpl::instance() - : platformColourInstance(); - impl->use( _colourCode ); - } - -} // end namespace Catch - -// #included from: catch_generators_impl.hpp -#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED - -#include -#include -#include - -namespace Catch { - - struct GeneratorInfo : IGeneratorInfo { - - GeneratorInfo( std::size_t size ) - : m_size( size ), - m_currentIndex( 0 ) - {} - - bool moveNext() { - if( ++m_currentIndex == m_size ) { - m_currentIndex = 0; - return false; - } - return true; - } - - std::size_t getCurrentIndex() const { - return m_currentIndex; - } - - std::size_t m_size; - std::size_t m_currentIndex; - }; - - /////////////////////////////////////////////////////////////////////////// - - class GeneratorsForTest : public IGeneratorsForTest { - - public: - ~GeneratorsForTest() { - deleteAll( m_generatorsInOrder ); - } - - IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { - std::map::const_iterator it = m_generatorsByName.find( fileInfo ); - if( it == m_generatorsByName.end() ) { - IGeneratorInfo* info = new GeneratorInfo( size ); - m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); - m_generatorsInOrder.push_back( info ); - return *info; - } - return *it->second; - } - - bool moveNext() { - std::vector::const_iterator it = m_generatorsInOrder.begin(); - std::vector::const_iterator itEnd = m_generatorsInOrder.end(); - for(; it != itEnd; ++it ) { - if( (*it)->moveNext() ) - return true; - } - return false; - } - - private: - std::map m_generatorsByName; - std::vector m_generatorsInOrder; - }; - - IGeneratorsForTest* createGeneratorsForTest() - { - return new GeneratorsForTest(); - } - -} // end namespace Catch - -// #included from: catch_assertionresult.hpp -#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED - -namespace Catch { - - AssertionInfo::AssertionInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - std::string const& _capturedExpression, - ResultDisposition::Flags _resultDisposition ) - : macroName( _macroName ), - lineInfo( _lineInfo ), - capturedExpression( _capturedExpression ), - resultDisposition( _resultDisposition ) - {} - - AssertionResult::AssertionResult() {} - - AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) - : m_info( info ), - m_resultData( data ) - {} - - AssertionResult::~AssertionResult() {} - - // Result was a success - bool AssertionResult::succeeded() const { - return Catch::isOk( m_resultData.resultType ); - } - - // Result was a success, or failure is suppressed - bool AssertionResult::isOk() const { - return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); - } - - ResultWas::OfType AssertionResult::getResultType() const { - return m_resultData.resultType; - } - - bool AssertionResult::hasExpression() const { - return !m_info.capturedExpression.empty(); - } - - bool AssertionResult::hasMessage() const { - return !m_resultData.message.empty(); - } - - std::string AssertionResult::getExpression() const { - if( isFalseTest( m_info.resultDisposition ) ) - return "!" + m_info.capturedExpression; - else - return m_info.capturedExpression; - } - std::string AssertionResult::getExpressionInMacro() const { - if( m_info.macroName.empty() ) - return m_info.capturedExpression; - else - return m_info.macroName + "( " + m_info.capturedExpression + " )"; - } - - bool AssertionResult::hasExpandedExpression() const { - return hasExpression() && getExpandedExpression() != getExpression(); - } - - std::string AssertionResult::getExpandedExpression() const { - return m_resultData.reconstructedExpression; - } - - std::string AssertionResult::getMessage() const { - return m_resultData.message; - } - SourceLineInfo AssertionResult::getSourceInfo() const { - return m_info.lineInfo; - } - - std::string AssertionResult::getTestMacroName() const { - return m_info.macroName; - } - -} // end namespace Catch - -// #included from: catch_test_case_info.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED - -namespace Catch { - - inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { - if( startsWith( tag, "." ) || - tag == "hide" || - tag == "!hide" ) - return TestCaseInfo::IsHidden; - else if( tag == "!throws" ) - return TestCaseInfo::Throws; - else if( tag == "!shouldfail" ) - return TestCaseInfo::ShouldFail; - else if( tag == "!mayfail" ) - return TestCaseInfo::MayFail; - else - return TestCaseInfo::None; - } - inline bool isReservedTag( std::string const& tag ) { - return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] ); - } - inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { - if( isReservedTag( tag ) ) { - { - Colour colourGuard( Colour::Red ); - Catch::cerr() - << "Tag name [" << tag << "] not allowed.\n" - << "Tag names starting with non alpha-numeric characters are reserved\n"; - } - { - Colour colourGuard( Colour::FileName ); - Catch::cerr() << _lineInfo << std::endl; - } - exit(1); - } - } - - TestCase makeTestCase( ITestCase* _testCase, - std::string const& _className, - std::string const& _name, - std::string const& _descOrTags, - SourceLineInfo const& _lineInfo ) - { - bool isHidden( startsWith( _name, "./" ) ); // Legacy support - - // Parse out tags - std::set tags; - std::string desc, tag; - bool inTag = false; - for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { - char c = _descOrTags[i]; - if( !inTag ) { - if( c == '[' ) - inTag = true; - else - desc += c; - } - else { - if( c == ']' ) { - TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); - if( prop == TestCaseInfo::IsHidden ) - isHidden = true; - else if( prop == TestCaseInfo::None ) - enforceNotReservedTag( tag, _lineInfo ); - - tags.insert( tag ); - tag.clear(); - inTag = false; - } - else - tag += c; - } - } - if( isHidden ) { - tags.insert( "hide" ); - tags.insert( "." ); - } - - TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); - return TestCase( _testCase, info ); - } - - TestCaseInfo::TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::set const& _tags, - SourceLineInfo const& _lineInfo ) - : name( _name ), - className( _className ), - description( _description ), - tags( _tags ), - lineInfo( _lineInfo ), - properties( None ) - { - std::ostringstream oss; - for( std::set::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) { - oss << "[" << *it << "]"; - std::string lcaseTag = toLower( *it ); - properties = static_cast( properties | parseSpecialTag( lcaseTag ) ); - lcaseTags.insert( lcaseTag ); - } - tagsAsString = oss.str(); - } - - TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) - : name( other.name ), - className( other.className ), - description( other.description ), - tags( other.tags ), - lcaseTags( other.lcaseTags ), - tagsAsString( other.tagsAsString ), - lineInfo( other.lineInfo ), - properties( other.properties ) - {} - - bool TestCaseInfo::isHidden() const { - return ( properties & IsHidden ) != 0; - } - bool TestCaseInfo::throws() const { - return ( properties & Throws ) != 0; - } - bool TestCaseInfo::okToFail() const { - return ( properties & (ShouldFail | MayFail ) ) != 0; - } - bool TestCaseInfo::expectedToFail() const { - return ( properties & (ShouldFail ) ) != 0; - } - - TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} - - TestCase::TestCase( TestCase const& other ) - : TestCaseInfo( other ), - test( other.test ) - {} - - TestCase TestCase::withName( std::string const& _newName ) const { - TestCase other( *this ); - other.name = _newName; - return other; - } - - void TestCase::swap( TestCase& other ) { - test.swap( other.test ); - name.swap( other.name ); - className.swap( other.className ); - description.swap( other.description ); - tags.swap( other.tags ); - lcaseTags.swap( other.lcaseTags ); - tagsAsString.swap( other.tagsAsString ); - std::swap( TestCaseInfo::properties, static_cast( other ).properties ); - std::swap( lineInfo, other.lineInfo ); - } - - void TestCase::invoke() const { - test->invoke(); - } - - bool TestCase::operator == ( TestCase const& other ) const { - return test.get() == other.test.get() && - name == other.name && - className == other.className; - } - - bool TestCase::operator < ( TestCase const& other ) const { - return name < other.name; - } - TestCase& TestCase::operator = ( TestCase const& other ) { - TestCase temp( other ); - swap( temp ); - return *this; - } - - TestCaseInfo const& TestCase::getTestCaseInfo() const - { - return *this; - } - -} // end namespace Catch - -// #included from: catch_version.hpp -#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED - -namespace Catch { - - // These numbers are maintained by a script - Version libraryVersion( 1, 1, 1, "master" ); -} - -// #included from: catch_message.hpp -#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED - -namespace Catch { - - MessageInfo::MessageInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ) - : macroName( _macroName ), - lineInfo( _lineInfo ), - type( _type ), - sequence( ++globalCount ) - {} - - // This may need protecting if threading support is added - unsigned int MessageInfo::globalCount = 0; - - //////////////////////////////////////////////////////////////////////////// - - ScopedMessage::ScopedMessage( MessageBuilder const& builder ) - : m_info( builder.m_info ) - { - m_info.message = builder.m_stream.str(); - getResultCapture().pushScopedMessage( m_info ); - } - ScopedMessage::ScopedMessage( ScopedMessage const& other ) - : m_info( other.m_info ) - {} - - ScopedMessage::~ScopedMessage() { - getResultCapture().popScopedMessage( m_info ); - } - -} // end namespace Catch - -// #included from: catch_legacy_reporter_adapter.hpp -#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED - -// #included from: catch_legacy_reporter_adapter.h -#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED - -namespace Catch -{ - // Deprecated - struct IReporter : IShared { - virtual ~IReporter(); - - virtual bool shouldRedirectStdout() const = 0; - - virtual void StartTesting() = 0; - virtual void EndTesting( Totals const& totals ) = 0; - virtual void StartGroup( std::string const& groupName ) = 0; - virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; - virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; - virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; - virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; - virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; - virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; - virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; - virtual void Aborted() = 0; - virtual void Result( AssertionResult const& result ) = 0; - }; - - class LegacyReporterAdapter : public SharedImpl - { - public: - LegacyReporterAdapter( Ptr const& legacyReporter ); - virtual ~LegacyReporterAdapter(); - - virtual ReporterPreferences getPreferences() const; - virtual void noMatchingTestCases( std::string const& ); - virtual void testRunStarting( TestRunInfo const& ); - virtual void testGroupStarting( GroupInfo const& groupInfo ); - virtual void testCaseStarting( TestCaseInfo const& testInfo ); - virtual void sectionStarting( SectionInfo const& sectionInfo ); - virtual void assertionStarting( AssertionInfo const& ); - virtual bool assertionEnded( AssertionStats const& assertionStats ); - virtual void sectionEnded( SectionStats const& sectionStats ); - virtual void testCaseEnded( TestCaseStats const& testCaseStats ); - virtual void testGroupEnded( TestGroupStats const& testGroupStats ); - virtual void testRunEnded( TestRunStats const& testRunStats ); - virtual void skipTest( TestCaseInfo const& ); - - private: - Ptr m_legacyReporter; - }; -} - -namespace Catch -{ - LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) - : m_legacyReporter( legacyReporter ) - {} - LegacyReporterAdapter::~LegacyReporterAdapter() {} - - ReporterPreferences LegacyReporterAdapter::getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); - return prefs; - } - - void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} - void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { - m_legacyReporter->StartTesting(); - } - void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { - m_legacyReporter->StartGroup( groupInfo.name ); - } - void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { - m_legacyReporter->StartTestCase( testInfo ); - } - void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { - m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); - } - void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { - // Not on legacy interface - } - - bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { - if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { - for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); - it != itEnd; - ++it ) { - if( it->type == ResultWas::Info ) { - ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); - rb << it->message; - rb.setResultType( ResultWas::Info ); - AssertionResult result = rb.build(); - m_legacyReporter->Result( result ); - } - } - } - m_legacyReporter->Result( assertionStats.assertionResult ); - return true; - } - void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { - if( sectionStats.missingAssertions ) - m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); - m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); - } - void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { - m_legacyReporter->EndTestCase - ( testCaseStats.testInfo, - testCaseStats.totals, - testCaseStats.stdOut, - testCaseStats.stdErr ); - } - void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { - if( testGroupStats.aborting ) - m_legacyReporter->Aborted(); - m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); - } - void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { - m_legacyReporter->EndTesting( testRunStats.totals ); - } - void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { - } -} - -// #included from: catch_timer.hpp - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wc++11-long-long" -#endif - -#ifdef CATCH_PLATFORM_WINDOWS -#include -#else -#include -#endif - -namespace Catch { - - namespace { -#ifdef CATCH_PLATFORM_WINDOWS - uint64_t getCurrentTicks() { - static uint64_t hz=0, hzo=0; - if (!hz) { - QueryPerformanceFrequency( reinterpret_cast( &hz ) ); - QueryPerformanceCounter( reinterpret_cast( &hzo ) ); - } - uint64_t t; - QueryPerformanceCounter( reinterpret_cast( &t ) ); - return ((t-hzo)*1000000)/hz; - } -#else - uint64_t getCurrentTicks() { - timeval t; - gettimeofday(&t,NULL); - return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); - } -#endif - } - - void Timer::start() { - m_ticks = getCurrentTicks(); - } - unsigned int Timer::getElapsedMicroseconds() const { - return static_cast(getCurrentTicks() - m_ticks); - } - unsigned int Timer::getElapsedMilliseconds() const { - return static_cast(getElapsedMicroseconds()/1000); - } - double Timer::getElapsedSeconds() const { - return getElapsedMicroseconds()/1000000.0; - } - -} // namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif -// #included from: catch_common.hpp -#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED - -namespace Catch { - - bool startsWith( std::string const& s, std::string const& prefix ) { - return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix; - } - bool endsWith( std::string const& s, std::string const& suffix ) { - return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix; - } - bool contains( std::string const& s, std::string const& infix ) { - return s.find( infix ) != std::string::npos; - } - void toLowerInPlace( std::string& s ) { - std::transform( s.begin(), s.end(), s.begin(), ::tolower ); - } - std::string toLower( std::string const& s ) { - std::string lc = s; - toLowerInPlace( lc ); - return lc; - } - std::string trim( std::string const& str ) { - static char const* whitespaceChars = "\n\r\t "; - std::string::size_type start = str.find_first_not_of( whitespaceChars ); - std::string::size_type end = str.find_last_not_of( whitespaceChars ); - - return start != std::string::npos ? str.substr( start, 1+end-start ) : ""; - } - - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { - bool replaced = false; - std::size_t i = str.find( replaceThis ); - while( i != std::string::npos ) { - replaced = true; - str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); - if( i < str.size()-withThis.size() ) - i = str.find( replaceThis, i+withThis.size() ); - else - i = std::string::npos; - } - return replaced; - } - - pluralise::pluralise( std::size_t count, std::string const& label ) - : m_count( count ), - m_label( label ) - {} - - std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { - os << pluraliser.m_count << " " << pluraliser.m_label; - if( pluraliser.m_count != 1 ) - os << "s"; - return os; - } - - SourceLineInfo::SourceLineInfo() : line( 0 ){} - SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) - : file( _file ), - line( _line ) - {} - SourceLineInfo::SourceLineInfo( SourceLineInfo const& other ) - : file( other.file ), - line( other.line ) - {} - bool SourceLineInfo::empty() const { - return file.empty(); - } - bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { - return line == other.line && file == other.file; - } - bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { - return line < other.line || ( line == other.line && file < other.file ); - } - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { -#ifndef __GNUG__ - os << info.file << "(" << info.line << ")"; -#else - os << info.file << ":" << info.line; -#endif - return os; - } - - void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { - std::ostringstream oss; - oss << locationInfo << ": Internal Catch error: '" << message << "'"; - if( alwaysTrue() ) - throw std::logic_error( oss.str() ); - } -} - -// #included from: catch_section.hpp -#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED - -namespace Catch { - - SectionInfo::SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name, - std::string const& _description ) - : name( _name ), - description( _description ), - lineInfo( _lineInfo ) - {} - - Section::Section( SectionInfo const& info ) - : m_info( info ), - m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) - { - m_timer.start(); - } - - Section::~Section() { - if( m_sectionIncluded ) - getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() ); - } - - // This indicates whether the section should be executed or not - Section::operator bool() const { - return m_sectionIncluded; - } - -} // end namespace Catch - -// #included from: catch_debugger.hpp -#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED - -#include - -#ifdef CATCH_PLATFORM_MAC - - #include - #include - #include - #include - #include - - namespace Catch{ - - // The following function is taken directly from the following technical note: - // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html - - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). - bool isDebuggerActive(){ - - int mib[4]; - struct kinfo_proc info; - size_t size; - - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - - info.kp_proc.p_flag = 0; - - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - // Call sysctl. - - size = sizeof(info); - if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) { - Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; - return false; - } - - // We're being debugged if the P_TRACED flag is set. - - return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); - } - } // namespace Catch - -#elif defined(_MSC_VER) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#else - namespace Catch { - inline bool isDebuggerActive() { return false; } - } -#endif // Platform - -#ifdef CATCH_PLATFORM_WINDOWS - extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* ); - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - ::OutputDebugStringA( text.c_str() ); - } - } -#else - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - // !TBD: Need a version for Mac/ XCode and other IDEs - Catch::cout() << text; - } - } -#endif // Platform - -// #included from: catch_tostring.hpp -#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED - -namespace Catch { - -namespace Detail { - - std::string unprintableString = "{?}"; - - namespace { - struct Endianness { - enum Arch { Big, Little }; - - static Arch which() { - union _{ - int asInt; - char asChar[sizeof (int)]; - } u; - - u.asInt = 1; - return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; - } - }; - } - - std::string rawMemoryToString( const void *object, std::size_t size ) - { - // Reverse order for little endian architectures - int i = 0, end = static_cast( size ), inc = 1; - if( Endianness::which() == Endianness::Little ) { - i = end-1; - end = inc = -1; - } - - unsigned char const *bytes = static_cast(object); - std::ostringstream os; - os << "0x" << std::setfill('0') << std::hex; - for( ; i != end; i += inc ) - os << std::setw(2) << static_cast(bytes[i]); - return os.str(); - } -} - -std::string toString( std::string const& value ) { - std::string s = value; - if( getCurrentContext().getConfig()->showInvisibles() ) { - for(size_t i = 0; i < s.size(); ++i ) { - std::string subs; - switch( s[i] ) { - case '\n': subs = "\\n"; break; - case '\t': subs = "\\t"; break; - default: break; - } - if( !subs.empty() ) { - s = s.substr( 0, i ) + subs + s.substr( i+1 ); - ++i; - } - } - } - return "\"" + s + "\""; -} -std::string toString( std::wstring const& value ) { - - std::string s; - s.reserve( value.size() ); - for(size_t i = 0; i < value.size(); ++i ) - s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; - return Catch::toString( s ); -} - -std::string toString( const char* const value ) { - return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); -} - -std::string toString( char* const value ) { - return Catch::toString( static_cast( value ) ); -} - -std::string toString( const wchar_t* const value ) -{ - return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); -} - -std::string toString( wchar_t* const value ) -{ - return Catch::toString( static_cast( value ) ); -} - -std::string toString( int value ) { - std::ostringstream oss; - if( value > 8192 ) - oss << "0x" << std::hex << value; - else - oss << value; - return oss.str(); -} - -std::string toString( unsigned long value ) { - std::ostringstream oss; - if( value > 8192 ) - oss << "0x" << std::hex << value; - else - oss << value; - return oss.str(); -} - -std::string toString( unsigned int value ) { - return Catch::toString( static_cast( value ) ); -} - -template -std::string fpToString( T value, int precision ) { - std::ostringstream oss; - oss << std::setprecision( precision ) - << std::fixed - << value; - std::string d = oss.str(); - std::size_t i = d.find_last_not_of( '0' ); - if( i != std::string::npos && i != d.size()-1 ) { - if( d[i] == '.' ) - i++; - d = d.substr( 0, i+1 ); - } - return d; -} - -std::string toString( const double value ) { - return fpToString( value, 10 ); -} -std::string toString( const float value ) { - return fpToString( value, 5 ) + "f"; -} - -std::string toString( bool value ) { - return value ? "true" : "false"; -} - -std::string toString( char value ) { - return value < ' ' - ? toString( static_cast( value ) ) - : Detail::makeString( value ); -} - -std::string toString( signed char value ) { - return toString( static_cast( value ) ); -} - -std::string toString( unsigned char value ) { - return toString( static_cast( value ) ); -} - -#ifdef CATCH_CONFIG_CPP11_NULLPTR -std::string toString( std::nullptr_t ) { - return "nullptr"; -} -#endif - -#ifdef __OBJC__ - std::string toString( NSString const * const& nsstring ) { - if( !nsstring ) - return "nil"; - return "@" + toString([nsstring UTF8String]); - } - std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) { - if( !nsstring ) - return "nil"; - return "@" + toString([nsstring UTF8String]); - } - std::string toString( NSObject* const& nsObject ) { - return toString( [nsObject description] ); - } -#endif - -} // end namespace Catch - -// #included from: catch_result_builder.hpp -#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED - -namespace Catch { - - ResultBuilder::ResultBuilder( char const* macroName, - SourceLineInfo const& lineInfo, - char const* capturedExpression, - ResultDisposition::Flags resultDisposition ) - : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ), - m_shouldDebugBreak( false ), - m_shouldThrow( false ) - {} - - ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { - m_data.resultType = result; - return *this; - } - ResultBuilder& ResultBuilder::setResultType( bool result ) { - m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; - return *this; - } - ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) { - m_exprComponents.lhs = lhs; - return *this; - } - ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) { - m_exprComponents.rhs = rhs; - return *this; - } - ResultBuilder& ResultBuilder::setOp( std::string const& op ) { - m_exprComponents.op = op; - return *this; - } - - void ResultBuilder::endExpression() { - m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition ); - captureExpression(); - } - - void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { - m_assertionInfo.resultDisposition = resultDisposition; - m_stream.oss << Catch::translateActiveException(); - captureResult( ResultWas::ThrewException ); - } - - void ResultBuilder::captureResult( ResultWas::OfType resultType ) { - setResultType( resultType ); - captureExpression(); - } - - void ResultBuilder::captureExpression() { - AssertionResult result = build(); - getResultCapture().assertionEnded( result ); - - if( !result.isOk() ) { - if( getCurrentContext().getConfig()->shouldDebugBreak() ) - m_shouldDebugBreak = true; - if( getCurrentContext().getRunner()->aborting() || m_assertionInfo.resultDisposition == ResultDisposition::Normal ) - m_shouldThrow = true; - } - } - void ResultBuilder::react() { - if( m_shouldThrow ) - throw Catch::TestFailureException(); - } - - bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } - bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } - - AssertionResult ResultBuilder::build() const - { - assert( m_data.resultType != ResultWas::Unknown ); - - AssertionResultData data = m_data; - - // Flip bool results if testFalse is set - if( m_exprComponents.testFalse ) { - if( data.resultType == ResultWas::Ok ) - data.resultType = ResultWas::ExpressionFailed; - else if( data.resultType == ResultWas::ExpressionFailed ) - data.resultType = ResultWas::Ok; - } - - data.message = m_stream.oss.str(); - data.reconstructedExpression = reconstructExpression(); - if( m_exprComponents.testFalse ) { - if( m_exprComponents.op == "" ) - data.reconstructedExpression = "!" + data.reconstructedExpression; - else - data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; - } - return AssertionResult( m_assertionInfo, data ); - } - std::string ResultBuilder::reconstructExpression() const { - if( m_exprComponents.op == "" ) - return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs; - else if( m_exprComponents.op == "matches" ) - return m_exprComponents.lhs + " " + m_exprComponents.rhs; - else if( m_exprComponents.op != "!" ) { - if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && - m_exprComponents.lhs.find("\n") == std::string::npos && - m_exprComponents.rhs.find("\n") == std::string::npos ) - return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; - else - return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; - } - else - return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}"; - } - -} // end namespace Catch - -// #included from: catch_tag_alias_registry.hpp -#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED - -// #included from: catch_tag_alias_registry.h -#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED - -#include - -namespace Catch { - - class TagAliasRegistry : public ITagAliasRegistry { - public: - virtual ~TagAliasRegistry(); - virtual Option find( std::string const& alias ) const; - virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; - void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - static TagAliasRegistry& get(); - - private: - std::map m_registry; - }; - -} // end namespace Catch - -#include -#include - -namespace Catch { - - TagAliasRegistry::~TagAliasRegistry() {} - - Option TagAliasRegistry::find( std::string const& alias ) const { - std::map::const_iterator it = m_registry.find( alias ); - if( it != m_registry.end() ) - return it->second; - else - return Option(); - } - - std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { - std::string expandedTestSpec = unexpandedTestSpec; - for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); - it != itEnd; - ++it ) { - std::size_t pos = expandedTestSpec.find( it->first ); - if( pos != std::string::npos ) { - expandedTestSpec = expandedTestSpec.substr( 0, pos ) + - it->second.tag + - expandedTestSpec.substr( pos + it->first.size() ); - } - } - return expandedTestSpec; - } - - void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { - - if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) { - std::ostringstream oss; - oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo; - throw std::domain_error( oss.str().c_str() ); - } - if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { - std::ostringstream oss; - oss << "error: tag alias, \"" << alias << "\" already registered.\n" - << "\tFirst seen at " << find(alias)->lineInfo << "\n" - << "\tRedefined at " << lineInfo; - throw std::domain_error( oss.str().c_str() ); - } - } - - TagAliasRegistry& TagAliasRegistry::get() { - static TagAliasRegistry instance; - return instance; - - } - - ITagAliasRegistry::~ITagAliasRegistry() {} - ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); } - - RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { - try { - TagAliasRegistry::get().add( alias, tag, lineInfo ); - } - catch( std::exception& ex ) { - Colour colourGuard( Colour::Red ); - Catch::cerr() << ex.what() << std::endl; - exit(1); - } - } - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_xml.hpp -#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED - -// #included from: catch_reporter_bases.hpp -#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED - -#include - -namespace Catch { - - struct StreamingReporterBase : SharedImpl { - - StreamingReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - {} - - virtual ~StreamingReporterBase(); - - virtual void noMatchingTestCases( std::string const& ) {} - - virtual void testRunStarting( TestRunInfo const& _testRunInfo ) { - currentTestRunInfo = _testRunInfo; - } - virtual void testGroupStarting( GroupInfo const& _groupInfo ) { - currentGroupInfo = _groupInfo; - } - - virtual void testCaseStarting( TestCaseInfo const& _testInfo ) { - currentTestCaseInfo = _testInfo; - } - virtual void sectionStarting( SectionInfo const& _sectionInfo ) { - m_sectionStack.push_back( _sectionInfo ); - } - - virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) { - m_sectionStack.pop_back(); - } - virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) { - currentTestCaseInfo.reset(); - } - virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) { - currentGroupInfo.reset(); - } - virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) { - currentTestCaseInfo.reset(); - currentGroupInfo.reset(); - currentTestRunInfo.reset(); - } - - virtual void skipTest( TestCaseInfo const& ) { - // Don't do anything with this by default. - // It can optionally be overridden in the derived class. - } - - Ptr m_config; - std::ostream& stream; - - LazyStat currentTestRunInfo; - LazyStat currentGroupInfo; - LazyStat currentTestCaseInfo; - - std::vector m_sectionStack; - }; - - struct CumulativeReporterBase : SharedImpl { - template - struct Node : SharedImpl<> { - explicit Node( T const& _value ) : value( _value ) {} - virtual ~Node() {} - - typedef std::vector > ChildNodes; - T value; - ChildNodes children; - }; - struct SectionNode : SharedImpl<> { - explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} - virtual ~SectionNode(); - - bool operator == ( SectionNode const& other ) const { - return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; - } - bool operator == ( Ptr const& other ) const { - return operator==( *other ); - } - - SectionStats stats; - typedef std::vector > ChildSections; - typedef std::vector Assertions; - ChildSections childSections; - Assertions assertions; - std::string stdOut; - std::string stdErr; - }; - - struct BySectionInfo { - BySectionInfo( SectionInfo const& other ) : m_other( other ) {} - BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} - bool operator() ( Ptr const& node ) const { - return node->stats.sectionInfo.lineInfo == m_other.lineInfo; - } - private: - void operator=( BySectionInfo const& ); - SectionInfo const& m_other; - }; - - typedef Node TestCaseNode; - typedef Node TestGroupNode; - typedef Node TestRunNode; - - CumulativeReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - {} - ~CumulativeReporterBase(); - - virtual void testRunStarting( TestRunInfo const& ) {} - virtual void testGroupStarting( GroupInfo const& ) {} - - virtual void testCaseStarting( TestCaseInfo const& ) {} - - virtual void sectionStarting( SectionInfo const& sectionInfo ) { - SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); - Ptr node; - if( m_sectionStack.empty() ) { - if( !m_rootSection ) - m_rootSection = new SectionNode( incompleteStats ); - node = m_rootSection; - } - else { - SectionNode& parentNode = *m_sectionStack.back(); - SectionNode::ChildSections::const_iterator it = - std::find_if( parentNode.childSections.begin(), - parentNode.childSections.end(), - BySectionInfo( sectionInfo ) ); - if( it == parentNode.childSections.end() ) { - node = new SectionNode( incompleteStats ); - parentNode.childSections.push_back( node ); - } - else - node = *it; - } - m_sectionStack.push_back( node ); - m_deepestSection = node; - } - - virtual void assertionStarting( AssertionInfo const& ) {} - - virtual bool assertionEnded( AssertionStats const& assertionStats ) { - assert( !m_sectionStack.empty() ); - SectionNode& sectionNode = *m_sectionStack.back(); - sectionNode.assertions.push_back( assertionStats ); - return true; - } - virtual void sectionEnded( SectionStats const& sectionStats ) { - assert( !m_sectionStack.empty() ); - SectionNode& node = *m_sectionStack.back(); - node.stats = sectionStats; - m_sectionStack.pop_back(); - } - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) { - Ptr node = new TestCaseNode( testCaseStats ); - assert( m_sectionStack.size() == 0 ); - node->children.push_back( m_rootSection ); - m_testCases.push_back( node ); - m_rootSection.reset(); - - assert( m_deepestSection ); - m_deepestSection->stdOut = testCaseStats.stdOut; - m_deepestSection->stdErr = testCaseStats.stdErr; - } - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) { - Ptr node = new TestGroupNode( testGroupStats ); - node->children.swap( m_testCases ); - m_testGroups.push_back( node ); - } - virtual void testRunEnded( TestRunStats const& testRunStats ) { - Ptr node = new TestRunNode( testRunStats ); - node->children.swap( m_testGroups ); - m_testRuns.push_back( node ); - testRunEndedCumulative(); - } - virtual void testRunEndedCumulative() = 0; - - virtual void skipTest( TestCaseInfo const& ) {} - - Ptr m_config; - std::ostream& stream; - std::vector m_assertions; - std::vector > > m_sections; - std::vector > m_testCases; - std::vector > m_testGroups; - - std::vector > m_testRuns; - - Ptr m_rootSection; - Ptr m_deepestSection; - std::vector > m_sectionStack; - - }; - - template - char const* getLineOfChars() { - static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; - if( !*line ) { - memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); - line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; - } - return line; - } - -} // end namespace Catch - -// #included from: ../internal/catch_reporter_registrars.hpp -#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED - -namespace Catch { - - template - class LegacyReporterRegistrar { - - class ReporterFactory : public IReporterFactory { - virtual IStreamingReporter* create( ReporterConfig const& config ) const { - return new LegacyReporterAdapter( new T( config ) ); - } - - virtual std::string getDescription() const { - return T::getDescription(); - } - }; - - public: - - LegacyReporterRegistrar( std::string const& name ) { - getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); - } - }; - - template - class ReporterRegistrar { - - class ReporterFactory : public IReporterFactory { - - // *** Please Note ***: - // - If you end up here looking at a compiler error because it's trying to register - // your custom reporter class be aware that the native reporter interface has changed - // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via - // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. - // However please consider updating to the new interface as the old one is now - // deprecated and will probably be removed quite soon! - // Please contact me via github if you have any questions at all about this. - // In fact, ideally, please contact me anyway to let me know you've hit this - as I have - // no idea who is actually using custom reporters at all (possibly no-one!). - // The new interface is designed to minimise exposure to interface changes in the future. - virtual IStreamingReporter* create( ReporterConfig const& config ) const { - return new T( config ); - } - - virtual std::string getDescription() const { - return T::getDescription(); - } - }; - - public: - - ReporterRegistrar( std::string const& name ) { - getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); - } - }; -} - -#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ - namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } -#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ - namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } - -// #included from: ../internal/catch_xmlwriter.hpp -#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED - -#include -#include -#include - -namespace Catch { - - class XmlWriter { - public: - - class ScopedElement { - public: - ScopedElement( XmlWriter* writer ) - : m_writer( writer ) - {} - - ScopedElement( ScopedElement const& other ) - : m_writer( other.m_writer ){ - other.m_writer = NULL; - } - - ~ScopedElement() { - if( m_writer ) - m_writer->endElement(); - } - - ScopedElement& writeText( std::string const& text, bool indent = true ) { - m_writer->writeText( text, indent ); - return *this; - } - - template - ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { - m_writer->writeAttribute( name, attribute ); - return *this; - } - - private: - mutable XmlWriter* m_writer; - }; - - XmlWriter() - : m_tagIsOpen( false ), - m_needsNewline( false ), - m_os( &Catch::cout() ) - {} - - XmlWriter( std::ostream& os ) - : m_tagIsOpen( false ), - m_needsNewline( false ), - m_os( &os ) - {} - - ~XmlWriter() { - while( !m_tags.empty() ) - endElement(); - } - -//# ifndef CATCH_CPP11_OR_GREATER -// XmlWriter& operator = ( XmlWriter const& other ) { -// XmlWriter temp( other ); -// swap( temp ); -// return *this; -// } -//# else -// XmlWriter( XmlWriter const& ) = default; -// XmlWriter( XmlWriter && ) = default; -// XmlWriter& operator = ( XmlWriter const& ) = default; -// XmlWriter& operator = ( XmlWriter && ) = default; -//# endif -// -// void swap( XmlWriter& other ) { -// std::swap( m_tagIsOpen, other.m_tagIsOpen ); -// std::swap( m_needsNewline, other.m_needsNewline ); -// std::swap( m_tags, other.m_tags ); -// std::swap( m_indent, other.m_indent ); -// std::swap( m_os, other.m_os ); -// } - - XmlWriter& startElement( std::string const& name ) { - ensureTagClosed(); - newlineIfNecessary(); - stream() << m_indent << "<" << name; - m_tags.push_back( name ); - m_indent += " "; - m_tagIsOpen = true; - return *this; - } - - ScopedElement scopedElement( std::string const& name ) { - ScopedElement scoped( this ); - startElement( name ); - return scoped; - } - - XmlWriter& endElement() { - newlineIfNecessary(); - m_indent = m_indent.substr( 0, m_indent.size()-2 ); - if( m_tagIsOpen ) { - stream() << "/>\n"; - m_tagIsOpen = false; - } - else { - stream() << m_indent << "\n"; - } - m_tags.pop_back(); - return *this; - } - - XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { - if( !name.empty() && !attribute.empty() ) { - stream() << " " << name << "=\""; - writeEncodedText( attribute ); - stream() << "\""; - } - return *this; - } - - XmlWriter& writeAttribute( std::string const& name, bool attribute ) { - stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\""; - return *this; - } - - template - XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { - if( !name.empty() ) - stream() << " " << name << "=\"" << attribute << "\""; - return *this; - } - - XmlWriter& writeText( std::string const& text, bool indent = true ) { - if( !text.empty() ){ - bool tagWasOpen = m_tagIsOpen; - ensureTagClosed(); - if( tagWasOpen && indent ) - stream() << m_indent; - writeEncodedText( text ); - m_needsNewline = true; - } - return *this; - } - - XmlWriter& writeComment( std::string const& text ) { - ensureTagClosed(); - stream() << m_indent << ""; - m_needsNewline = true; - return *this; - } - - XmlWriter& writeBlankLine() { - ensureTagClosed(); - stream() << "\n"; - return *this; - } - - void setStream( std::ostream& os ) { - m_os = &os; - } - - private: - XmlWriter( XmlWriter const& ); - void operator=( XmlWriter const& ); - - std::ostream& stream() { - return *m_os; - } - - void ensureTagClosed() { - if( m_tagIsOpen ) { - stream() << ">\n"; - m_tagIsOpen = false; - } - } - - void newlineIfNecessary() { - if( m_needsNewline ) { - stream() << "\n"; - m_needsNewline = false; - } - } - - void writeEncodedText( std::string const& text ) { - static const char* charsToEncode = "<&\""; - std::string mtext = text; - std::string::size_type pos = mtext.find_first_of( charsToEncode ); - while( pos != std::string::npos ) { - stream() << mtext.substr( 0, pos ); - - switch( mtext[pos] ) { - case '<': - stream() << "<"; - break; - case '&': - stream() << "&"; - break; - case '\"': - stream() << """; - break; - } - mtext = mtext.substr( pos+1 ); - pos = mtext.find_first_of( charsToEncode ); - } - stream() << mtext; - } - - bool m_tagIsOpen; - bool m_needsNewline; - std::vector m_tags; - std::string m_indent; - std::ostream* m_os; - }; - -} -namespace Catch { - class XmlReporter : public StreamingReporterBase { - public: - XmlReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ), - m_sectionDepth( 0 ) - {} - - virtual ~XmlReporter(); - - static std::string getDescription() { - return "Reports test results as an XML document"; - } - - public: // StreamingReporterBase - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = true; - return prefs; - } - - virtual void noMatchingTestCases( std::string const& s ) { - StreamingReporterBase::noMatchingTestCases( s ); - } - - virtual void testRunStarting( TestRunInfo const& testInfo ) { - StreamingReporterBase::testRunStarting( testInfo ); - m_xml.setStream( stream ); - m_xml.startElement( "Catch" ); - if( !m_config->name().empty() ) - m_xml.writeAttribute( "name", m_config->name() ); - } - - virtual void testGroupStarting( GroupInfo const& groupInfo ) { - StreamingReporterBase::testGroupStarting( groupInfo ); - m_xml.startElement( "Group" ) - .writeAttribute( "name", groupInfo.name ); - } - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) { - StreamingReporterBase::testCaseStarting(testInfo); - m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) ); - - if ( m_config->showDurations() == ShowDurations::Always ) - m_testCaseTimer.start(); - } - - virtual void sectionStarting( SectionInfo const& sectionInfo ) { - StreamingReporterBase::sectionStarting( sectionInfo ); - if( m_sectionDepth++ > 0 ) { - m_xml.startElement( "Section" ) - .writeAttribute( "name", trim( sectionInfo.name ) ) - .writeAttribute( "description", sectionInfo.description ); - } - } - - virtual void assertionStarting( AssertionInfo const& ) { } - - virtual bool assertionEnded( AssertionStats const& assertionStats ) { - const AssertionResult& assertionResult = assertionStats.assertionResult; - - // Print any info messages in tags. - if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { - for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); - it != itEnd; - ++it ) { - if( it->type == ResultWas::Info ) { - m_xml.scopedElement( "Info" ) - .writeText( it->message ); - } else if ( it->type == ResultWas::Warning ) { - m_xml.scopedElement( "Warning" ) - .writeText( it->message ); - } - } - } - - // Drop out if result was successful but we're not printing them. - if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) ) - return true; - - // Print the expression if there is one. - if( assertionResult.hasExpression() ) { - m_xml.startElement( "Expression" ) - .writeAttribute( "success", assertionResult.succeeded() ) - .writeAttribute( "type", assertionResult.getTestMacroName() ) - .writeAttribute( "filename", assertionResult.getSourceInfo().file ) - .writeAttribute( "line", assertionResult.getSourceInfo().line ); - - m_xml.scopedElement( "Original" ) - .writeText( assertionResult.getExpression() ); - m_xml.scopedElement( "Expanded" ) - .writeText( assertionResult.getExpandedExpression() ); - } - - // And... Print a result applicable to each result type. - switch( assertionResult.getResultType() ) { - case ResultWas::ThrewException: - m_xml.scopedElement( "Exception" ) - .writeAttribute( "filename", assertionResult.getSourceInfo().file ) - .writeAttribute( "line", assertionResult.getSourceInfo().line ) - .writeText( assertionResult.getMessage() ); - break; - case ResultWas::FatalErrorCondition: - m_xml.scopedElement( "Fatal Error Condition" ) - .writeAttribute( "filename", assertionResult.getSourceInfo().file ) - .writeAttribute( "line", assertionResult.getSourceInfo().line ) - .writeText( assertionResult.getMessage() ); - break; - case ResultWas::Info: - m_xml.scopedElement( "Info" ) - .writeText( assertionResult.getMessage() ); - break; - case ResultWas::Warning: - // Warning will already have been written - break; - case ResultWas::ExplicitFailure: - m_xml.scopedElement( "Failure" ) - .writeText( assertionResult.getMessage() ); - break; - default: - break; - } - - if( assertionResult.hasExpression() ) - m_xml.endElement(); - - return true; - } - - virtual void sectionEnded( SectionStats const& sectionStats ) { - StreamingReporterBase::sectionEnded( sectionStats ); - if( --m_sectionDepth > 0 ) { - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); - e.writeAttribute( "successes", sectionStats.assertions.passed ); - e.writeAttribute( "failures", sectionStats.assertions.failed ); - e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); - - m_xml.endElement(); - } - } - - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) { - StreamingReporterBase::testCaseEnded( testCaseStats ); - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); - e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); - - m_xml.endElement(); - } - - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) { - StreamingReporterBase::testGroupEnded( testGroupStats ); - // TODO: Check testGroupStats.aborting and act accordingly. - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) - .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - - virtual void testRunEnded( TestRunStats const& testRunStats ) { - StreamingReporterBase::testRunEnded( testRunStats ); - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testRunStats.totals.assertions.passed ) - .writeAttribute( "failures", testRunStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - - private: - Timer m_testCaseTimer; - XmlWriter m_xml; - int m_sectionDepth; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_junit.hpp -#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED - -#include - -namespace Catch { - - class JunitReporter : public CumulativeReporterBase { - public: - JunitReporter( ReporterConfig const& _config ) - : CumulativeReporterBase( _config ), - xml( _config.stream() ) - {} - - ~JunitReporter(); - - static std::string getDescription() { - return "Reports test results in an XML format that looks like Ant's junitreport target"; - } - - virtual void noMatchingTestCases( std::string const& /*spec*/ ) {} - - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = true; - return prefs; - } - - virtual void testRunStarting( TestRunInfo const& runInfo ) { - CumulativeReporterBase::testRunStarting( runInfo ); - xml.startElement( "testsuites" ); - } - - virtual void testGroupStarting( GroupInfo const& groupInfo ) { - suiteTimer.start(); - stdOutForSuite.str(""); - stdErrForSuite.str(""); - unexpectedExceptions = 0; - CumulativeReporterBase::testGroupStarting( groupInfo ); - } - - virtual bool assertionEnded( AssertionStats const& assertionStats ) { - if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException ) - unexpectedExceptions++; - return CumulativeReporterBase::assertionEnded( assertionStats ); - } - - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) { - stdOutForSuite << testCaseStats.stdOut; - stdErrForSuite << testCaseStats.stdErr; - CumulativeReporterBase::testCaseEnded( testCaseStats ); - } - - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) { - double suiteTime = suiteTimer.getElapsedSeconds(); - CumulativeReporterBase::testGroupEnded( testGroupStats ); - writeGroup( *m_testGroups.back(), suiteTime ); - } - - virtual void testRunEndedCumulative() { - xml.endElement(); - } - - void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); - TestGroupStats const& stats = groupNode.value; - xml.writeAttribute( "name", stats.groupInfo.name ); - xml.writeAttribute( "errors", unexpectedExceptions ); - xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); - xml.writeAttribute( "tests", stats.totals.assertions.total() ); - xml.writeAttribute( "hostname", "tbd" ); // !TBD - if( m_config->showDurations() == ShowDurations::Never ) - xml.writeAttribute( "time", "" ); - else - xml.writeAttribute( "time", suiteTime ); - xml.writeAttribute( "timestamp", "tbd" ); // !TBD - - // Write test cases - for( TestGroupNode::ChildNodes::const_iterator - it = groupNode.children.begin(), itEnd = groupNode.children.end(); - it != itEnd; - ++it ) - writeTestCase( **it ); - - xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); - xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); - } - - void writeTestCase( TestCaseNode const& testCaseNode ) { - TestCaseStats const& stats = testCaseNode.value; - - // All test cases have exactly one section - which represents the - // test case itself. That section may have 0-n nested sections - assert( testCaseNode.children.size() == 1 ); - SectionNode const& rootSection = *testCaseNode.children.front(); - - std::string className = stats.testInfo.className; - - if( className.empty() ) { - if( rootSection.childSections.empty() ) - className = "global"; - } - writeSection( className, "", rootSection ); - } - - void writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { - std::string name = trim( sectionNode.stats.sectionInfo.name ); - if( !rootName.empty() ) - name = rootName + "/" + name; - - if( !sectionNode.assertions.empty() || - !sectionNode.stdOut.empty() || - !sectionNode.stdErr.empty() ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); - if( className.empty() ) { - xml.writeAttribute( "classname", name ); - xml.writeAttribute( "name", "root" ); - } - else { - xml.writeAttribute( "classname", className ); - xml.writeAttribute( "name", name ); - } - xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); - - writeAssertions( sectionNode ); - - if( !sectionNode.stdOut.empty() ) - xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); - if( !sectionNode.stdErr.empty() ) - xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); - } - for( SectionNode::ChildSections::const_iterator - it = sectionNode.childSections.begin(), - itEnd = sectionNode.childSections.end(); - it != itEnd; - ++it ) - if( className.empty() ) - writeSection( name, "", **it ); - else - writeSection( className, name, **it ); - } - - void writeAssertions( SectionNode const& sectionNode ) { - for( SectionNode::Assertions::const_iterator - it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); - it != itEnd; - ++it ) - writeAssertion( *it ); - } - void writeAssertion( AssertionStats const& stats ) { - AssertionResult const& result = stats.assertionResult; - if( !result.isOk() ) { - std::string elementName; - switch( result.getResultType() ) { - case ResultWas::ThrewException: - case ResultWas::FatalErrorCondition: - elementName = "error"; - break; - case ResultWas::ExplicitFailure: - elementName = "failure"; - break; - case ResultWas::ExpressionFailed: - elementName = "failure"; - break; - case ResultWas::DidntThrowException: - elementName = "failure"; - break; - - // We should never see these here: - case ResultWas::Info: - case ResultWas::Warning: - case ResultWas::Ok: - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - elementName = "internalError"; - break; - } - - XmlWriter::ScopedElement e = xml.scopedElement( elementName ); - - xml.writeAttribute( "message", result.getExpandedExpression() ); - xml.writeAttribute( "type", result.getTestMacroName() ); - - std::ostringstream oss; - if( !result.getMessage().empty() ) - oss << result.getMessage() << "\n"; - for( std::vector::const_iterator - it = stats.infoMessages.begin(), - itEnd = stats.infoMessages.end(); - it != itEnd; - ++it ) - if( it->type == ResultWas::Info ) - oss << it->message << "\n"; - - oss << "at " << result.getSourceInfo(); - xml.writeText( oss.str(), false ); - } - } - - XmlWriter xml; - Timer suiteTimer; - std::ostringstream stdOutForSuite; - std::ostringstream stdErrForSuite; - unsigned int unexpectedExceptions; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_console.hpp -#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED - -namespace Catch { - - struct ConsoleReporter : StreamingReporterBase { - ConsoleReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ), - m_headerPrinted( false ) - {} - - virtual ~ConsoleReporter(); - static std::string getDescription() { - return "Reports test results as plain lines of text"; - } - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = false; - return prefs; - } - - virtual void noMatchingTestCases( std::string const& spec ) { - stream << "No test cases matched '" << spec << "'" << std::endl; - } - - virtual void assertionStarting( AssertionInfo const& ) { - } - - virtual bool assertionEnded( AssertionStats const& _assertionStats ) { - AssertionResult const& result = _assertionStats.assertionResult; - - bool printInfoMessages = true; - - // Drop out if result was successful and we're not printing those - if( !m_config->includeSuccessfulResults() && result.isOk() ) { - if( result.getResultType() != ResultWas::Warning ) - return false; - printInfoMessages = false; - } - - lazyPrint(); - - AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); - printer.print(); - stream << std::endl; - return true; - } - - virtual void sectionStarting( SectionInfo const& _sectionInfo ) { - m_headerPrinted = false; - StreamingReporterBase::sectionStarting( _sectionInfo ); - } - virtual void sectionEnded( SectionStats const& _sectionStats ) { - if( _sectionStats.missingAssertions ) { - lazyPrint(); - Colour colour( Colour::ResultError ); - if( m_sectionStack.size() > 1 ) - stream << "\nNo assertions in section"; - else - stream << "\nNo assertions in test case"; - stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; - } - if( m_headerPrinted ) { - if( m_config->showDurations() == ShowDurations::Always ) - stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl; - m_headerPrinted = false; - } - else { - if( m_config->showDurations() == ShowDurations::Always ) - stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl; - } - StreamingReporterBase::sectionEnded( _sectionStats ); - } - - virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) { - StreamingReporterBase::testCaseEnded( _testCaseStats ); - m_headerPrinted = false; - } - virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) { - if( currentGroupInfo.used ) { - printSummaryDivider(); - stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; - printTotals( _testGroupStats.totals ); - stream << "\n" << std::endl; - } - StreamingReporterBase::testGroupEnded( _testGroupStats ); - } - virtual void testRunEnded( TestRunStats const& _testRunStats ) { - printTotalsDivider( _testRunStats.totals ); - printTotals( _testRunStats.totals ); - stream << std::endl; - StreamingReporterBase::testRunEnded( _testRunStats ); - } - - private: - - class AssertionPrinter { - void operator= ( AssertionPrinter const& ); - public: - AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) - : stream( _stream ), - stats( _stats ), - result( _stats.assertionResult ), - colour( Colour::None ), - message( result.getMessage() ), - messages( _stats.infoMessages ), - printInfoMessages( _printInfoMessages ) - { - switch( result.getResultType() ) { - case ResultWas::Ok: - colour = Colour::Success; - passOrFail = "PASSED"; - //if( result.hasMessage() ) - if( _stats.infoMessages.size() == 1 ) - messageLabel = "with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "with messages"; - break; - case ResultWas::ExpressionFailed: - if( result.isOk() ) { - colour = Colour::Success; - passOrFail = "FAILED - but was ok"; - } - else { - colour = Colour::Error; - passOrFail = "FAILED"; - } - if( _stats.infoMessages.size() == 1 ) - messageLabel = "with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "with messages"; - break; - case ResultWas::ThrewException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to unexpected exception with message"; - break; - case ResultWas::FatalErrorCondition: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to a fatal error condition"; - break; - case ResultWas::DidntThrowException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "because no exception was thrown where one was expected"; - break; - case ResultWas::Info: - messageLabel = "info"; - break; - case ResultWas::Warning: - messageLabel = "warning"; - break; - case ResultWas::ExplicitFailure: - passOrFail = "FAILED"; - colour = Colour::Error; - if( _stats.infoMessages.size() == 1 ) - messageLabel = "explicitly with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "explicitly with messages"; - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - passOrFail = "** internal error **"; - colour = Colour::Error; - break; - } - } - - void print() const { - printSourceInfo(); - if( stats.totals.assertions.total() > 0 ) { - if( result.isOk() ) - stream << "\n"; - printResultType(); - printOriginalExpression(); - printReconstructedExpression(); - } - else { - stream << "\n"; - } - printMessage(); - } - - private: - void printResultType() const { - if( !passOrFail.empty() ) { - Colour colourGuard( colour ); - stream << passOrFail << ":\n"; - } - } - void printOriginalExpression() const { - if( result.hasExpression() ) { - Colour colourGuard( Colour::OriginalExpression ); - stream << " "; - stream << result.getExpressionInMacro(); - stream << "\n"; - } - } - void printReconstructedExpression() const { - if( result.hasExpandedExpression() ) { - stream << "with expansion:\n"; - Colour colourGuard( Colour::ReconstructedExpression ); - stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n"; - } - } - void printMessage() const { - if( !messageLabel.empty() ) - stream << messageLabel << ":" << "\n"; - for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); - it != itEnd; - ++it ) { - // If this assertion is a warning ignore any INFO messages - if( printInfoMessages || it->type != ResultWas::Info ) - stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n"; - } - } - void printSourceInfo() const { - Colour colourGuard( Colour::FileName ); - stream << result.getSourceInfo() << ": "; - } - - std::ostream& stream; - AssertionStats const& stats; - AssertionResult const& result; - Colour::Code colour; - std::string passOrFail; - std::string messageLabel; - std::string message; - std::vector messages; - bool printInfoMessages; - }; - - void lazyPrint() { - - if( !currentTestRunInfo.used ) - lazyPrintRunInfo(); - if( !currentGroupInfo.used ) - lazyPrintGroupInfo(); - - if( !m_headerPrinted ) { - printTestCaseAndSectionHeader(); - m_headerPrinted = true; - } - } - void lazyPrintRunInfo() { - stream << "\n" << getLineOfChars<'~'>() << "\n"; - Colour colour( Colour::SecondaryText ); - stream << currentTestRunInfo->name - << " is a Catch v" << libraryVersion.majorVersion << "." - << libraryVersion.minorVersion << " b" - << libraryVersion.buildNumber; - if( libraryVersion.branchName != std::string( "master" ) ) - stream << " (" << libraryVersion.branchName << ")"; - stream << " host application.\n" - << "Run with -? for options\n\n"; - - if( m_config->rngSeed() != 0 ) - stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; - - currentTestRunInfo.used = true; - } - void lazyPrintGroupInfo() { - if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { - printClosedHeader( "Group: " + currentGroupInfo->name ); - currentGroupInfo.used = true; - } - } - void printTestCaseAndSectionHeader() { - assert( !m_sectionStack.empty() ); - printOpenHeader( currentTestCaseInfo->name ); - - if( m_sectionStack.size() > 1 ) { - Colour colourGuard( Colour::Headers ); - - std::vector::const_iterator - it = m_sectionStack.begin()+1, // Skip first section (test case) - itEnd = m_sectionStack.end(); - for( ; it != itEnd; ++it ) - printHeaderString( it->name, 2 ); - } - - SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; - - if( !lineInfo.empty() ){ - stream << getLineOfChars<'-'>() << "\n"; - Colour colourGuard( Colour::FileName ); - stream << lineInfo << "\n"; - } - stream << getLineOfChars<'.'>() << "\n" << std::endl; - } - - void printClosedHeader( std::string const& _name ) { - printOpenHeader( _name ); - stream << getLineOfChars<'.'>() << "\n"; - } - void printOpenHeader( std::string const& _name ) { - stream << getLineOfChars<'-'>() << "\n"; - { - Colour colourGuard( Colour::Headers ); - printHeaderString( _name ); - } - } - - // if string has a : in first line will set indent to follow it on - // subsequent lines - void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { - std::size_t i = _string.find( ": " ); - if( i != std::string::npos ) - i+=2; - else - i = 0; - stream << Text( _string, TextAttributes() - .setIndent( indent+i) - .setInitialIndent( indent ) ) << "\n"; - } - - struct SummaryColumn { - - SummaryColumn( std::string const& _label, Colour::Code _colour ) - : label( _label ), - colour( _colour ) - {} - SummaryColumn addRow( std::size_t count ) { - std::ostringstream oss; - oss << count; - std::string row = oss.str(); - for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { - while( it->size() < row.size() ) - *it = " " + *it; - while( it->size() > row.size() ) - row = " " + row; - } - rows.push_back( row ); - return *this; - } - - std::string label; - Colour::Code colour; - std::vector rows; - - }; - - void printTotals( Totals const& totals ) { - if( totals.testCases.total() == 0 ) { - stream << Colour( Colour::Warning ) << "No tests ran\n"; - } - else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) { - stream << Colour( Colour::ResultSuccess ) << "All tests passed"; - stream << " (" - << pluralise( totals.assertions.passed, "assertion" ) << " in " - << pluralise( totals.testCases.passed, "test case" ) << ")" - << "\n"; - } - else { - - std::vector columns; - columns.push_back( SummaryColumn( "", Colour::None ) - .addRow( totals.testCases.total() ) - .addRow( totals.assertions.total() ) ); - columns.push_back( SummaryColumn( "passed", Colour::Success ) - .addRow( totals.testCases.passed ) - .addRow( totals.assertions.passed ) ); - columns.push_back( SummaryColumn( "failed", Colour::ResultError ) - .addRow( totals.testCases.failed ) - .addRow( totals.assertions.failed ) ); - columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) - .addRow( totals.testCases.failedButOk ) - .addRow( totals.assertions.failedButOk ) ); - - printSummaryRow( "test cases", columns, 0 ); - printSummaryRow( "assertions", columns, 1 ); - } - } - void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { - for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { - std::string value = it->rows[row]; - if( it->label.empty() ) { - stream << label << ": "; - if( value != "0" ) - stream << value; - else - stream << Colour( Colour::Warning ) << "- none -"; - } - else if( value != "0" ) { - stream << Colour( Colour::LightGrey ) << " | "; - stream << Colour( it->colour ) - << value << " " << it->label; - } - } - stream << "\n"; - } - - static std::size_t makeRatio( std::size_t number, std::size_t total ) { - std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; - return ( ratio == 0 && number > 0 ) ? 1 : ratio; - } - static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { - if( i > j && i > k ) - return i; - else if( j > k ) - return j; - else - return k; - } - - void printTotalsDivider( Totals const& totals ) { - if( totals.testCases.total() > 0 ) { - std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); - std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); - std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); - while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) - findMax( failedRatio, failedButOkRatio, passedRatio )++; - while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) - findMax( failedRatio, failedButOkRatio, passedRatio )--; - - stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); - stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); - if( totals.testCases.allPassed() ) - stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); - else - stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); - } - else { - stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); - } - stream << "\n"; - } - void printSummaryDivider() { - stream << getLineOfChars<'-'>() << "\n"; - } - - private: - bool m_headerPrinted; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_compact.hpp -#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED - -namespace Catch { - - struct CompactReporter : StreamingReporterBase { - - CompactReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ) - {} - - virtual ~CompactReporter(); - - static std::string getDescription() { - return "Reports test results on a single line, suitable for IDEs"; - } - - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = false; - return prefs; - } - - virtual void noMatchingTestCases( std::string const& spec ) { - stream << "No test cases matched '" << spec << "'" << std::endl; - } - - virtual void assertionStarting( AssertionInfo const& ) { - } - - virtual bool assertionEnded( AssertionStats const& _assertionStats ) { - AssertionResult const& result = _assertionStats.assertionResult; - - bool printInfoMessages = true; - - // Drop out if result was successful and we're not printing those - if( !m_config->includeSuccessfulResults() && result.isOk() ) { - if( result.getResultType() != ResultWas::Warning ) - return false; - printInfoMessages = false; - } - - AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); - printer.print(); - - stream << std::endl; - return true; - } - - virtual void testRunEnded( TestRunStats const& _testRunStats ) { - printTotals( _testRunStats.totals ); - stream << "\n" << std::endl; - StreamingReporterBase::testRunEnded( _testRunStats ); - } - - private: - class AssertionPrinter { - void operator= ( AssertionPrinter const& ); - public: - AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) - : stream( _stream ) - , stats( _stats ) - , result( _stats.assertionResult ) - , messages( _stats.infoMessages ) - , itMessage( _stats.infoMessages.begin() ) - , printInfoMessages( _printInfoMessages ) - {} - - void print() { - printSourceInfo(); - - itMessage = messages.begin(); - - switch( result.getResultType() ) { - case ResultWas::Ok: - printResultType( Colour::ResultSuccess, passedString() ); - printOriginalExpression(); - printReconstructedExpression(); - if ( ! result.hasExpression() ) - printRemainingMessages( Colour::None ); - else - printRemainingMessages(); - break; - case ResultWas::ExpressionFailed: - if( result.isOk() ) - printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); - else - printResultType( Colour::Error, failedString() ); - printOriginalExpression(); - printReconstructedExpression(); - printRemainingMessages(); - break; - case ResultWas::ThrewException: - printResultType( Colour::Error, failedString() ); - printIssue( "unexpected exception with message:" ); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::FatalErrorCondition: - printResultType( Colour::Error, failedString() ); - printIssue( "fatal error condition with message:" ); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::DidntThrowException: - printResultType( Colour::Error, failedString() ); - printIssue( "expected exception, got none" ); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::Info: - printResultType( Colour::None, "info" ); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::Warning: - printResultType( Colour::None, "warning" ); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::ExplicitFailure: - printResultType( Colour::Error, failedString() ); - printIssue( "explicitly" ); - printRemainingMessages( Colour::None ); - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - printResultType( Colour::Error, "** internal error **" ); - break; - } - } - - private: - // Colour::LightGrey - - static Colour::Code dimColour() { return Colour::FileName; } - -#ifdef CATCH_PLATFORM_MAC - static const char* failedString() { return "FAILED"; } - static const char* passedString() { return "PASSED"; } -#else - static const char* failedString() { return "failed"; } - static const char* passedString() { return "passed"; } -#endif - - void printSourceInfo() const { - Colour colourGuard( Colour::FileName ); - stream << result.getSourceInfo() << ":"; - } - - void printResultType( Colour::Code colour, std::string passOrFail ) const { - if( !passOrFail.empty() ) { - { - Colour colourGuard( colour ); - stream << " " << passOrFail; - } - stream << ":"; - } - } - - void printIssue( std::string issue ) const { - stream << " " << issue; - } - - void printExpressionWas() { - if( result.hasExpression() ) { - stream << ";"; - { - Colour colour( dimColour() ); - stream << " expression was:"; - } - printOriginalExpression(); - } - } - - void printOriginalExpression() const { - if( result.hasExpression() ) { - stream << " " << result.getExpression(); - } - } - - void printReconstructedExpression() const { - if( result.hasExpandedExpression() ) { - { - Colour colour( dimColour() ); - stream << " for: "; - } - stream << result.getExpandedExpression(); - } - } - - void printMessage() { - if ( itMessage != messages.end() ) { - stream << " '" << itMessage->message << "'"; - ++itMessage; - } - } - - void printRemainingMessages( Colour::Code colour = dimColour() ) { - if ( itMessage == messages.end() ) - return; - - // using messages.end() directly yields compilation error: - std::vector::const_iterator itEnd = messages.end(); - const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); - - { - Colour colourGuard( colour ); - stream << " with " << pluralise( N, "message" ) << ":"; - } - - for(; itMessage != itEnd; ) { - // If this assertion is a warning ignore any INFO messages - if( printInfoMessages || itMessage->type != ResultWas::Info ) { - stream << " '" << itMessage->message << "'"; - if ( ++itMessage != itEnd ) { - Colour colourGuard( dimColour() ); - stream << " and"; - } - } - } - } - - private: - std::ostream& stream; - AssertionStats const& stats; - AssertionResult const& result; - std::vector messages; - std::vector::const_iterator itMessage; - bool printInfoMessages; - }; - - // Colour, message variants: - // - white: No tests ran. - // - red: Failed [both/all] N test cases, failed [both/all] M assertions. - // - white: Passed [both/all] N test cases (no assertions). - // - red: Failed N tests cases, failed M assertions. - // - green: Passed [both/all] N tests cases with M assertions. - - std::string bothOrAll( std::size_t count ) const { - return count == 1 ? "" : count == 2 ? "both " : "all " ; - } - - void printTotals( const Totals& totals ) const { - if( totals.testCases.total() == 0 ) { - stream << "No tests ran."; - } - else if( totals.testCases.failed == totals.testCases.total() ) { - Colour colour( Colour::ResultError ); - const std::string qualify_assertions_failed = - totals.assertions.failed == totals.assertions.total() ? - bothOrAll( totals.assertions.failed ) : ""; - stream << - "Failed " << bothOrAll( totals.testCases.failed ) - << pluralise( totals.testCases.failed, "test case" ) << ", " - "failed " << qualify_assertions_failed << - pluralise( totals.assertions.failed, "assertion" ) << "."; - } - else if( totals.assertions.total() == 0 ) { - stream << - "Passed " << bothOrAll( totals.testCases.total() ) - << pluralise( totals.testCases.total(), "test case" ) - << " (no assertions)."; - } - else if( totals.assertions.failed ) { - Colour colour( Colour::ResultError ); - stream << - "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " - "failed " << pluralise( totals.assertions.failed, "assertion" ) << "."; - } - else { - Colour colour( Colour::ResultSuccess ); - stream << - "Passed " << bothOrAll( totals.testCases.passed ) - << pluralise( totals.testCases.passed, "test case" ) << - " with " << pluralise( totals.assertions.passed, "assertion" ) << "."; - } - } - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) - -} // end namespace Catch - -namespace Catch { - NonCopyable::~NonCopyable() {} - IShared::~IShared() {} - StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} - IContext::~IContext() {} - IResultCapture::~IResultCapture() {} - ITestCase::~ITestCase() {} - ITestCaseRegistry::~ITestCaseRegistry() {} - IRegistryHub::~IRegistryHub() {} - IMutableRegistryHub::~IMutableRegistryHub() {} - IExceptionTranslator::~IExceptionTranslator() {} - IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} - IReporter::~IReporter() {} - IReporterFactory::~IReporterFactory() {} - IReporterRegistry::~IReporterRegistry() {} - IStreamingReporter::~IStreamingReporter() {} - AssertionStats::~AssertionStats() {} - SectionStats::~SectionStats() {} - TestCaseStats::~TestCaseStats() {} - TestGroupStats::~TestGroupStats() {} - TestRunStats::~TestRunStats() {} - CumulativeReporterBase::SectionNode::~SectionNode() {} - CumulativeReporterBase::~CumulativeReporterBase() {} - - StreamingReporterBase::~StreamingReporterBase() {} - ConsoleReporter::~ConsoleReporter() {} - CompactReporter::~CompactReporter() {} - IRunner::~IRunner() {} - IMutableContext::~IMutableContext() {} - IConfig::~IConfig() {} - XmlReporter::~XmlReporter() {} - JunitReporter::~JunitReporter() {} - TestRegistry::~TestRegistry() {} - FreeFunctionTestCase::~FreeFunctionTestCase() {} - IGeneratorInfo::~IGeneratorInfo() {} - IGeneratorsForTest::~IGeneratorsForTest() {} - TestSpec::Pattern::~Pattern() {} - TestSpec::NamePattern::~NamePattern() {} - TestSpec::TagPattern::~TagPattern() {} - TestSpec::ExcludedPattern::~ExcludedPattern() {} - - Matchers::Impl::StdString::Equals::~Equals() {} - Matchers::Impl::StdString::Contains::~Contains() {} - Matchers::Impl::StdString::StartsWith::~StartsWith() {} - Matchers::Impl::StdString::EndsWith::~EndsWith() {} - - void Config::dummy() {} -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#endif - -#ifdef CATCH_CONFIG_MAIN -// #included from: internal/catch_default_main.hpp -#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED - -#ifndef __OBJC__ - -// Standard C/C++ main entry point -int main (int argc, char * const argv[]) { - return Catch::Session().run( argc, argv ); -} - -#else // __OBJC__ - -// Objective-C entry point -int main (int argc, char * const argv[]) { -#if !CATCH_ARC_ENABLED - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; -#endif - - Catch::registerTestMethods(); - int result = Catch::Session().run( argc, (char* const*)argv ); - -#if !CATCH_ARC_ENABLED - [pool drain]; -#endif - - return result; -} - -#endif // __OBJC__ - -#endif - -#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED -# undef CLARA_CONFIG_MAIN -#endif - -////// - -// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ -#ifdef CATCH_CONFIG_PREFIX_ALL - -#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) -#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) - -#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" ) -#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) -#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) - -#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) -#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) -#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) -#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) -#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) - -#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" ) -#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) -#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) - -#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) -#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) - -#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) -#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) -#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) -#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) -#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) - #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) - #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) - #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) - #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) - #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) -#else - #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) - #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) - #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) - #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) - #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) - #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) -#endif -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) - -#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) -#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) - -#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) - -// "BDD-style" convenience wrappers -#ifdef CATCH_CONFIG_VARIADIC_MACROS -#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) -#else -#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) -#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) -#endif -#define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" ) -#define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" ) -#define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" ) -#define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" ) -#define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" ) - -// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required -#else - -#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) -#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) - -#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" ) -#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) -#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) - -#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) -#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) -#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) -#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) -#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) - -#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" ) -#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) -#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) - -#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) -#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) - -#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) -#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) -#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) -#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) -#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) - #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) - #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) - #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) - #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) - #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) -#else - #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) - #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) - #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) - #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) - #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) - #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) -#endif -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) - -#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) -#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) - -#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) - -#endif - -#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) - -// "BDD-style" convenience wrappers -#ifdef CATCH_CONFIG_VARIADIC_MACROS -#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) -#else -#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) -#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) -#endif -#define GIVEN( desc ) SECTION( " Given: " desc, "" ) -#define WHEN( desc ) SECTION( " When: " desc, "" ) -#define AND_WHEN( desc ) SECTION( "And when: " desc, "" ) -#define THEN( desc ) SECTION( " Then: " desc, "" ) -#define AND_THEN( desc ) SECTION( " And: " desc, "" ) - -using Catch::Detail::Approx; - -// #included from: internal/catch_reenable_warnings.h - -#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(pop) -# else -# pragma clang diagnostic pop -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic pop -#endif - -#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED - diff --git a/fpga/thirdparty/spdlog/tests/catch.license b/fpga/thirdparty/spdlog/tests/catch.license deleted file mode 100644 index 127a5bc39..000000000 --- a/fpga/thirdparty/spdlog/tests/catch.license +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/fpga/thirdparty/spdlog/tests/errors.cpp b/fpga/thirdparty/spdlog/tests/errors.cpp deleted file mode 100644 index c8281d632..000000000 --- a/fpga/thirdparty/spdlog/tests/errors.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE -*/ -#include "includes.h" - -#include - - - - -class failing_sink: public spdlog::sinks::sink -{ - void log(const spdlog::details::log_msg& msg) override - { - throw std::runtime_error("some error happened during log"); - } - - void flush() override - {} -}; - -TEST_CASE("default_error_handler", "[errors]]") -{ - prepare_logdir(); - std::string filename = "logs/simple_log.txt"; - - auto logger = spdlog::create("logger", filename, true); - logger->set_pattern("%v"); -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {} {}", 1); - logger->info("Test message {}", 2); -#else - logger->info("Test message %d %d", 1); - logger->info("Test message %d", 2); -#endif - logger->flush(); - - REQUIRE(file_contents(filename) == std::string("Test message 2\n")); - REQUIRE(count_lines(filename) == 1); -} - - - - -struct custom_ex -{}; -TEST_CASE("custom_error_handler", "[errors]]") -{ - prepare_logdir(); - std::string filename = "logs/simple_log.txt"; - auto logger = spdlog::create("logger", filename, true); - logger->flush_on(spdlog::level::info); - logger->set_error_handler([=](const std::string& msg) - { - throw custom_ex(); - }); - logger->info("Good message #1"); -#if !defined(SPDLOG_FMT_PRINTF) - REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex); -#else - REQUIRE_THROWS_AS(logger->info("Bad format msg %s %s", "xxx"), custom_ex); -#endif - logger->info("Good message #2"); - REQUIRE(count_lines(filename) == 2); -} - -TEST_CASE("default_error_handler2", "[errors]]") -{ - - auto logger = spdlog::create("failed_logger"); - logger->set_error_handler([=](const std::string& msg) - { - throw custom_ex(); - }); - REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex); -} - -TEST_CASE("async_error_handler", "[errors]]") -{ - prepare_logdir(); - std::string err_msg("log failed with some msg"); - spdlog::set_async_mode(128); - std::string filename = "logs/simple_async_log.txt"; - { - auto logger = spdlog::create("logger", filename, true); - logger->set_error_handler([=](const std::string& msg) - { - std::ofstream ofs("logs/custom_err.txt"); - if (!ofs) throw std::runtime_error("Failed open logs/custom_err.txt"); - ofs << err_msg; - }); - logger->info("Good message #1"); -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Bad format msg {} {}", "xxx"); -#else - logger->info("Bad format msg %s %s", "xxx"); -#endif - logger->info("Good message #2"); - spdlog::drop("logger"); //force logger to drain the queue and shutdown - spdlog::set_sync_mode(); - } - REQUIRE(count_lines(filename) == 2); - REQUIRE(file_contents("logs/custom_err.txt") == err_msg); -} - -// Make sure async error handler is executed -TEST_CASE("async_error_handler2", "[errors]]") -{ - prepare_logdir(); - std::string err_msg("This is async handler error message"); - spdlog::set_async_mode(128); - { - auto logger = spdlog::create("failed_logger"); - logger->set_error_handler([=](const std::string& msg) - { - std::ofstream ofs("logs/custom_err2.txt"); - if (!ofs) throw std::runtime_error("Failed open logs/custom_err2.txt"); - ofs << err_msg; - }); - logger->info("Hello failure"); - spdlog::drop("failed_logger"); //force logger to drain the queue and shutdown - spdlog::set_sync_mode(); - } - - REQUIRE(file_contents("logs/custom_err2.txt") == err_msg); -} diff --git a/fpga/thirdparty/spdlog/tests/file_helper.cpp b/fpga/thirdparty/spdlog/tests/file_helper.cpp deleted file mode 100644 index d127c8f06..000000000 --- a/fpga/thirdparty/spdlog/tests/file_helper.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* -* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE -*/ -#include "includes.h" - -using namespace spdlog::details; - -static const std::string target_filename = "logs/file_helper_test.txt"; - -static void write_with_helper(file_helper &helper, size_t howmany) -{ - log_msg msg; - msg.formatted << std::string(howmany, '1'); - helper.write(msg); - helper.flush(); -} - - -TEST_CASE("file_helper_filename", "[file_helper::filename()]]") -{ - prepare_logdir(); - - file_helper helper; - helper.open(target_filename); - REQUIRE(helper.filename() == target_filename); -} - - - -TEST_CASE("file_helper_size", "[file_helper::size()]]") -{ - prepare_logdir(); - size_t expected_size = 123; - { - file_helper helper; - helper.open(target_filename); - write_with_helper(helper, expected_size); - REQUIRE(static_cast(helper.size()) == 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()]]") -{ - prepare_logdir(); - file_helper helper; - helper.open(target_filename); - write_with_helper(helper, 12); - REQUIRE(helper.size() == 12); - helper.reopen(true); - REQUIRE(helper.size() == 0); -} - -TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]") -{ - prepare_logdir(); - size_t expected_size = 14; - file_helper helper; - helper.open(target_filename); - write_with_helper(helper, expected_size); - REQUIRE(helper.size() == expected_size); - helper.reopen(false); - REQUIRE(helper.size() == expected_size); -} - - - -static void test_split_ext(const char* fname, const char* expect_base, const char* expect_ext) -{ - spdlog::filename_t filename(fname); - spdlog::filename_t expected_base(expect_base); - spdlog::filename_t expected_ext(expect_ext); - -#ifdef _WIN32 // replace folder sep - std::replace(filename.begin(), filename.end(), '/', '\\'); - std::replace(expected_base.begin(), expected_base.end(), '/', '\\'); -#endif - spdlog::filename_t basename, ext; - std::tie(basename, ext) = file_helper::split_by_extenstion(filename); - REQUIRE(basename == expected_base); - REQUIRE(ext == expected_ext); -} - - -TEST_CASE("file_helper_split_by_extenstion", "[file_helper::split_by_extenstion()]]") -{ - test_split_ext("mylog.txt", "mylog", ".txt"); - test_split_ext(".mylog.txt", ".mylog", ".txt"); - test_split_ext(".mylog", ".mylog", ""); - test_split_ext("/aaa/bb.d/mylog", "/aaa/bb.d/mylog", ""); - test_split_ext("/aaa/bb.d/mylog.txt", "/aaa/bb.d/mylog", ".txt"); - test_split_ext("aaa/bbb/ccc/mylog.txt", "aaa/bbb/ccc/mylog", ".txt"); - test_split_ext("aaa/bbb/ccc/mylog.", "aaa/bbb/ccc/mylog.", ""); - test_split_ext("aaa/bbb/ccc/.mylog.txt", "aaa/bbb/ccc/.mylog", ".txt"); - test_split_ext("/aaa/bbb/ccc/mylog.txt", "/aaa/bbb/ccc/mylog", ".txt"); - test_split_ext("/aaa/bbb/ccc/.mylog", "/aaa/bbb/ccc/.mylog", ""); - test_split_ext("../mylog.txt", "../mylog", ".txt"); - test_split_ext(".././mylog.txt", ".././mylog", ".txt"); - test_split_ext(".././mylog.txt/xxx", ".././mylog.txt/xxx", ""); - test_split_ext("/mylog.txt", "/mylog", ".txt"); - test_split_ext("//mylog.txt", "//mylog", ".txt"); - test_split_ext("", "", ""); - test_split_ext(".", ".", ""); - test_split_ext("..txt", ".", ".txt"); -} - - - diff --git a/fpga/thirdparty/spdlog/tests/file_log.cpp b/fpga/thirdparty/spdlog/tests/file_log.cpp deleted file mode 100644 index 086bd5ed4..000000000 --- a/fpga/thirdparty/spdlog/tests/file_log.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE - */ -#include "includes.h" - - -TEST_CASE("simple_file_logger", "[simple_logger]]") -{ - prepare_logdir(); - std::string filename = "logs/simple_log"; - - auto logger = spdlog::create("logger", filename); - logger->set_pattern("%v"); - -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {}", 1); - logger->info("Test message {}", 2); -#else - logger->info("Test message %d", 1); - logger->info("Test message %d", 2); -#endif - logger->flush(); - REQUIRE(file_contents(filename) == std::string("Test message 1\nTest message 2\n")); - REQUIRE(count_lines(filename) == 2); -} - - -TEST_CASE("flush_on", "[flush_on]]") -{ - prepare_logdir(); - std::string filename = "logs/simple_log"; - - auto logger = spdlog::create("logger", filename); - logger->set_pattern("%v"); - logger->set_level(spdlog::level::trace); - logger->flush_on(spdlog::level::info); - logger->trace("Should not be flushed"); - REQUIRE(count_lines(filename) == 0); - -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {}", 1); - logger->info("Test message {}", 2); -#else - logger->info("Test message %d", 1); - logger->info("Test message %d", 2); -#endif - logger->flush(); - REQUIRE(file_contents(filename) == std::string("Should not be flushed\nTest message 1\nTest message 2\n")); - REQUIRE(count_lines(filename) == 3); -} - -TEST_CASE("rotating_file_logger1", "[rotating_logger]]") -{ - prepare_logdir(); - std::string basename = "logs/rotating_log"; - auto logger = spdlog::rotating_logger_mt("logger", basename, 1024, 0); - - for (int i = 0; i < 10; ++i) - { -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {}", i); -#else - logger->info("Test message %d", i); -#endif - } - - logger->flush(); - auto filename = basename; - REQUIRE(count_lines(filename) == 10); -} - - -TEST_CASE("rotating_file_logger2", "[rotating_logger]]") -{ - prepare_logdir(); - std::string basename = "logs/rotating_log"; - auto logger = spdlog::rotating_logger_mt("logger", basename, 1024, 1); - for (int i = 0; i < 10; ++i) - logger->info("Test message {}", i); - - logger->flush(); - auto filename = basename; - REQUIRE(count_lines(filename) == 10); - for (int i = 0; i < 1000; i++) - { -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {}", i); -#else - logger->info("Test message %d", i); -#endif - } - - logger->flush(); - REQUIRE(get_filesize(filename) <= 1024); - auto filename1 = basename + ".1"; - REQUIRE(get_filesize(filename1) <= 1024); -} - - -TEST_CASE("daily_logger", "[daily_logger]]") -{ - prepare_logdir(); - //calculate filename (time based) - std::string basename = "logs/daily_log"; - std::tm tm = spdlog::details::os::localtime(); - fmt::MemoryWriter w; - w.write("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min); - - auto logger = spdlog::daily_logger_mt("logger", basename, 0, 0); - logger->flush_on(spdlog::level::info); - for (int i = 0; i < 10; ++i) - { -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {}", i); -#else - logger->info("Test message %d", i); -#endif - } - - auto filename = w.str(); - REQUIRE(count_lines(filename) == 10); -} - - -TEST_CASE("daily_logger with dateonly calculator", "[daily_logger_dateonly]]") -{ - using sink_type = spdlog::sinks::daily_file_sink< - std::mutex, - spdlog::sinks::dateonly_daily_file_name_calculator>; - - prepare_logdir(); - //calculate filename (time based) - std::string basename = "logs/daily_dateonly"; - std::tm tm = spdlog::details::os::localtime(); - fmt::MemoryWriter w; - w.write("{}_{:04d}-{:02d}-{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - - auto logger = spdlog::create("logger", basename, 0, 0); - for (int i = 0; i < 10; ++i) - { -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {}", i); -#else - logger->info("Test message %d", i); -#endif - } - logger->flush(); - auto filename = w.str(); - REQUIRE(count_lines(filename) == 10); -} - -struct custom_daily_file_name_calculator -{ - static spdlog::filename_t calc_filename(const spdlog::filename_t& basename) - { - std::tm tm = spdlog::details::os::localtime(); - fmt::MemoryWriter w; - w.write("{}{:04d}{:02d}{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - return w.str(); - } -}; - -TEST_CASE("daily_logger with custom calculator", "[daily_logger_custom]]") -{ - using sink_type = spdlog::sinks::daily_file_sink< - std::mutex, - custom_daily_file_name_calculator>; - - prepare_logdir(); - //calculate filename (time based) - std::string basename = "logs/daily_dateonly"; - std::tm tm = spdlog::details::os::localtime(); - fmt::MemoryWriter w; - w.write("{}{:04d}{:02d}{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - - auto logger = spdlog::create("logger", basename, 0, 0); - for (int i = 0; i < 10; ++i) - { -#if !defined(SPDLOG_FMT_PRINTF) - logger->info("Test message {}", i); -#else - logger->info("Test message %d", i); -#endif - } - - logger->flush(); - auto filename = w.str(); - REQUIRE(count_lines(filename) == 10); -} - - -/* - * File name calculations - */ - -TEST_CASE("rotating_file_sink::calc_filename1", "[rotating_file_sink]]") -{ - auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename("rotated.txt", 3); - REQUIRE(filename == "rotated.3.txt"); -} - -TEST_CASE("rotating_file_sink::calc_filename2", "[rotating_file_sink]]") -{ - auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename("rotated", 3); - REQUIRE(filename == "rotated.3"); -} - -TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]]") -{ - auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename("rotated.txt", 0); - REQUIRE(filename == "rotated.txt"); -} - - - - - -// regex supported only from gcc 4.9 and above -#if defined (_MSC_VER) || !(__GNUC__ <= 4 && __GNUC_MINOR__ < 9) -#include -TEST_CASE("daily_file_sink::default_daily_file_name_calculator1", "[daily_file_sink]]") -{ - // daily_YYYY-MM-DD_hh-mm.txt - auto filename = spdlog::sinks::default_daily_file_name_calculator::calc_filename("daily.txt"); - std::regex re(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])_\d\d-[0-5][0-9].txt$)"); - std::smatch match; - REQUIRE(std::regex_match(filename, match, re)); -} - -TEST_CASE("daily_file_sink::default_daily_file_name_calculator2", "[daily_file_sink]]") -{ - // daily_YYYY-MM-DD_hh-mm.txt - auto filename = spdlog::sinks::default_daily_file_name_calculator::calc_filename("daily"); - std::regex re(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])_\d\d-[0-5][0-9]$)"); - std::smatch match; - REQUIRE(std::regex_match(filename, match, re)); -} - -TEST_CASE("daily_file_sink::dateonly_daily_file_name_calculator", "[daily_file_sink]]") -{ - // daily_YYYY-MM-DD_hh-mm.txt - auto filename = spdlog::sinks::dateonly_daily_file_name_calculator::calc_filename("daily.txt"); - // date regex based on https://www.regular-expressions.info/dates.html - std::regex re(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])\.txt$)"); - std::smatch match; - REQUIRE(std::regex_match(filename, match, re)); -} -#endif diff --git a/fpga/thirdparty/spdlog/tests/format.cpp b/fpga/thirdparty/spdlog/tests/format.cpp deleted file mode 100644 index adb8ba8be..000000000 --- a/fpga/thirdparty/spdlog/tests/format.cpp +++ /dev/null @@ -1,56 +0,0 @@ - -#include "includes.h" - -template -std::string log_info(const T& what, spdlog::level::level_enum logger_level = spdlog::level::info) -{ - - std::ostringstream oss; - auto oss_sink = std::make_shared(oss); - - spdlog::logger oss_logger("oss", oss_sink); - oss_logger.set_level(logger_level); - oss_logger.set_pattern("%v"); - oss_logger.info(what); - - return oss.str().substr(0, oss.str().length() - spdlog::details::os::eol_size); -} - - - - - - -TEST_CASE("basic_logging ", "[basic_logging]") -{ - //const char - REQUIRE(log_info("Hello") == "Hello"); - REQUIRE(log_info("") == ""); - - //std::string - REQUIRE(log_info(std::string("Hello")) == "Hello"); - REQUIRE(log_info(std::string()) == std::string()); - - //Numbers - REQUIRE(log_info(5) == "5"); - REQUIRE(log_info(5.6) == "5.6"); - - //User defined class - //REQUIRE(log_info(some_logged_class("some_val")) == "some_val"); -} - - -TEST_CASE("log_levels", "[log_levels]") -{ - REQUIRE(log_info("Hello", spdlog::level::err) == ""); - REQUIRE(log_info("Hello", spdlog::level::critical) == ""); - REQUIRE(log_info("Hello", spdlog::level::info) == "Hello"); - REQUIRE(log_info("Hello", spdlog::level::debug) == "Hello"); - REQUIRE(log_info("Hello", spdlog::level::trace) == "Hello"); -} - - - - - - diff --git a/fpga/thirdparty/spdlog/tests/includes.h b/fpga/thirdparty/spdlog/tests/includes.h deleted file mode 100644 index 8e70efad9..000000000 --- a/fpga/thirdparty/spdlog/tests/includes.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "catch.hpp" -#include "utils.h" - -#define SPDLOG_TRACE_ON -#define SPDLOG_DEBUG_ON - -#include "../include/spdlog/spdlog.h" -#include "../include/spdlog/sinks/null_sink.h" -#include "../include/spdlog/sinks/ostream_sink.h" - diff --git a/fpga/thirdparty/spdlog/tests/install_libcxx.sh b/fpga/thirdparty/spdlog/tests/install_libcxx.sh deleted file mode 100755 index cee976928..000000000 --- a/fpga/thirdparty/spdlog/tests/install_libcxx.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# -# Install libc++ under travis - -svn --quiet co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx -mkdir libcxx/build -(cd libcxx/build && cmake .. -DLIBCXX_CXX_ABI=libstdc++ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.6;/usr/include/c++/4.6/x86_64-linux-gnu") -make -C libcxx/build cxx -j2 -sudo cp libcxx/build/lib/libc++.so.1.0 /usr/lib/ -sudo cp -r libcxx/build/include/c++/v1 /usr/include/c++/v1/ -sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so -sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so.1 diff --git a/fpga/thirdparty/spdlog/tests/main.cpp b/fpga/thirdparty/spdlog/tests/main.cpp deleted file mode 100644 index 063e87874..000000000 --- a/fpga/thirdparty/spdlog/tests/main.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#define CATCH_CONFIG_MAIN -#include "catch.hpp" \ No newline at end of file diff --git a/fpga/thirdparty/spdlog/tests/registry.cpp b/fpga/thirdparty/spdlog/tests/registry.cpp deleted file mode 100644 index 1936932ae..000000000 --- a/fpga/thirdparty/spdlog/tests/registry.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "includes.h" - -static const char *tested_logger_name = "null_logger"; -static const char *tested_logger_name2 = "null_logger2"; - -TEST_CASE("register_drop", "[registry]") -{ - spdlog::drop_all(); - spdlog::create(tested_logger_name); - REQUIRE(spdlog::get(tested_logger_name)!=nullptr); - //Throw if registring existing name - REQUIRE_THROWS_AS(spdlog::create(tested_logger_name), spdlog::spdlog_ex); -} - - -TEST_CASE("explicit register" "[registry]") -{ - spdlog::drop_all(); - auto logger = std::make_shared(tested_logger_name, std::make_shared()); - spdlog::register_logger(logger); - REQUIRE(spdlog::get(tested_logger_name) != nullptr); - //Throw if registring existing name - REQUIRE_THROWS_AS(spdlog::create(tested_logger_name), spdlog::spdlog_ex); -} - -TEST_CASE("apply_all" "[registry]") -{ - spdlog::drop_all(); - auto logger = std::make_shared(tested_logger_name, std::make_shared()); - spdlog::register_logger(logger); - auto logger2 = std::make_shared(tested_logger_name2, std::make_shared()); - spdlog::register_logger(logger2); - - int counter = 0; - spdlog::apply_all([&counter](std::shared_ptr l) - { - counter++; - }); - REQUIRE(counter == 2); - - counter = 0; - spdlog::drop(tested_logger_name2); - spdlog::apply_all([&counter](std::shared_ptr l) - { - REQUIRE(l->name() == tested_logger_name); - counter++; - } - ); - REQUIRE(counter == 1); -} - - - -TEST_CASE("drop" "[registry]") -{ - spdlog::drop_all(); - spdlog::create(tested_logger_name); - spdlog::drop(tested_logger_name); - REQUIRE_FALSE(spdlog::get(tested_logger_name)); -} - -TEST_CASE("drop_all" "[registry]") -{ - spdlog::drop_all(); - spdlog::create(tested_logger_name); - spdlog::create(tested_logger_name2); - spdlog::drop_all(); - REQUIRE_FALSE(spdlog::get(tested_logger_name)); - REQUIRE_FALSE(spdlog::get(tested_logger_name)); -} - - -TEST_CASE("drop non existing" "[registry]") -{ - spdlog::drop_all(); - spdlog::create(tested_logger_name); - spdlog::drop("some_name"); - REQUIRE_FALSE(spdlog::get("some_name")); - REQUIRE(spdlog::get(tested_logger_name)); - spdlog::drop_all(); -} - - - diff --git a/fpga/thirdparty/spdlog/tests/test_macros.cpp b/fpga/thirdparty/spdlog/tests/test_macros.cpp deleted file mode 100644 index 8ad7bd417..000000000 --- a/fpga/thirdparty/spdlog/tests/test_macros.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -* This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE -*/ - -#include "includes.h" - -TEST_CASE("debug and trace w/o format string", "[macros]]") -{ - prepare_logdir(); - std::string filename = "logs/simple_log"; - - auto logger = spdlog::create("logger", filename); - logger->set_pattern("%v"); - logger->set_level(spdlog::level::trace); - - SPDLOG_TRACE(logger, "Test message 1"); - //SPDLOG_DEBUG(logger, "Test message 2"); - SPDLOG_DEBUG(logger, "Test message 2"); - logger->flush(); - - REQUIRE(ends_with(file_contents(filename), "Test message 2\n")); - REQUIRE(count_lines(filename) == 2); -} - - -TEST_CASE("debug and trace with format strings", "[macros]]") -{ - prepare_logdir(); - std::string filename = "logs/simple_log"; - - auto logger = spdlog::create("logger", filename); - logger->set_pattern("%v"); - logger->set_level(spdlog::level::trace); - -#if !defined(SPDLOG_FMT_PRINTF) - SPDLOG_TRACE(logger, "Test message {}", 1); - //SPDLOG_DEBUG(logger, "Test message 2"); - SPDLOG_DEBUG(logger, "Test message {}", 222); -#else - SPDLOG_TRACE(logger, "Test message %d", 1); - //SPDLOG_DEBUG(logger, "Test message 2"); - SPDLOG_DEBUG(logger, "Test message %d", 222); -#endif - - logger->flush(); - - REQUIRE(ends_with(file_contents(filename), "Test message 222\n")); - REQUIRE(count_lines(filename) == 2); -} - diff --git a/fpga/thirdparty/spdlog/tests/tests.sln b/fpga/thirdparty/spdlog/tests/tests.sln deleted file mode 100644 index d224d204f..000000000 --- a/fpga/thirdparty/spdlog/tests/tests.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2015 -VisualStudioVersion = 14.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcxproj", "{59A07559-5F38-4DD6-A7FA-DB4153690B42}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|Win32.ActiveCfg = Debug|Win32 - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|Win32.Build.0 = Debug|Win32 - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|x64.ActiveCfg = Debug|x64 - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|x64.Build.0 = Debug|x64 - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|Win32.ActiveCfg = Release|Win32 - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|Win32.Build.0 = Release|Win32 - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|x64.ActiveCfg = Release|x64 - {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/fpga/thirdparty/spdlog/tests/tests.vcxproj b/fpga/thirdparty/spdlog/tests/tests.vcxproj deleted file mode 100644 index ef9d78f93..000000000 --- a/fpga/thirdparty/spdlog/tests/tests.vcxproj +++ /dev/null @@ -1,145 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {59A07559-5F38-4DD6-A7FA-DB4153690B42} - tests - - - - Application - true - v140 - MultiByte - - - Application - true - v140 - MultiByte - - - Application - false - v140 - true - MultiByte - - - Application - false - v140 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - true - $(SolutionDir)\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - _MBCS;%(PreprocessorDefinitions) - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level4 - MaxSpeed - true - true - true - $(SolutionDir)\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level4 - MaxSpeed - true - true - true - _MBCS;%(PreprocessorDefinitions) - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fpga/thirdparty/spdlog/tests/tests.vcxproj.filters b/fpga/thirdparty/spdlog/tests/tests.vcxproj.filters deleted file mode 100644 index adc86e7b7..000000000 --- a/fpga/thirdparty/spdlog/tests/tests.vcxproj.filters +++ /dev/null @@ -1,54 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/fpga/thirdparty/spdlog/tests/utils.cpp b/fpga/thirdparty/spdlog/tests/utils.cpp deleted file mode 100644 index e179147b1..000000000 --- a/fpga/thirdparty/spdlog/tests/utils.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "includes.h" - - -void prepare_logdir() -{ - spdlog::drop_all(); -#ifdef _WIN32 - system("if not exist logs mkdir logs"); - system("del /F /Q logs\\*"); -#else - auto rv = system("mkdir -p logs"); - rv = system("rm -f logs/*"); - (void)rv; -#endif -} - - -std::string file_contents(const std::string& filename) -{ - std::ifstream ifs(filename); - if (!ifs) - throw std::runtime_error("Failed open file "); - return std::string((std::istreambuf_iterator(ifs)), - (std::istreambuf_iterator())); - -} - -std::size_t count_lines(const std::string& filename) -{ - std::ifstream ifs(filename); - if (!ifs) - throw std::runtime_error("Failed open file "); - - std::string line; - size_t counter = 0; - while(std::getline(ifs, line)) - counter++; - return counter; -} - -std::size_t get_filesize(const std::string& filename) -{ - std::ifstream ifs(filename, std::ifstream::ate | std::ifstream::binary); - if (!ifs) - throw std::runtime_error("Failed open file "); - - return static_cast(ifs.tellg()); -} - - -// source: https://stackoverflow.com/a/2072890/192001 -bool ends_with(std::string const & value, std::string const & ending) -{ - if (ending.size() > value.size()) return false; - return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); -} diff --git a/fpga/thirdparty/spdlog/tests/utils.h b/fpga/thirdparty/spdlog/tests/utils.h deleted file mode 100644 index 819bcee61..000000000 --- a/fpga/thirdparty/spdlog/tests/utils.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include - -std::size_t count_lines(const std::string& filename); - -void prepare_logdir(); - -std::string file_contents(const std::string& filename); - -std::size_t count_lines(const std::string& filename); - -std::size_t get_filesize(const std::string& filename); - -bool ends_with(std::string const & value, std::string const & ending); \ No newline at end of file