File indexing completed on 2025-09-17 08:53:31
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_MESSAGE_HPP_INCLUDED
0009 #define CATCH_MESSAGE_HPP_INCLUDED
0010
0011 #include <catch2/internal/catch_config_prefix_messages.hpp>
0012 #include <catch2/internal/catch_result_type.hpp>
0013 #include <catch2/internal/catch_reusable_string_stream.hpp>
0014 #include <catch2/internal/catch_stream_end_stop.hpp>
0015 #include <catch2/internal/catch_message_info.hpp>
0016 #include <catch2/catch_tostring.hpp>
0017 #include <catch2/interfaces/catch_interfaces_capture.hpp>
0018
0019 #include <string>
0020 #include <vector>
0021
0022 namespace Catch {
0023
0024 struct SourceLineInfo;
0025 class IResultCapture;
0026
0027 struct MessageStream {
0028
0029 template<typename T>
0030 MessageStream& operator << ( T const& value ) {
0031 m_stream << value;
0032 return *this;
0033 }
0034
0035 ReusableStringStream m_stream;
0036 };
0037
0038 struct MessageBuilder : MessageStream {
0039 MessageBuilder( StringRef macroName,
0040 SourceLineInfo const& lineInfo,
0041 ResultWas::OfType type ):
0042 m_info(macroName, lineInfo, type) {}
0043
0044 template<typename T>
0045 MessageBuilder&& operator << ( T const& value ) && {
0046 m_stream << value;
0047 return CATCH_MOVE(*this);
0048 }
0049
0050 MessageInfo m_info;
0051 };
0052
0053 class ScopedMessage {
0054 public:
0055 explicit ScopedMessage( MessageBuilder&& builder );
0056 ScopedMessage( ScopedMessage& duplicate ) = delete;
0057 ScopedMessage( ScopedMessage&& old ) noexcept;
0058 ~ScopedMessage();
0059
0060 MessageInfo m_info;
0061 bool m_moved = false;
0062 };
0063
0064 class Capturer {
0065 std::vector<MessageInfo> m_messages;
0066 IResultCapture& m_resultCapture;
0067 size_t m_captured = 0;
0068 public:
0069 Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
0070
0071 Capturer(Capturer const&) = delete;
0072 Capturer& operator=(Capturer const&) = delete;
0073
0074 ~Capturer();
0075
0076 void captureValue( size_t index, std::string const& value );
0077
0078 template<typename T>
0079 void captureValues( size_t index, T const& value ) {
0080 captureValue( index, Catch::Detail::stringify( value ) );
0081 }
0082
0083 template<typename T, typename... Ts>
0084 void captureValues( size_t index, T const& value, Ts const&... values ) {
0085 captureValue( index, Catch::Detail::stringify(value) );
0086 captureValues( index+1, values... );
0087 }
0088 };
0089
0090 }
0091
0092
0093 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
0094 do { \
0095 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
0096 catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
0097 catchAssertionHandler.complete(); \
0098 } while( false )
0099
0100
0101 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
0102 Catch::Capturer varName( macroName##_catch_sr, \
0103 CATCH_INTERNAL_LINEINFO, \
0104 Catch::ResultWas::Info, \
0105 #__VA_ARGS__##_catch_sr ); \
0106 varName.captureValues( 0, __VA_ARGS__ )
0107
0108
0109 #define INTERNAL_CATCH_INFO( macroName, log ) \
0110 const Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
0111
0112
0113 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
0114 Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
0115
0116
0117 #if defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
0118
0119 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
0120 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
0121 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
0122 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__ )
0123
0124 #elif defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
0125
0126 #define CATCH_INFO( msg ) (void)(0)
0127 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
0128 #define CATCH_WARN( msg ) (void)(0)
0129 #define CATCH_CAPTURE( ... ) (void)(0)
0130
0131 #elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
0132
0133 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
0134 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
0135 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
0136 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__ )
0137
0138 #elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
0139
0140 #define INFO( msg ) (void)(0)
0141 #define UNSCOPED_INFO( msg ) (void)(0)
0142 #define WARN( msg ) (void)(0)
0143 #define CAPTURE( ... ) (void)(0)
0144
0145 #endif
0146
0147
0148
0149
0150 #endif