$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r86199 - in branches/release: boost/log boost/log/detail libs/log libs/log/build libs/log/src
From: andrey.semashev_at_[hidden]
Date: 2013-10-08 10:45:00
Author: andysem
Date: 2013-10-08 10:44:59 EDT (Tue, 08 Oct 2013)
New Revision: 86199
URL: http://svn.boost.org/trac/boost/changeset/86199
Log:
Reapplied changeset [86160].
Properties modified: 
   branches/release/boost/log/   (props changed)
   branches/release/libs/log/   (props changed)
Text files modified: 
   branches/release/boost/log/detail/config.hpp             |     2                                         
   branches/release/libs/log/build/Jamfile.v2               |     1                                         
   branches/release/libs/log/src/core.cpp                   |     4                                         
   branches/release/libs/log/src/default_filter_factory.cpp |   175 ++++++++++++--------------------------- 
   branches/release/libs/log/src/text_file_backend.cpp      |    39 +++++---                                
   5 files changed, 80 insertions(+), 141 deletions(-)
Modified: branches/release/boost/log/detail/config.hpp
==============================================================================
--- branches/release/boost/log/detail/config.hpp	Tue Oct  8 10:29:06 2013	(r86198)
+++ branches/release/boost/log/detail/config.hpp	2013-10-08 10:44:59 EDT (Tue, 08 Oct 2013)	(r86199)
@@ -316,7 +316,7 @@
 namespace BOOST_LOG_VERSION_NAMESPACE {}
 
 using namespace BOOST_LOG_VERSION_NAMESPACE
-#       if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#       if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && !defined(__clang__)
 __attribute__((__strong__))
 #       endif
 ;
Modified: branches/release/libs/log/build/Jamfile.v2
==============================================================================
--- branches/release/libs/log/build/Jamfile.v2	Tue Oct  8 10:29:06 2013	(r86198)
+++ branches/release/libs/log/build/Jamfile.v2	2013-10-08 10:44:59 EDT (Tue, 08 Oct 2013)	(r86199)
@@ -110,6 +110,7 @@
         <toolset>intel-win:<define>_CRT_SECURE_NO_WARNINGS
         <toolset>intel-win:<define>_CRT_SECURE_NO_DEPRECATE
         <toolset>darwin:<cxxflags>-ftemplate-depth-1024
+        <toolset>clang:<cxxflags>-ftemplate-depth-1024
         <toolset>gcc:<cxxflags>-ftemplate-depth-1024
         <toolset>gcc:<cxxflags>-fno-strict-aliasing  # avoids strict aliasing violations in other Boost components
         <toolset>gcc-mingw:<linkflags>-Wl,--enable-auto-import
Modified: branches/release/libs/log/src/core.cpp
==============================================================================
--- branches/release/libs/log/src/core.cpp	Tue Oct  8 10:29:06 2013	(r86198)
+++ branches/release/libs/log/src/core.cpp	2013-10-08 10:44:59 EDT (Tue, 08 Oct 2013)	(r86199)
@@ -252,10 +252,6 @@
         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
Modified: branches/release/libs/log/src/default_filter_factory.cpp
==============================================================================
--- branches/release/libs/log/src/default_filter_factory.cpp	Tue Oct  8 10:29:06 2013	(r86198)
+++ branches/release/libs/log/src/default_filter_factory.cpp	2013-10-08 10:44:59 EDT (Tue, 08 Oct 2013)	(r86199)
@@ -16,15 +16,9 @@
 #if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
 
 #include <string>
-#include <boost/move/core.hpp>
-#include <boost/move/utility.hpp>
-#include <boost/utility/enable_if.hpp>
 #include <boost/mpl/copy.hpp>
-#include <boost/mpl/contains.hpp>
 #include <boost/mpl/back_inserter.hpp>
 #include <boost/spirit/include/qi_core.hpp>
-#include <boost/spirit/include/qi_eoi.hpp>
-#include <boost/spirit/include/qi_as.hpp>
 #include <boost/log/exceptions.hpp>
 #include <boost/log/expressions/predicates/has_attr.hpp>
 #include <boost/log/utility/type_dispatch/standard_types.hpp>
@@ -33,7 +27,6 @@
 #include <boost/log/utility/functional/begins_with.hpp>
 #include <boost/log/utility/functional/ends_with.hpp>
 #include <boost/log/utility/functional/contains.hpp>
-#include <boost/log/utility/functional/as_action.hpp>
 #include <boost/log/detail/code_conversion.hpp>
 #if defined(BOOST_LOG_USE_CHAR) && defined(BOOST_LOG_USE_WCHAR_T)
 #include <boost/fusion/container/set.hpp>
@@ -42,7 +35,6 @@
 #endif
 #include "default_filter_factory.hpp"
 #include "parser_utils.hpp"
-#include "spirit_encoding.hpp"
 #include <boost/log/detail/header.hpp>
 
 namespace qi = boost::spirit::qi;
@@ -100,10 +92,7 @@
     }
 
     template< typename T >
-    typename boost::enable_if<
-        mpl::contains< log::string_types::type, T >,
-        result_type
-    >::type operator() (T const& val) const
+    result_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));
@@ -170,99 +159,32 @@
     {
     }
 
