From 56bb6f2dcae7825a8af63015106df55128ca4631 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 5 Oct 2013 19:02:18 +0000 Subject: [PATCH] Temporarily reverted the last commit [86164], until 1.55 beta ships. [SVN r86166] --- build/Jamfile.v2 | 1 - include/boost/log/detail/config.hpp | 2 +- src/core.cpp | 4 + src/default_filter_factory.cpp | 175 +++++++++++++++++++--------- src/text_file_backend.cpp | 39 +++---- 5 files changed, 141 insertions(+), 80 deletions(-) diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 0b881ca..486e660 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -110,7 +110,6 @@ project boost/log intel-win:_CRT_SECURE_NO_WARNINGS intel-win:_CRT_SECURE_NO_DEPRECATE darwin:-ftemplate-depth-1024 - clang:-ftemplate-depth-1024 gcc:-ftemplate-depth-1024 gcc:-fno-strict-aliasing # avoids strict aliasing violations in other Boost components gcc-mingw:-Wl,--enable-auto-import diff --git a/include/boost/log/detail/config.hpp b/include/boost/log/detail/config.hpp index 1955897..e13ce23 100644 --- a/include/boost/log/detail/config.hpp +++ b/include/boost/log/detail/config.hpp @@ -316,7 +316,7 @@ inline namespace BOOST_LOG_VERSION_NAMESPACE {} namespace BOOST_LOG_VERSION_NAMESPACE {} using namespace BOOST_LOG_VERSION_NAMESPACE -# if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && !defined(__clang__) +# if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) __attribute__((__strong__)) # endif ; diff --git a/src/core.cpp b/src/core.cpp index 13c5a24..65c989d 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -252,6 +252,10 @@ public: m_default_sink(boost::make_shared< sinks::aux::default_sink >()), m_enabled(true) { + // Workaround for https://svn.boost.org/trac/boost/ticket/8642 + // Initialize global locale in Boost.Filesystem early, so that it is still available while the logging core is destroyed. + // Note that this only helps in the simplest case, when the core is not kept alive by a shared_ptr saved by user. + filesystem::path::codecvt(); } //! Invokes sink-specific filter and adds the sink to the record if the filter passes the log record diff --git a/src/default_filter_factory.cpp b/src/default_filter_factory.cpp index d754f72..9cb04a0 100644 --- a/src/default_filter_factory.cpp +++ b/src/default_filter_factory.cpp @@ -16,9 +16,15 @@ #if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES) #include +#include +#include +#include #include +#include #include #include +#include +#include #include #include #include @@ -27,6 +33,7 @@ #include #include #include +#include #include #if defined(BOOST_LOG_USE_CHAR) && defined(BOOST_LOG_USE_WCHAR_T) #include @@ -35,6 +42,7 @@ #endif #include "default_filter_factory.hpp" #include "parser_utils.hpp" +#include "spirit_encoding.hpp" #include namespace qi = boost::spirit::qi; @@ -92,7 +100,10 @@ public: } template< typename T > - result_type operator() (T const& val) const + typename boost::enable_if< + mpl::contains< log::string_types::type, T >, + result_type + >::type operator() (T const& val) const { typedef std::basic_string< typename T::value_type > operand_type; return relation_type::operator() (val, fusion::at_key< operand_type >(m_operands)); @@ -159,20 +170,20 @@ public: { } - template< typename CharT, typename TraitsT, typename AllocatorT > - result_type operator() (std::basic_string< CharT, TraitsT, AllocatorT > const& val) const - { - return base_type::operator() (val); - } - - template< typename CharT, typename TraitsT > - result_type operator() (basic_string_literal< CharT, TraitsT > const& val) const + template< typename T > + typename boost::enable_if< + mpl::contains< log::string_types, T >, + result_type + >::type operator() (T const& val) const { return base_type::operator() (val); } template< typename T > - result_type operator() (T const& val) const + typename boost::disable_if< + mpl::contains< log::string_types, T >, + result_type + >::type operator() (T const& val) const { return relation_type::operator() (val, m_numeric_operand); } @@ -181,10 +192,77 @@ private: const numeric_type m_numeric_operand; }; -typedef mpl::copy< - log::string_types, - mpl::back_inserter< log::floating_point_types > ->::type floating_point_and_string_types; + +template< typename RelationT > +struct on_string_argument +{ + typedef void result_type; + + on_string_argument(attribute_name const& name, filter& f) : m_name(name), m_filter(f) + { + } + + template< typename StringT > + result_type operator() (StringT const& val) const + { + typedef string_predicate< RelationT > predicate; + m_filter = predicate_wrapper< log::string_types, predicate >(m_name, predicate(RelationT(), val)); + } + +private: + attribute_name m_name; + filter& m_filter; +}; + +template< typename RelationT, typename StringT > +struct on_integral_argument +{ + typedef void result_type; + + on_integral_argument(attribute_name const& name, StringT const& operand, filter& f) : m_name(name), m_operand(operand), m_filter(f) + { + } + + result_type operator() (long val) const + { + typedef numeric_predicate< long, RelationT > predicate; + typedef mpl::copy< + log::string_types, + mpl::back_inserter< log::numeric_types > + >::type value_types; + m_filter = predicate_wrapper< value_types, predicate >(m_name, predicate(RelationT(), m_operand, val)); + } + +private: + attribute_name m_name; + StringT const& m_operand; + filter& m_filter; +}; + +template< typename RelationT, typename StringT > +struct on_fp_argument +{ + typedef void result_type; + + on_fp_argument(attribute_name const& name, StringT const& operand, filter& f) : m_name(name), m_operand(operand), m_filter(f) + { + } + + result_type operator() (double val) const + { + typedef numeric_predicate< double, RelationT > predicate; + typedef mpl::copy< + log::string_types, + mpl::back_inserter< log::floating_point_types > + >::type value_types; + m_filter = predicate_wrapper< value_types, predicate >(m_name, predicate(RelationT(), m_operand, val)); + } + +private: + attribute_name m_name; + StringT const& m_operand; + filter& m_filter; +}; } // namespace @@ -236,27 +314,21 @@ filter default_filter_factory< CharT >::on_custom_relation(attribute_name const& { typedef log::aux::char_constants< char_type > constants; + filter f; if (rel == constants::begins_with_keyword()) - { - typedef string_predicate< begins_with_fun > predicate; - return predicate_wrapper< log::string_types, predicate >(name, predicate(begins_with_fun(), arg)); - } + on_string_argument< begins_with_fun >(name, f)(arg); else if (rel == constants::ends_with_keyword()) - { - typedef string_predicate< ends_with_fun > predicate; - return predicate_wrapper< log::string_types, predicate >(name, predicate(ends_with_fun(), arg)); - } + on_string_argument< ends_with_fun >(name, f)(arg); else if (rel == constants::contains_keyword()) - { - typedef string_predicate< contains_fun > predicate; - return predicate_wrapper< log::string_types, predicate >(name, predicate(contains_fun(), arg)); - } - else if (rel != constants::matches_keyword()) + on_string_argument< contains_fun >(name, f)(arg); + else if (rel == constants::matches_keyword()) + f = parse_matches_relation(name, arg); + else { BOOST_LOG_THROW_DESCR(parse_error, "The custom attribute relation \"" + log::aux::to_narrow(rel) + "\" is not supported"); } - return parse_matches_relation(name, arg); + return boost::move(f); } @@ -265,33 +337,28 @@ template< typename CharT > template< typename RelationT > filter default_filter_factory< CharT >::parse_argument(attribute_name const& name, string_type const& arg) { - const char_type* begin = arg.c_str(); - const char_type* const end = begin + arg.size(); - - double real_val = 0.0; + typedef log::aux::encoding_specific< typename log::aux::encoding< char_type >::type > encoding_specific; const qi::real_parser< double, qi::strict_real_policies< double > > real_; - if (qi::parse(begin, end, real_, real_val) && begin == end) - { - typedef numeric_predicate< double, RelationT > predicate; - typedef floating_point_and_string_types value_types; - return predicate_wrapper< value_types, predicate >(name, predicate(RelationT(), arg, real_val)); - } - else - { - begin = arg.c_str(); - long int_val = 0; - if (qi::parse(begin, end, qi::long_, int_val) && begin == end) - { - typedef numeric_predicate< long, RelationT > predicate; - typedef default_attribute_types value_types; - return predicate_wrapper< value_types, predicate >(name, predicate(RelationT(), arg, int_val)); - } - else - { - typedef string_predicate< RelationT > predicate; - return predicate_wrapper< log::string_types, predicate >(name, predicate(RelationT(), arg)); - } - } + + filter f; + const on_fp_argument< RelationT, string_type > on_fp(name, arg, f); + const on_integral_argument< RelationT, string_type > on_int(name, arg, f); + const on_string_argument< RelationT > on_str(name, f); + + const bool res = qi::parse + ( + arg.c_str(), arg.c_str() + arg.size(), + ( + real_[boost::log::as_action(on_fp)] | + qi::long_[boost::log::as_action(on_int)] | + qi::as< string_type >()[ +encoding_specific::print ][boost::log::as_action(on_str)] + ) >> qi::eoi + ); + + if (!res) + BOOST_LOG_THROW_DESCR(parse_error, "Failed to parse relation operand"); + + return boost::move(f); } // Explicitly instantiate factory implementation diff --git a/src/text_file_backend.cpp b/src/text_file_backend.cpp index aac83f6..b5f33ae 100644 --- a/src/text_file_backend.cpp +++ b/src/text_file_backend.cpp @@ -76,8 +76,6 @@ namespace sinks { BOOST_LOG_ANONYMOUS_NAMESPACE { - typedef filesystem::filesystem_error filesystem_error; - //! A possible Boost.Filesystem extension - renames or moves the file to the target storage inline void move_file( filesystem::path const& from, @@ -88,20 +86,20 @@ BOOST_LOG_ANONYMOUS_NAMESPACE { filesystem::rename(from, to); #else // On POSIX rename fails if the target points to a different device - system::error_code ec; - filesystem::rename(from, to, ec); - if (ec) + try { - if (ec.value() == system::errc::cross_device_link) + filesystem::rename(from, to); + } + catch (system::system_error& e) + { + if (e.code().value() == system::errc::cross_device_link) { // Attempt to manually move the file instead filesystem::copy_file(from, to); filesystem::remove(from); } else - { - BOOST_THROW_EXCEPTION(filesystem_error("failed to move file to another location", from, to, ec)); - } + throw; } #endif } @@ -109,6 +107,8 @@ BOOST_LOG_ANONYMOUS_NAMESPACE { typedef filesystem::path::string_type path_string_type; typedef path_string_type::value_type path_char_type; + typedef filesystem::filesystem_error filesystem_error; + //! An auxiliary traits that contain various constants and functions regarding string and character operations template< typename CharT > struct file_char_traits; @@ -633,19 +633,13 @@ BOOST_LOG_ANONYMOUS_NAMESPACE { //! The function stores the specified file in the storage void file_collector::store_file(filesystem::path const& src_path) { - // NOTE FOR THE FOLLOWING CODE: - // Avoid using Boost.Filesystem functions that would call path::codecvt(). store_file() can be called - // at process termination, and the global codecvt facet can already be destroyed at this point. - // https://svn.boost.org/trac/boost/ticket/8642 - // Let's construct the new file name file_info info; info.m_TimeStamp = filesystem::last_write_time(src_path); info.m_Size = filesystem::file_size(src_path); - filesystem::path file_name_path = src_path.filename(); - path_string_type file_name = file_name_path.native(); - info.m_Path = m_StorageDir / file_name_path; + path_string_type file_name = filename_string(src_path); + info.m_Path = m_StorageDir / file_name; // Check if the file is already in the target directory filesystem::path src_dir = src_path.has_parent_path() ? @@ -663,7 +657,7 @@ BOOST_LOG_ANONYMOUS_NAMESPACE { do { path_string_type alt_file_name = formatter(file_name, n++); - info.m_Path = m_StorageDir / filesystem::path(alt_file_name); + info.m_Path = m_StorageDir / alt_file_name; } while (filesystem::exists(info.m_Path) && n < (std::numeric_limits< unsigned int >::max)()); } @@ -1185,16 +1179,13 @@ BOOST_LOG_API void text_file_backend::flush() //! The method sets file name mask BOOST_LOG_API void text_file_backend::set_file_name_pattern_internal(filesystem::path const& pattern) { - // Note: avoid calling Boost.Filesystem functions that involve path::codecvt() - // https://svn.boost.org/trac/boost/ticket/9119 - typedef file_char_traits< path_char_type > traits_t; filesystem::path p = pattern; if (p.empty()) - p = filesystem::path(traits_t::default_file_name_pattern()); + p = traits_t::default_file_name_pattern(); - m_pImpl->m_FileNamePattern = p.filename(); - path_string_type name_pattern = m_pImpl->m_FileNamePattern.native(); + path_string_type name_pattern = p.filename().string< path_string_type >(); + m_pImpl->m_FileNamePattern = name_pattern; m_pImpl->m_StorageDir = filesystem::absolute(p.parent_path()); // Let's try to find the file counter placeholder