diff --git a/example/doc/core_core_manual.cpp b/example/doc/core_core_manual.cpp index 874de33..71f6a0b 100644 --- a/example/doc/core_core_manual.cpp +++ b/example/doc/core_core_manual.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include diff --git a/example/doc/extension_record_tagger.cpp b/example/doc/extension_record_tagger.cpp index 1c1d627..99cc7cd 100644 --- a/example/doc/extension_record_tagger.cpp +++ b/example/doc/extension_record_tagger.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/example/doc/sources_net_connection.cpp b/example/doc/sources_net_connection.cpp index 59c950b..ef7ce35 100644 --- a/example/doc/sources_net_connection.cpp +++ b/example/doc/sources_net_connection.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/example/doc/sources_severity.cpp b/example/doc/sources_severity.cpp index 8741524..4110fb7 100644 --- a/example/doc/sources_severity.cpp +++ b/example/doc/sources_severity.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/example/doc/tutorial_logging.cpp b/example/doc/tutorial_logging.cpp index 31fe887..fd37f29 100644 --- a/example/doc/tutorial_logging.cpp +++ b/example/doc/tutorial_logging.cpp @@ -5,7 +5,7 @@ * http://www.boost.org/LICENSE_1_0.txt) */ -#include +#include #include #include #include diff --git a/include/boost/log/attributes/attribute_value_impl.hpp b/include/boost/log/attributes/attribute_value_impl.hpp index b21091e..e18015b 100644 --- a/include/boost/log/attributes/attribute_value_impl.hpp +++ b/include/boost/log/attributes/attribute_value_impl.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/boost/log/attributes/constant.hpp b/include/boost/log/attributes/constant.hpp index 1e9a036..f10b0a7 100644 --- a/include/boost/log/attributes/constant.hpp +++ b/include/boost/log/attributes/constant.hpp @@ -16,7 +16,7 @@ #define BOOST_LOG_ATTRIBUTES_CONSTANT_HPP_INCLUDED_ #include -#include +#include #include #include #include diff --git a/include/boost/log/attributes/mutable_constant.hpp b/include/boost/log/attributes/mutable_constant.hpp index 52356b4..6ff76dd 100644 --- a/include/boost/log/attributes/mutable_constant.hpp +++ b/include/boost/log/attributes/mutable_constant.hpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/attributes/scoped_attribute.hpp b/include/boost/log/attributes/scoped_attribute.hpp index 0e49581..88dd218 100644 --- a/include/boost/log/attributes/scoped_attribute.hpp +++ b/include/boost/log/attributes/scoped_attribute.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/boost/log/detail/attachable_sstream_buf.hpp b/include/boost/log/detail/attachable_sstream_buf.hpp index dd70d0e..3608bb1 100644 --- a/include/boost/log/detail/attachable_sstream_buf.hpp +++ b/include/boost/log/detail/attachable_sstream_buf.hpp @@ -150,7 +150,8 @@ public: { if (m_storage_state.storage && m_storage_state.storage->size() > m_storage_state.max_size) { - m_storage_state.storage->resize(m_storage_state.max_size); + const size_type len = length_until_boundary(m_storage_state.storage->c_str(), m_storage_state.storage->size(), m_storage_state.max_size); + m_storage_state.storage->resize(len); m_storage_state.overflow = true; } } @@ -186,7 +187,7 @@ public: else { // We have to find out where the last character that fits before the limit ends - left = length_until_boundary(s, n, left, mpl::bool_< sizeof(char_type) == 1u >()); + left = length_until_boundary(s, n, left); m_storage_state.storage->append(s, left); m_storage_state.overflow = true; return left; @@ -273,11 +274,17 @@ protected: return static_cast< std::streamsize >(this->append(s, static_cast< size_type >(n))); } + //! Finds the string length so that it includes only complete characters, and does not exceed \a max_size + size_type length_until_boundary(const char_type* s, size_type n, size_type max_size) const + { + return length_until_boundary(s, n, max_size, mpl::bool_< sizeof(char_type) == 1u >());; + } + //! Finds the string length so that it includes only complete characters, and does not exceed \a max_size size_type length_until_boundary(const char_type* s, size_type n, size_type max_size, mpl::true_) const { std::locale loc = this->getloc(); - std::codecvt< char_type, char, std::mbstate_t > const& fac = std::use_facet< std::codecvt< char_type, char, std::mbstate_t > >(loc); + std::codecvt< wchar_t, char, std::mbstate_t > const& fac = std::use_facet< std::codecvt< wchar_t, char, std::mbstate_t > >(loc); std::mbstate_t mbs = std::mbstate_t(); return static_cast< size_type >(fac.length(mbs, s, s + max_size, ~static_cast< std::size_t >(0u))); } diff --git a/include/boost/log/detail/enqueued_record.hpp b/include/boost/log/detail/enqueued_record.hpp index ef63777..f482136 100644 --- a/include/boost/log/detail/enqueued_record.hpp +++ b/include/boost/log/detail/enqueued_record.hpp @@ -18,7 +18,7 @@ #define BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_ #include -#include +#include #include #include #include diff --git a/include/boost/log/detail/light_function.hpp b/include/boost/log/detail/light_function.hpp index 7d4efc9..0835772 100644 --- a/include/boost/log/detail/light_function.hpp +++ b/include/boost/log/detail/light_function.hpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/boost/log/detail/locks.hpp b/include/boost/log/detail/locks.hpp index 99bc7e1..224d8e5 100644 --- a/include/boost/log/detail/locks.hpp +++ b/include/boost/log/detail/locks.hpp @@ -32,6 +32,8 @@ namespace boost { template< typename > class lock_guard; template< typename > +class shared_lock_guard; +template< typename > class shared_lock; template< typename > class upgrade_lock; @@ -92,6 +94,25 @@ struct is_shared_lockable enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) }; }; +//! A scope guard that automatically unlocks the mutex on destruction +template< typename MutexT > +struct exclusive_auto_unlocker +{ + explicit exclusive_auto_unlocker(MutexT& m) BOOST_NOEXCEPT : m_Mutex(m) + { + } + ~exclusive_auto_unlocker() + { + m_Mutex.unlock(); + } + + BOOST_DELETED_FUNCTION(exclusive_auto_unlocker(exclusive_auto_unlocker const&)) + BOOST_DELETED_FUNCTION(exclusive_auto_unlocker& operator= (exclusive_auto_unlocker const&)) + +protected: + MutexT& m_Mutex; +}; + //! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread. template< typename MutexT > struct exclusive_lock_guard @@ -105,9 +126,8 @@ struct exclusive_lock_guard m_Mutex.unlock(); } -private: - exclusive_lock_guard(exclusive_lock_guard const&); - exclusive_lock_guard& operator= (exclusive_lock_guard const&); + BOOST_DELETED_FUNCTION(exclusive_lock_guard(exclusive_lock_guard const&)) + BOOST_DELETED_FUNCTION(exclusive_lock_guard& operator= (exclusive_lock_guard const&)) private: MutexT& m_Mutex; @@ -126,9 +146,8 @@ struct shared_lock_guard m_Mutex.unlock_shared(); } -private: - shared_lock_guard(shared_lock_guard const&); - shared_lock_guard& operator= (shared_lock_guard const&); + BOOST_DELETED_FUNCTION(shared_lock_guard(shared_lock_guard const&)) + BOOST_DELETED_FUNCTION(shared_lock_guard& operator= (shared_lock_guard const&)) private: MutexT& m_Mutex; diff --git a/include/boost/log/detail/threadsafe_queue.hpp b/include/boost/log/detail/threadsafe_queue.hpp index 2ab2172..b8b3dbe 100644 --- a/include/boost/log/detail/threadsafe_queue.hpp +++ b/include/boost/log/detail/threadsafe_queue.hpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/expressions/filter.hpp b/include/boost/log/expressions/filter.hpp index 2d1d188..1e53f5c 100644 --- a/include/boost/log/expressions/filter.hpp +++ b/include/boost/log/expressions/filter.hpp @@ -16,7 +16,7 @@ #define BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_ #include -#include +#include #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include #include diff --git a/include/boost/log/expressions/formatter.hpp b/include/boost/log/expressions/formatter.hpp index 56aa1d2..bc80dfa 100644 --- a/include/boost/log/expressions/formatter.hpp +++ b/include/boost/log/expressions/formatter.hpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include #include diff --git a/include/boost/log/expressions/formatters.hpp b/include/boost/log/expressions/formatters.hpp index 1d3f4ed..f85cb79 100644 --- a/include/boost/log/expressions/formatters.hpp +++ b/include/boost/log/expressions/formatters.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/include/boost/log/expressions/formatters/char_decorator.hpp b/include/boost/log/expressions/formatters/char_decorator.hpp index 9c29622..50f6391 100644 --- a/include/boost/log/expressions/formatters/char_decorator.hpp +++ b/include/boost/log/expressions/formatters/char_decorator.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/expressions/formatters/date_time.hpp b/include/boost/log/expressions/formatters/date_time.hpp index 72029f0..a51f843 100644 --- a/include/boost/log/expressions/formatters/date_time.hpp +++ b/include/boost/log/expressions/formatters/date_time.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/boost/log/expressions/formatters/max_size_decorator.hpp b/include/boost/log/expressions/formatters/max_size_decorator.hpp index fe70bef..f428812 100644 --- a/include/boost/log/expressions/formatters/max_size_decorator.hpp +++ b/include/boost/log/expressions/formatters/max_size_decorator.hpp @@ -17,9 +17,10 @@ #include #include +#include #include #include -#include +#include #include #include #include @@ -100,6 +101,7 @@ public: max_size_decorator_output_terminal(LeftT const& left, subactor_type const& sub, size_type max_size, string_type const& overflow_marker = string_type()) : m_left(left), m_subactor(sub), m_max_size(max_size), m_overflow_marker(overflow_marker) { + BOOST_ASSERT(overflow_marker.size() <= max_size); } /*! * Copy constructor @@ -136,10 +138,20 @@ public: if (strm.rdbuf()->storage_overflow()) { - // Append overflow marker - strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size()); - strm.rdbuf()->storage_overflow(false); - strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + if (!m_overflow_marker.empty()) + { + // Free up space for the overflow marker + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); + + // Append the marker + strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size()); + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + } + else + { + strm.rdbuf()->storage_overflow(false); + } } // Restore the original size limit @@ -183,10 +195,20 @@ public: if (strm.rdbuf()->storage_overflow()) { - // Append overflow marker - strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size()); - strm.rdbuf()->storage_overflow(false); - strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + if (!m_overflow_marker.empty()) + { + // Free up space for the overflow marker + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); + + // Append the marker + strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size()); + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + } + else + { + strm.rdbuf()->storage_overflow(false); + } } // Restore the original size limit @@ -213,8 +235,8 @@ public: * of the strings generated by other formatters. * * The \c max_size_decorator_terminal class aggregates the formatter being decorated, the maximum string length - * it can produce and an optional truncation marker string, which will get appended if the limit is exceeded. Note that - * the marker length is not accounted for by the limit. + * it can produce and an optional truncation marker string, which will be put at the end of the output if the limit is exceeded. Note that + * the marker length is included in the limit and as such must not exceed it. * The \c max_size_decorator_terminal class is a formatter itself, so it can be used to construct * more complex formatters, including nesting decorators. */ @@ -258,6 +280,7 @@ public: max_size_decorator_terminal(subactor_type const& sub, size_type max_size, string_type const& overflow_marker = string_type()) : m_subactor(sub), m_max_size(max_size), m_overflow_marker(overflow_marker) { + BOOST_ASSERT(overflow_marker.size() <= max_size); } /*! * Copy constructor @@ -320,8 +343,9 @@ public: // Flush the buffered characters and see of overflow happened strm.flush(); - if (strm.rdbuf()->storage_overflow()) + if (strm.rdbuf()->storage_overflow() && !m_overflow_marker.empty()) { + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); strm.rdbuf()->max_size(str.max_size()); strm.rdbuf()->storage_overflow(false); strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); @@ -362,6 +386,7 @@ public: if (strm.rdbuf()->storage_overflow()) { + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); strm.rdbuf()->max_size(str.max_size()); strm.rdbuf()->storage_overflow(false); strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); @@ -439,6 +464,7 @@ public: explicit max_size_decorator_gen(size_type max_size, string_type const& overflow_marker = string_type()) : m_max_size(max_size), m_overflow_marker(overflow_marker) { + BOOST_ASSERT(overflow_marker.size() <= max_size); } template< typename SubactorT > @@ -473,7 +499,7 @@ BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_ * \param overflow_marker The marker string which is appended to the output if the \a max_size limit is exceeded. Must be * a non-null pointer to a zero-terminated string. * - * \note The \a overflow_marker length is not included in the \a max_size limit. + * \pre The \a overflow_marker length must not exceed the \a max_size limit. */ template< typename CharT > BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size, const CharT* overflow_marker) @@ -488,7 +514,7 @@ BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_ * \param max_size The maximum number of characters (i.e. string element objects) that the decorated formatter can produce. * \param overflow_marker The marker string which is appended to the output if the \a max_size limit is exceeded. * - * \note The \a overflow_marker length is not included in the \a max_size limit. + * \pre The \a overflow_marker length must not exceed the \a max_size limit. */ template< typename CharT > BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size, std::basic_string< CharT > const& overflow_marker) diff --git a/include/boost/log/expressions/formatters/named_scope.hpp b/include/boost/log/expressions/formatters/named_scope.hpp index 0f3b9c7..a2c6615 100644 --- a/include/boost/log/expressions/formatters/named_scope.hpp +++ b/include/boost/log/expressions/formatters/named_scope.hpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/expressions/formatters/wrap_formatter.hpp b/include/boost/log/expressions/formatters/wrap_formatter.hpp index a5df456..81cc322 100644 --- a/include/boost/log/expressions/formatters/wrap_formatter.hpp +++ b/include/boost/log/expressions/formatters/wrap_formatter.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/boost/log/sinks/basic_sink_frontend.hpp b/include/boost/log/sinks/basic_sink_frontend.hpp index 965451c..3686bc5 100644 --- a/include/boost/log/sinks/basic_sink_frontend.hpp +++ b/include/boost/log/sinks/basic_sink_frontend.hpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -29,7 +28,6 @@ #if !defined(BOOST_LOG_NO_THREADS) #include #include -#include #include #include #endif // !defined(BOOST_LOG_NO_THREADS) @@ -186,13 +184,10 @@ protected: bool try_feed_record(record_view const& rec, BackendMutexT& backend_mutex, BackendT& backend) { #if !defined(BOOST_LOG_NO_THREADS) - unique_lock< BackendMutexT > lock; try { - unique_lock< BackendMutexT > tmp_lock(backend_mutex, try_to_lock); - if (!tmp_lock.owns_lock()) + if (!backend_mutex.try_lock()) return false; - lock.swap(tmp_lock); } catch (thread_interrupted&) { @@ -206,6 +201,8 @@ protected: this->exception_handler()(); return false; } + + boost::log::aux::exclusive_auto_unlocker< BackendMutexT > unlocker(backend_mutex); #endif // No need to lock anything in the feed_record method boost::log::aux::fake_mutex m; @@ -280,6 +277,28 @@ protected: private: struct formatting_context { + class cleanup_guard + { + private: + formatting_context& m_context; + + public: + explicit cleanup_guard(formatting_context& ctx) BOOST_NOEXCEPT : m_context(ctx) + { + } + + ~cleanup_guard() + { + m_context.m_FormattedRecord.clear(); + m_context.m_FormattingStream.rdbuf()->max_size(m_context.m_FormattedRecord.max_size()); + m_context.m_FormattingStream.rdbuf()->storage_overflow(false); + m_context.m_FormattingStream.clear(); + } + + BOOST_DELETED_FUNCTION(cleanup_guard(cleanup_guard const&)) + BOOST_DELETED_FUNCTION(cleanup_guard& operator=(cleanup_guard const&)) + }; + #if !defined(BOOST_LOG_NO_THREADS) //! Object version const unsigned int m_Version; @@ -431,8 +450,7 @@ protected: context = &m_Context; #endif - boost::log::aux::cleanup_guard< stream_type > cleanup1(context->m_FormattingStream); - boost::log::aux::cleanup_guard< string_type > cleanup2(context->m_FormattedRecord); + typename formatting_context::cleanup_guard cleanup(*context); try { @@ -464,13 +482,10 @@ protected: bool try_feed_record(record_view const& rec, BackendMutexT& backend_mutex, BackendT& backend) { #if !defined(BOOST_LOG_NO_THREADS) - unique_lock< BackendMutexT > lock; try { - unique_lock< BackendMutexT > tmp_lock(backend_mutex, try_to_lock); - if (!tmp_lock.owns_lock()) + if (!backend_mutex.try_lock()) return false; - lock.swap(tmp_lock); } catch (thread_interrupted&) { @@ -484,6 +499,8 @@ protected: this->exception_handler()(); return false; } + + boost::log::aux::exclusive_auto_unlocker< BackendMutexT > unlocker(backend_mutex); #endif // No need to lock anything in the feed_record method boost::log::aux::fake_mutex m; diff --git a/include/boost/log/sources/basic_logger.hpp b/include/boost/log/sources/basic_logger.hpp index 3403928..58bd659 100644 --- a/include/boost/log/sources/basic_logger.hpp +++ b/include/boost/log/sources/basic_logger.hpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/sources/channel_feature.hpp b/include/boost/log/sources/channel_feature.hpp index aa03490..d7e88c4 100644 --- a/include/boost/log/sources/channel_feature.hpp +++ b/include/boost/log/sources/channel_feature.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/boost/log/sources/exception_handler_feature.hpp b/include/boost/log/sources/exception_handler_feature.hpp index bd77fca..d290411 100644 --- a/include/boost/log/sources/exception_handler_feature.hpp +++ b/include/boost/log/sources/exception_handler_feature.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/boost/log/sources/record_ostream.hpp b/include/boost/log/sources/record_ostream.hpp index b8fcd9f..5fac874 100644 --- a/include/boost/log/sources/record_ostream.hpp +++ b/include/boost/log/sources/record_ostream.hpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/sources/severity_feature.hpp b/include/boost/log/sources/severity_feature.hpp index 6ecf95e..101769b 100644 --- a/include/boost/log/sources/severity_feature.hpp +++ b/include/boost/log/sources/severity_feature.hpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/support/date_time.hpp b/include/boost/log/support/date_time.hpp index e1c9050..468f02f 100644 --- a/include/boost/log/support/date_time.hpp +++ b/include/boost/log/support/date_time.hpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/log/utility/strictest_lock.hpp b/include/boost/log/utility/strictest_lock.hpp index 9735961..5dd48b4 100644 --- a/include/boost/log/utility/strictest_lock.hpp +++ b/include/boost/log/utility/strictest_lock.hpp @@ -78,6 +78,11 @@ struct thread_access_mode_of< lock_guard< MutexT > > : mpl::integral_c< lock_acc { }; +template< typename MutexT > +struct thread_access_mode_of< shared_lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, shared_access > +{ +}; + template< typename MutexT > struct thread_access_mode_of< unique_lock< MutexT > > : mpl::integral_c< lock_access_mode, exclusive_access > { diff --git a/src/core.cpp b/src/core.cpp index 1d9dd69..f43d80b 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/format_parser.cpp b/src/format_parser.cpp index d797dd9..1215d6b 100644 --- a/src/format_parser.cpp +++ b/src/format_parser.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/named_scope_format_parser.cpp b/src/named_scope_format_parser.cpp index 16e7bd2..729f1fb 100644 --- a/src/named_scope_format_parser.cpp +++ b/src/named_scope_format_parser.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/posix/object_name.cpp b/src/posix/object_name.cpp index 9465fbb..456e1ea 100644 --- a/src/posix/object_name.cpp +++ b/src/posix/object_name.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/setup/filter_parser.cpp b/src/setup/filter_parser.cpp index efb2402..cf41bca 100644 --- a/src/setup/filter_parser.cpp +++ b/src/setup/filter_parser.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/setup/formatter_parser.cpp b/src/setup/formatter_parser.cpp index e84f157..09ab8ee 100644 --- a/src/setup/formatter_parser.cpp +++ b/src/setup/formatter_parser.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/setup/settings_parser.cpp b/src/setup/settings_parser.cpp index 8af2373..d0ebe6f 100644 --- a/src/setup/settings_parser.cpp +++ b/src/setup/settings_parser.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/windows/object_name.cpp b/src/windows/object_name.cpp index b28848c..e89d100 100644 --- a/src/windows/object_name.cpp +++ b/src/windows/object_name.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/test/common/make_record.hpp b/test/common/make_record.hpp index bb81589..9d1f028 100644 --- a/test/common/make_record.hpp +++ b/test/common/make_record.hpp @@ -15,7 +15,7 @@ #ifndef BOOST_LOG_TESTS_MAKE_RECORD_HPP_INCLUDED_ #define BOOST_LOG_TESTS_MAKE_RECORD_HPP_INCLUDED_ -#include +#include #include #include diff --git a/test/run/core.cpp b/test/run/core.cpp index f945c03..69b4264 100644 --- a/test/run/core.cpp +++ b/test/run/core.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/test/run/form_max_size_decor.cpp b/test/run/form_max_size_decor.cpp new file mode 100644 index 0000000..8fec3fa --- /dev/null +++ b/test/run/form_max_size_decor.cpp @@ -0,0 +1,185 @@ +/* + * Copyright Andrey Semashev 2016. + * 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) + */ +/*! + * \file form_max_size_decor.cpp + * \author Andrey Semashev + * \date 09.08.2016 + * + * \brief This header contains tests for the \c max_size_decor formatter. + */ + +#define BOOST_TEST_MODULE form_max_size_decor + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "char_definitions.hpp" +#include "make_record.hpp" + +#define BOOST_UTF8_DECL +#define BOOST_UTF8_BEGIN_NAMESPACE namespace { +#define BOOST_UTF8_END_NAMESPACE } + +#include +#include + +namespace logging = boost::log; +namespace attrs = logging::attributes; +namespace expr = logging::expressions; + +namespace { + +template< typename > +struct test_strings; + +#ifdef BOOST_LOG_USE_CHAR +template< > +struct test_strings< char > : public test_data< char > +{ + static const char* printable_chars() { return " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; } + static const char* overflow_marker() { return ">>>"; } +}; +#endif + +#ifdef BOOST_LOG_USE_WCHAR_T +template< > +struct test_strings< wchar_t > : public test_data< wchar_t > +{ + static const wchar_t* printable_chars() { return L" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; } + static const wchar_t* overflow_marker() { return L">>>"; } +}; +#endif + +} // namespace + +BOOST_AUTO_TEST_CASE_TEMPLATE(decorator_formatting, CharT, char_types) +{ + typedef logging::record_view record_view; + typedef logging::attribute_set attr_set; + typedef std::basic_string< CharT > string; + typedef logging::basic_formatting_ostream< CharT > osstream; + typedef logging::basic_formatter< CharT > formatter; + typedef test_strings< CharT > data; + + attrs::constant< string > attr1(data::printable_chars()); + + attr_set set1; + set1[data::attr1()] = attr1; + + record_view rec = make_record_view(set1); + + // Test output truncation + { + string str1, str2; + osstream strm1(str1), strm2(str2); + formatter f = expr::stream << expr::max_size_decor< CharT >(10)[ expr::stream << expr::attr< string >(data::attr1()) << data::some_test_string() << 1234 << data::abc() ]; + f(rec, strm1); + strm2 << string(data::printable_chars(), 10); + BOOST_CHECK(equal_strings(strm1.str(), strm2.str())); + } + + // Test output truncation with a marker + { + string str1, str2; + osstream strm1(str1), strm2(str2); + formatter f = expr::stream << expr::max_size_decor(10, data::overflow_marker())[ expr::stream << expr::attr< string >(data::attr1()) << data::some_test_string() << 1234 << data::abc() ]; + f(rec, strm1); + strm2 << string(data::printable_chars(), 7) << data::overflow_marker(); + BOOST_CHECK(equal_strings(strm1.str(), strm2.str())); + } + + // Test nested decorators, when the outer decorator enforces the limit that includes the inner decorator + { + string str1, str2; + osstream strm1(str1), strm2(str2); + formatter f = expr::stream << expr::max_size_decor(35, data::overflow_marker())[ + expr::stream << data::abcdefg0123456789() << expr::max_size_decor(10, data::overflow_marker())[ expr::stream << expr::attr< string >(data::attr1()) ] << data::abcdefg0123456789() + ]; + f(rec, strm1); + strm2 << data::abcdefg0123456789() << string(data::printable_chars(), 7) << data::overflow_marker() << string(data::abcdefg0123456789(), 5) << data::overflow_marker(); + BOOST_CHECK(equal_strings(strm1.str(), strm2.str())); + } + + // Test nested decorators, when the outer decorator enforces the limit that also limits the inner decorator + { + string str1, str2; + osstream strm1(str1), strm2(str2); + formatter f = expr::stream << expr::max_size_decor(25, data::overflow_marker())[ + expr::stream << data::abcdefg0123456789() << expr::max_size_decor(10, data::overflow_marker())[ expr::stream << expr::attr< string >(data::attr1()) ] << data::abcdefg0123456789() + ]; + f(rec, strm1); + strm2 << data::abcdefg0123456789() << string(data::printable_chars(), 5) << data::overflow_marker(); + BOOST_CHECK(equal_strings(strm1.str(), strm2.str())); + } +} + +namespace { + +const char narrow_chars[] = +{ + static_cast< char >(0xd0), static_cast< char >(0x9f), static_cast< char >(0xd1), static_cast< char >(0x80), + static_cast< char >(0xd0), static_cast< char >(0xb8), static_cast< char >(0xd0), static_cast< char >(0xb2), + static_cast< char >(0xd0), static_cast< char >(0xb5), static_cast< char >(0xd1), static_cast< char >(0x82), + ',', ' ', + static_cast< char >(0xd0), static_cast< char >(0xbc), static_cast< char >(0xd0), static_cast< char >(0xb8), + static_cast< char >(0xd1), static_cast< char >(0x80), '!', 0 +}; + +} // namespace + +BOOST_AUTO_TEST_CASE(character_boundary_maintenance) +{ + typedef logging::record_view record_view; + typedef logging::attribute_set attr_set; + typedef std::basic_string< char > string; + typedef logging::basic_formatting_ostream< char > osstream; + typedef logging::basic_formatter< char > formatter; + typedef test_strings< char > data; + + std::locale loc(std::locale::classic(), new utf8_codecvt_facet()); + + attrs::constant< string > attr1(narrow_chars); + + attr_set set1; + set1[data::attr1()] = attr1; + + record_view rec = make_record_view(set1); + + // Test that output truncation does not happen in the middle of a multibyte character + { + string str1, str2; + osstream strm1(str1), strm2(str2); + strm1.imbue(loc); + strm2.imbue(loc); + formatter f = expr::stream << expr::max_size_decor< char >(7)[ expr::stream << expr::attr< string >(data::attr1()) ]; + f(rec, strm1); + strm2 << string(narrow_chars, 6); + BOOST_CHECK(equal_strings(strm1.str(), strm2.str())); + } + + // Test output truncation with a marker, when the marker length would have caused truncation in the middle of a multibyte character + { + string str1, str2; + osstream strm1(str1), strm2(str2); + strm1.imbue(loc); + strm2.imbue(loc); + formatter f = expr::stream << expr::max_size_decor(6, data::overflow_marker())[ expr::stream << expr::attr< string >(data::attr1()) ]; + f(rec, strm1); + strm2 << string(narrow_chars, 2) << data::overflow_marker(); + BOOST_CHECK(equal_strings(strm1.str(), strm2.str())); + } +} diff --git a/test/run/util_ipc_object_name.cpp b/test/run/util_ipc_object_name.cpp index 8373257..42ad03c 100644 --- a/test/run/util_ipc_object_name.cpp +++ b/test/run/util_ipc_object_name.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include "char_definitions.hpp" const char test_object_name1[] = "boost_log_test_object_name1"; diff --git a/test/run/util_ipc_reliable_mq.cpp b/test/run/util_ipc_reliable_mq.cpp index ec535d0..d4b68ff 100644 --- a/test/run/util_ipc_reliable_mq.cpp +++ b/test/run/util_ipc_reliable_mq.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #if !defined(BOOST_LOG_NO_THREADS) #include #include