-    template< typename T >
-    typename boost::enable_if<
-        mpl::contains< log::string_types, T >,
-        result_type
-    >::type operator() (T const& val) const
+    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 T >
-    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);
-    }
-
-private:
-    const numeric_type m_numeric_operand;
-};
-
-
-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)
+    template< typename CharT, typename TraitsT >
+    result_type operator() (basic_string_literal< CharT, TraitsT > const& val) const
     {
+        return base_type::operator() (val);
     }
 
-    result_type operator() (long val) const
+    template< typename T >
+    result_type operator() (T const& 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));
+        return relation_type::operator() (val, m_numeric_operand);
     }
 
 private:
-    attribute_name m_name;
-    StringT const& m_operand;
-    filter& m_filter;
+    const numeric_type m_numeric_operand;
 };
 
-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;
-};
+typedef mpl::copy<
+    log::string_types,
+    mpl::back_inserter< log::floating_point_types >
+>::type floating_point_and_string_types;
 
 } // namespace
 
@@ -314,21 +236,27 @@
 {
     typedef log::aux::char_constants< char_type > constants;
 
-    filter f;
     if (rel == constants::begins_with_keyword())
-        on_string_argument< begins_with_fun >(name, f)(arg);
+    {
+        typedef string_predicate< begins_with_fun > predicate;
+        return predicate_wrapper< log::string_types, predicate >(name, predicate(begins_with_fun(), arg));
+    }
     else if (rel == constants::ends_with_keyword())
-        on_string_argument< ends_with_fun >(name, f)(arg);
+    {
+        typedef string_predicate< ends_with_fun > predicate;
+        return predicate_wrapper< log::string_types, predicate >(name, predicate(ends_with_fun(), arg));
+    }
     else if (rel == constants::contains_keyword())
-        on_string_argument< contains_fun >(name, f)(arg);
-    else if (rel == constants::matches_keyword())
-        f = parse_matches_relation(name, arg);
-    else
+    {
+        typedef string_predicate< contains_fun > predicate;
+        return predicate_wrapper< log::string_types, predicate >(name, predicate(contains_fun(), arg));
+    }
+    else if (rel != constants::matches_keyword())
     {
         BOOST_LOG_THROW_DESCR(parse_error, "The custom attribute relation \"" + log::aux::to_narrow(rel) + "\" is not supported");
     }
 
-    return boost::move(f);
+    return parse_matches_relation(name, arg);
 }
 
 
@@ -337,28 +265,33 @@
 template< typename RelationT >
 filter default_filter_factory< CharT >::parse_argument(attribute_name const& name, string_type const& arg)
 {
-    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_;
-
-    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
-    );
+    const char_type* begin = arg.c_str();
+    const char_type* const end = begin + arg.size();
 
-    if (!res)
-        BOOST_LOG_THROW_DESCR(parse_error, "Failed to parse relation operand");
-
-    return boost::move(f);
+    double real_val = 0.0;
+    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));
+        }
+    }
 }
 
 //  Explicitly instantiate factory implementation
Modified: branches/release/libs/log/src/text_file_backend.cpp
==============================================================================
--- branches/release/libs/log/src/text_file_backend.cpp	Tue Oct  8 10:29:06 2013	(r86198)
+++ branches/release/libs/log/src/text_file_backend.cpp	2013-10-08 10:44:59 EDT (Tue, 08 Oct 2013)	(r86199)
@@ -76,6 +76,8 @@
 
 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,
@@ -86,20 +88,20 @@
         filesystem::rename(from, to);
 #else
         // On POSIX rename fails if the target points to a different device
-        try
+        system::error_code ec;
+        filesystem::rename(from, to, ec);
+        if (ec)
         {
-            filesystem::rename(from, to);
-        }
-        catch (system::system_error& e)
-        {
-            if (e.code().value() == system::errc::cross_device_link)
+            if (ec.value() == system::errc::cross_device_link)
             {
                 // Attempt to manually move the file instead
                 filesystem::copy_file(from, to);
                 filesystem::remove(from);
             }
             else
-                throw;
+            {
+                BOOST_THROW_EXCEPTION(filesystem_error("failed to move file to another location", from, to, ec));
+            }
         }
 #endif
     }
@@ -107,8 +109,6 @@
     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,13 +633,19 @@
     //! 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);
 
-        path_string_type file_name = filename_string(src_path);
-        info.m_Path = m_StorageDir / file_name;
+        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;
 
         // Check if the file is already in the target directory
         filesystem::path src_dir = src_path.has_parent_path() ?
@@ -657,7 +663,7 @@
                 do
                 {
                     path_string_type alt_file_name = formatter(file_name, n++);
-                    info.m_Path = m_StorageDir / alt_file_name;
+                    info.m_Path = m_StorageDir / filesystem::path(alt_file_name);
                 }
                 while (filesystem::exists(info.m_Path) && n < (std::numeric_limits< unsigned int >::max)());
             }
@@ -1179,13 +1185,16 @@
 //! 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 = traits_t::default_file_name_pattern();
+        p = filesystem::path(traits_t::default_file_name_pattern());
 
-    path_string_type name_pattern = p.filename().string< path_string_type >();
-    m_pImpl->m_FileNamePattern = name_pattern;
+    m_pImpl->m_FileNamePattern = p.filename();
+    path_string_type name_pattern = m_pImpl->m_FileNamePattern.native();
     m_pImpl->m_StorageDir = filesystem::absolute(p.parent_path());
 
     // Let's try to find the file counter placeholder