$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r85476 - in trunk/libs/log: src test/run
From: andrey.semashev_at_[hidden]
Date: 2013-08-26 14:41:05
Author: andysem
Date: 2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)
New Revision: 85476
URL: http://svn.boost.org/trac/boost/changeset/85476
Log:
Worked around compilation problem with clang. Renamed parsers tests to avoid alarming Windows UAC. Refs #9050.
Added:
   trunk/libs/log/test/run/util_stp_filter_parser.cpp
      - copied unchanged from r85460, trunk/libs/log/test/run/setup_filter_parser.cpp
   trunk/libs/log/test/run/util_stp_formatter_parser.cpp
      - copied unchanged from r85460, trunk/libs/log/test/run/setup_formatter_parser.cpp
   trunk/libs/log/test/run/util_stp_settings_parser.cpp
      - copied unchanged from r85460, trunk/libs/log/test/run/setup_settings_parser.cpp
Deleted:
   trunk/libs/log/test/run/setup_filter_parser.cpp
   trunk/libs/log/test/run/setup_formatter_parser.cpp
   trunk/libs/log/test/run/setup_settings_parser.cpp
Text files modified: 
   trunk/libs/log/src/default_filter_factory.cpp         |    16                                         
   /dev/null                                             |   794 ----------------------------------------
   /dev/null                                             |   257 ------------                            
   /dev/null                                             |   294 --------------                          
   trunk/libs/log/test/run/util_stp_filter_parser.cpp    |   794 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/log/test/run/util_stp_formatter_parser.cpp |   257 ++++++++++++                            
   trunk/libs/log/test/run/util_stp_settings_parser.cpp  |   294 ++++++++++++++                          
   7 files changed, 1355 insertions(+), 1351 deletions(-)
Modified: trunk/libs/log/src/default_filter_factory.cpp
==============================================================================
--- trunk/libs/log/src/default_filter_factory.cpp	Mon Aug 26 07:18:42 2013	(r85475)
+++ trunk/libs/log/src/default_filter_factory.cpp	2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)	(r85476)
@@ -139,10 +139,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
     {
         return relation_type::operator() (val, m_operand);
     }
@@ -173,11 +170,18 @@
     {
     }
 
-    using base_type::operator();
+    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 >
     typename boost::disable_if<
-        mpl::contains< log::string_types::type, T >,
+        mpl::contains< log::string_types, T >,
         result_type
     >::type operator() (T const& val) const
     {
Deleted: trunk/libs/log/test/run/setup_filter_parser.cpp
==============================================================================
--- trunk/libs/log/test/run/setup_filter_parser.cpp	2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)	(r85475)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,794 +0,0 @@
-/*
- *          Copyright Andrey Semashev 2007 - 2013.
- * 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   setup_filter_parser.cpp
- * \author Andrey Semashev
- * \date   24.08.2013
- *
- * \brief  This header contains tests for the filter parser.
- */
-
-#define BOOST_TEST_MODULE setup_filter_parser
-
-#include <string>
-#include <boost/test/unit_test.hpp>
-#include <boost/log/utility/setup/filter_parser.hpp>
-
-#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
-
-#include <boost/shared_ptr.hpp>
-#include <boost/log/exceptions.hpp>
-#include <boost/log/attributes/constant.hpp>
-#include <boost/log/attributes/attribute_set.hpp>
-#include <boost/log/attributes/attribute_value_set.hpp>
-#include <boost/log/expressions/filter.hpp>
-
-namespace logging = boost::log;
-namespace attrs = logging::attributes;
-
-typedef logging::attribute_set attr_set;
-typedef logging::attribute_value_set attr_values;
-
-// Tests for attribute presence check
-BOOST_AUTO_TEST_CASE(attr_presence)
-{
-    attrs::constant< int > attr1(10);
-    attr_set set1, set2, set3;
-
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    set1["MyAttr"] = attr1;
-    attr_values values2(set1, set2, set3);
-    values2.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyAttr%");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter(" % MyAttr % ");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-}
-
-// Tests for integer relation filter
-BOOST_AUTO_TEST_CASE(int_relation)
-{
-    attrs::constant< int > attr1(10);
-    attrs::constant< long > attr2(20);
-    attrs::constant< int > attr3(-2);
-    attr_set set1, set2, set3;
-
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    set1["MyAttr"] = attr1;
-    attr_values values2(set1, set2, set3);
-    values2.freeze();
-
-    set1["MyAttr"] = attr2;
-    attr_values values3(set1, set2, set3);
-    values3.freeze();
-
-    set1["MyAttr"] = attr3;
-    attr_values values4(set1, set2, set3);
-    values4.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% = 10");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(!f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% != 10");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% < 20");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% < -7");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(!f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > 10");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(!f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > -5");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% <= 20");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% >= 20");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(!f(values4));
-    }
-}
-
-// Tests for floating point relation filter
-BOOST_AUTO_TEST_CASE(fp_relation)
-{
-    attrs::constant< float > attr1(2.5);
-    attrs::constant< float > attr2(8.8);
-    attrs::constant< double > attr3(-9.1);
-    attrs::constant< float > attr4(0);
-    attr_set set1, set2, set3;
-
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    set1["MyAttr"] = attr1;
-    attr_values values2(set1, set2, set3);
-    values2.freeze();
-
-    set1["MyAttr"] = attr2;
-    attr_values values3(set1, set2, set3);
-    values3.freeze();
-
-    set1["MyAttr"] = attr3;
-    attr_values values4(set1, set2, set3);
-    values4.freeze();
-
-    set1["MyAttr"] = attr4;
-    attr_values values5(set1, set2, set3);
-    values5.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% = 10.3");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(!f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% != 10");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% < 5.5");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% < -7");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > 5.6");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(!f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > -5");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(!f(values4));
-        BOOST_CHECK(f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% <= 20");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% >= 20");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(!f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-}
-
-// Tests for string relation filter
-BOOST_AUTO_TEST_CASE(string_relation)
-{
-    attrs::constant< std::string > attr1("hello");
-    attr_set set1, set2, set3;
-
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    set1["MyStr"] = attr1;
-    attr_values values2(set1, set2, set3);
-    values2.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyStr% = hello");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% = \"hello\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter(" % MyStr % = \"hello\" ");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% = \" hello\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% = \"hello \"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% = \"world\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% = \"Hello\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% != hello");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% != world");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% < world");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% > world");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-
-    // Check that strings that look like numbers can still be used in filters
-    attrs::constant< std::string > attr2("55");
-    set1["MyStr"] = attr2;
-    attr_values values3(set1, set2, set3);
-    values3.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyStr% = \"55\"");
-        BOOST_CHECK(f(values3));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% < \"555\"");
-        BOOST_CHECK(f(values3));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% > \"44\"");
-        BOOST_CHECK(f(values3));
-    }
-}
-
-// Tests for multiple expression filter
-BOOST_AUTO_TEST_CASE(multi_expression)
-{
-    attrs::constant< int > attr1(10);
-    attrs::constant< int > attr2(20);
-    attrs::constant< std::string > attr3("hello");
-    attrs::constant< std::string > attr4("world");
-    attr_set set1, set2, set3;
-
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    set1["MyAttr"] = attr1;
-    attr_values values2(set1, set2, set3);
-    values2.freeze();
-
-    set1["MyAttr"] = attr2;
-    attr_values values3(set1, set2, set3);
-    values3.freeze();
-
-    set1["MyStr"] = attr3;
-    attr_values values4(set1, set2, set3);
-    values4.freeze();
-
-    set1["MyStr"] = attr4;
-    attr_values values5(set1, set2, set3);
-    values5.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% = 10 & %MyStr% = \"hello\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(!f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > 10 & %MyStr% = \"hello\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > 10 and %MyStr% = \"hello\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% = 10 | %MyStr% = \"world\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(!f(values4));
-        BOOST_CHECK(f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > 10 | %MyStr% = \"world\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% = 10 or %MyStr% = \"world\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(!f(values4));
-        BOOST_CHECK(f(values5));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyAttr% > 0 & %MyAttr% < 20 | %MyStr% = \"hello\"");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(!f(values3));
-        BOOST_CHECK(f(values4));
-        BOOST_CHECK(!f(values5));
-    }
-}
-
-// Tests for negation
-BOOST_AUTO_TEST_CASE(negation)
-{
-    attrs::constant< int > attr1(10);
-    attrs::constant< int > attr2(20);
-    attrs::constant< std::string > attr3("hello");
-    attr_set set1, set2, set3;
-
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    set1["MyAttr"] = attr1;
-    attr_values values2(set1, set2, set3);
-    values2.freeze();
-
-    set1["MyAttr"] = attr2;
-    attr_values values3(set1, set2, set3);
-    values3.freeze();
-
-    set1["MyStr"] = attr3;
-    attr_values values4(set1, set2, set3);
-    values4.freeze();
-
-    // Test with presence filter
-    {
-        logging::filter f = logging::parse_filter("!%MyAttr%");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter(" ! % MyAttr % ");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("not %MyAttr%");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(!f(values2));
-    }
-    {
-        logging::filter f = logging::parse_filter("!!%MyAttr%");
-        BOOST_CHECK(!f(values1));
-        BOOST_CHECK(f(values2));
-    }
-
-    // Test with relations
-    {
-        logging::filter f = logging::parse_filter("!(%MyAttr% = 10)");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-    }
-    {
-        logging::filter f = logging::parse_filter("not ( %MyAttr% = 10 ) ");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-    }
-    {
-        logging::filter f = logging::parse_filter("!(%MyAttr% < 20)");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-    }
-
-    // Test with multiple subexpressions
-    {
-        logging::filter f = logging::parse_filter("!(%MyAttr% = 20 & %MyStr% = hello)");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(!f(values4));
-    }
-    {
-        logging::filter f = logging::parse_filter("!(%MyAttr% = 10 | %MyStr% = hello)");
-        BOOST_CHECK(f(values1));
-        BOOST_CHECK(!f(values2));
-        BOOST_CHECK(f(values3));
-        BOOST_CHECK(!f(values4));
-    }
-}
-
-// Tests for begins_with relation filter
-BOOST_AUTO_TEST_CASE(begins_with_relation)
-{
-    attrs::constant< std::string > attr1("abcdABCD");
-    attr_set set1, set2, set3;
-
-    set1["MyStr"] = attr1;
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyStr% begins_with \"abcd\"");
-        BOOST_CHECK(f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% begins_with \"ABCD\"");
-        BOOST_CHECK(!f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% begins_with \"efgh\"");
-        BOOST_CHECK(!f(values1));
-    }
-}
-
-// Tests for ends_with relation filter
-BOOST_AUTO_TEST_CASE(ends_with_relation)
-{
-    attrs::constant< std::string > attr1("abcdABCD");
-    attr_set set1, set2, set3;
-
-    set1["MyStr"] = attr1;
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyStr% ends_with \"abcd\"");
-        BOOST_CHECK(!f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% ends_with \"ABCD\"");
-        BOOST_CHECK(f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% ends_with \"efgh\"");
-        BOOST_CHECK(!f(values1));
-    }
-}
-
-// Tests for contains relation filter
-BOOST_AUTO_TEST_CASE(contains_relation)
-{
-    attrs::constant< std::string > attr1("abcdABCD");
-    attr_set set1, set2, set3;
-
-    set1["MyStr"] = attr1;
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyStr% contains \"abcd\"");
-        BOOST_CHECK(f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% contains \"ABCD\"");
-        BOOST_CHECK(f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% contains \"cdAB\"");
-        BOOST_CHECK(f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% contains \"efgh\"");
-        BOOST_CHECK(!f(values1));
-    }
-}
-
-// Tests for regex matching relation filter
-BOOST_AUTO_TEST_CASE(matches_relation)
-{
-    attrs::constant< std::string > attr1("hello");
-    attr_set set1, set2, set3;
-
-    set1["MyStr"] = attr1;
-    attr_values values1(set1, set2, set3);
-    values1.freeze();
-
-    {
-        logging::filter f = logging::parse_filter("%MyStr% matches \"h.*\"");
-        BOOST_CHECK(f(values1));
-    }
-    {
-        logging::filter f = logging::parse_filter("%MyStr% matches \"w.*\"");
-        BOOST_CHECK(!f(values1));
-    }
-}
-
-namespace {
-
-class test_filter_factory :
-    public logging::filter_factory< char >
-{
-private:
-    typedef logging::filter_factory< char > base_type;
-
-public:
-    enum relation_type
-    {
-        custom,
-        exists,
-        equality,
-        inequality,
-        less,
-        greater,
-        less_or_equal,
-        greater_or_equal
-    };
-
-    typedef base_type::string_type string_type;
-
-public:
-    explicit test_filter_factory(logging::attribute_name const& name) : m_name(name), m_rel(custom), m_called(false)
-    {
-    }
-
-    void expect_relation(relation_type rel, string_type const& arg)
-    {
-        m_rel = rel;
-        m_arg = arg;
-        m_custom_rel.clear();
-    }
-
-    void expect_relation(string_type const& rel, string_type const& arg)
-    {
-        m_rel = custom;
-        m_arg = arg;
-        m_custom_rel = rel;
-    }
-
-    void check_called()
-    {
-        BOOST_CHECK(m_called);
-        m_called = false;
-    }
-
-    logging::filter on_exists_test(logging::attribute_name const& name)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, exists);
-        m_called = true;
-        return logging::filter();
-    }
-    logging::filter on_equality_relation(logging::attribute_name const& name, string_type const& arg)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, equality);
-        BOOST_CHECK_EQUAL(m_arg, arg);
-        m_called = true;
-        return logging::filter();
-    }
-    logging::filter on_inequality_relation(logging::attribute_name const& name, string_type const& arg)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, inequality);
-        BOOST_CHECK_EQUAL(m_arg, arg);
-        m_called = true;
-        return logging::filter();
-    }
-    logging::filter on_less_relation(logging::attribute_name const& name, string_type const& arg)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, less);
-        BOOST_CHECK_EQUAL(m_arg, arg);
-        m_called = true;
-        return logging::filter();
-    }
-    logging::filter on_greater_relation(logging::attribute_name const& name, string_type const& arg)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, greater);
-        BOOST_CHECK_EQUAL(m_arg, arg);
-        m_called = true;
-        return logging::filter();
-    }
-    logging::filter on_less_or_equal_relation(logging::attribute_name const& name, string_type const& arg)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, less_or_equal);
-        BOOST_CHECK_EQUAL(m_arg, arg);
-        m_called = true;
-        return logging::filter();
-    }
-    logging::filter on_greater_or_equal_relation(logging::attribute_name const& name, string_type const& arg)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, greater_or_equal);
-        BOOST_CHECK_EQUAL(m_arg, arg);
-        m_called = true;
-        return logging::filter();
-    }
-    logging::filter on_custom_relation(logging::attribute_name const& name, string_type const& rel, string_type const& arg)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_rel, custom);
-        BOOST_CHECK_EQUAL(m_custom_rel, rel);
-        BOOST_CHECK_EQUAL(m_arg, arg);
-        m_called = true;
-        return logging::filter();
-    }
-
-private:
-    logging::attribute_name m_name;
-    relation_type m_rel;
-    string_type m_arg;
-    string_type m_custom_rel;
-    bool m_called;
-};
-
-} // namespace
-
-// Tests for filter factory
-BOOST_AUTO_TEST_CASE(filter_factory)
-{
-    logging::attribute_name attr_name("MyCustomAttr");
-    boost::shared_ptr< test_filter_factory > factory(new test_filter_factory(attr_name));
-    logging::register_filter_factory(attr_name, factory);
-
-    BOOST_TEST_CHECKPOINT("filter_factory::exists");
-    factory->expect_relation(test_filter_factory::exists, "");
-    logging::parse_filter("%MyCustomAttr%");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::equality");
-    factory->expect_relation(test_filter_factory::equality, "15");
-    logging::parse_filter("%MyCustomAttr% = 15");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::equality");
-    factory->expect_relation(test_filter_factory::equality, "hello");
-    logging::parse_filter("%MyCustomAttr% = hello");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::equality");
-    factory->expect_relation(test_filter_factory::equality, "hello");
-    logging::parse_filter("%MyCustomAttr% = \"hello\"");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::equality");
-    factory->expect_relation(test_filter_factory::equality, "hello\nworld");
-    logging::parse_filter("%MyCustomAttr% = \"hello\\nworld\"");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::inequality");
-    factory->expect_relation(test_filter_factory::inequality, "hello");
-    logging::parse_filter("%MyCustomAttr% != \"hello\"");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::less");
-    factory->expect_relation(test_filter_factory::less, "hello");
-    logging::parse_filter("%MyCustomAttr% < \"hello\"");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::greater");
-    factory->expect_relation(test_filter_factory::greater, "hello");
-    logging::parse_filter("%MyCustomAttr% > \"hello\"");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::less_or_equal");
-    factory->expect_relation(test_filter_factory::less_or_equal, "hello");
-    logging::parse_filter("%MyCustomAttr% <= \"hello\"");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::greater_or_equal");
-    factory->expect_relation(test_filter_factory::greater_or_equal, "hello");
-    logging::parse_filter("%MyCustomAttr% >= \"hello\"");
-    factory->check_called();
-
-    BOOST_TEST_CHECKPOINT("filter_factory::custom");
-    factory->expect_relation("my_relation", "hello");
-    logging::parse_filter("%MyCustomAttr% my_relation \"hello\"");
-    factory->check_called();
-}
-
-// Tests for invalid filters
-BOOST_AUTO_TEST_CASE(invalid)
-{
-    BOOST_CHECK_THROW(logging::parse_filter("%MyStr"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("MyStr%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% abcd"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("(%MyStr%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%MyStr%)"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("!"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("!()"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("\"xxx\" == %MyStr%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% == \"xxx"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% === \"xxx\""), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% ! \"xxx\""), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% %MyStr2%"), logging::parse_error);
-}
-
-#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
Deleted: trunk/libs/log/test/run/setup_formatter_parser.cpp
==============================================================================
--- trunk/libs/log/test/run/setup_formatter_parser.cpp	2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)	(r85475)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,257 +0,0 @@
-/*
- *          Copyright Andrey Semashev 2007 - 2013.
- * 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   setup_formatter_parser.cpp
- * \author Andrey Semashev
- * \date   25.08.2013
- *
- * \brief  This header contains tests for the formatter parser.
- */
-
-#define BOOST_TEST_MODULE setup_formatter_parser
-
-#include <string>
-#include <boost/test/unit_test.hpp>
-#include <boost/log/utility/setup/formatter_parser.hpp>
-
-#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
-
-#include <boost/shared_ptr.hpp>
-#include <boost/log/exceptions.hpp>
-#include <boost/log/core/record.hpp>
-#include <boost/log/core/record_view.hpp>
-#include <boost/log/attributes/constant.hpp>
-#include <boost/log/attributes/attribute_set.hpp>
-#include <boost/log/attributes/attribute_value_set.hpp>
-#include <boost/log/utility/formatting_ostream.hpp>
-#include <boost/log/expressions/formatter.hpp>
-#include "make_record.hpp"
-
-namespace logging = boost::log;
-namespace attrs = logging::attributes;
-
-typedef logging::attribute_set attr_set;
-typedef logging::attribute_value_set attr_values;
-typedef logging::record_view record_view;
-
-typedef logging::basic_formatting_ostream< char > osstream;
-typedef logging::basic_formatter< char > formatter;
-
-// Tests for simple attribute placeholders in formatters
-BOOST_AUTO_TEST_CASE(attr_placeholders)
-{
-    attrs::constant< int > attr1(10);
-    attrs::constant< std::string > attr2("hello");
-    attr_set set1;
-
-    set1["MyAttr"] = attr1;
-    set1["MyStr"] = attr2;
-
-    record_view rec = make_record_view(set1);
-
-    {
-        formatter f = logging::parse_formatter("String literal");
-        std::string str1, str2;
-        osstream strm1(str1), strm2(str2);
-        f(rec, strm1);
-        strm2 << "String literal";
-        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
-    }
-    {
-        formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MyStr: %MyStr%");
-        std::string str1, str2;
-        osstream strm1(str1), strm2(str2);
-        f(rec, strm1);
-        strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
-        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
-    }
-    {
-        formatter f = logging::parse_formatter("MyAttr: % MyAttr %, MyStr: % MyStr %");
-        std::string str1, str2;
-        osstream strm1(str1), strm2(str2);
-        f(rec, strm1);
-        strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
-        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
-    }
-    {
-        formatter f = logging::parse_formatter("%MyAttr%%MyStr%");
-        std::string str1, str2;
-        osstream strm1(str1), strm2(str2);
-        f(rec, strm1);
-        strm2 << attr1.get() << attr2.get();
-        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
-    }
-    {
-        formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MissingAttr: %MissingAttr%");
-        std::string str1, str2;
-        osstream strm1(str1), strm2(str2);
-        f(rec, strm1);
-        strm2 << "MyAttr: " << attr1.get() << ", MissingAttr: ";
-        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
-    }
-}
-
-namespace {
-
-class test_formatter_factory :
-    public logging::formatter_factory< char >
-{
-private:
-    typedef logging::formatter_factory< char > base_type;
-
-public:
-    typedef base_type::string_type string_type;
-    typedef base_type::args_map args_map;
-    typedef base_type::formatter_type formatter_type;
-
-public:
-    explicit test_formatter_factory(logging::attribute_name const& name) : m_name(name), m_called(false)
-    {
-    }
-
-    void expect_args(args_map const& args)
-    {
-        m_args = args;
-    }
-
-    void check_called()
-    {
-        BOOST_CHECK(m_called);
-        m_called = false;
-    }
-
-    formatter_type create_formatter(logging::attribute_name const& name, args_map const& args)
-    {
-        BOOST_CHECK_EQUAL(m_name, name);
-        BOOST_CHECK_EQUAL(m_args.size(), args.size());
-
-        for (args_map::const_iterator it = m_args.begin(), end = m_args.end(); it != end; ++it)
-        {
-            args_map::const_iterator parsed_it = args.find(it->first);
-            if (parsed_it != args.end())
-            {
-                BOOST_TEST_CHECKPOINT(("Arg: " + it->first));
-                BOOST_CHECK_EQUAL(it->second, parsed_it->second);
-            }
-            else
-            {
-                BOOST_ERROR(("Arg not found: " + it->first));
-            }
-        }
-
-        m_called = true;
-        return formatter_type();
-    }
-
-private:
-    logging::attribute_name m_name;
-    args_map m_args;
-    bool m_called;
-};
-
-} // namespace
-
-// Tests for formatter factory
-BOOST_AUTO_TEST_CASE(formatter_factory)
-{
-    logging::attribute_name attr_name("MyCustomAttr");
-    boost::shared_ptr< test_formatter_factory > factory(new test_formatter_factory(attr_name));
-    logging::register_formatter_factory(attr_name, factory);
-
-    {
-        BOOST_TEST_CHECKPOINT("formatter 1");
-        test_formatter_factory::args_map args;
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr%");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 2");
-        test_formatter_factory::args_map args;
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr()%");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 3");
-        test_formatter_factory::args_map args;
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr ( ) %");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 4");
-        test_formatter_factory::args_map args;
-        args["param1"] = "10";
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr(param1=10)%");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 5");
-        test_formatter_factory::args_map args;
-        args["param1"] = "10";
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: % MyCustomAttr ( param1 = 10 ) % ");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 6");
-        test_formatter_factory::args_map args;
-        args["param1"] = " 10 ";
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr(param1=\" 10 \")%");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 7");
-        test_formatter_factory::args_map args;
-        args["param1"] = "10";
-        args["param2"] = "abcd";
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = abcd)%");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 8");
-        test_formatter_factory::args_map args;
-        args["param1"] = "10";
-        args["param2"] = "abcd";
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr(param1=10,param2=abcd)%");
-        factory->check_called();
-    }
-    {
-        BOOST_TEST_CHECKPOINT("formatter 9");
-        test_formatter_factory::args_map args;
-        args["param1"] = "10";
-        args["param2"] = "abcd";
-        args["param_last"] = "-2.2";
-        factory->expect_args(args);
-        logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = \"abcd\", param_last = -2.2)%");
-        factory->check_called();
-    }
-}
-
-// Tests for invalid formatters
-BOOST_AUTO_TEST_CASE(invalid)
-{
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("MyStr%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr)%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param)%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=)%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(=value)%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param,param2)%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,)%"), logging::parse_error);
-    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,param2)%"), logging::parse_error);
-}
-
-#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
Deleted: trunk/libs/log/test/run/setup_settings_parser.cpp
==============================================================================
--- trunk/libs/log/test/run/setup_settings_parser.cpp	2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)	(r85475)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,294 +0,0 @@
-/*
- *          Copyright Andrey Semashev 2007 - 2013.
- * 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   setup_settings_parser.cpp
- * \author Andrey Semashev
- * \date   25.08.2013
- *
- * \brief  This header contains tests for the settings parser.
- */
-
-#define BOOST_TEST_MODULE setup_settings_parser
-
-#include <string>
-#include <sstream>
-#include <boost/test/unit_test.hpp>
-#include <boost/log/utility/setup/settings_parser.hpp>
-
-#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS)
-
-#include <boost/log/exceptions.hpp>
-
-namespace logging = boost::log;
-
-typedef logging::basic_settings< char > settings;
-
-// Tests for single-level settings
-BOOST_AUTO_TEST_CASE(single_level)
-{
-    {
-        std::istringstream strm
-        (
-            "[Section1]\n"
-            "\n"
-            "Param1 = Value1\n"
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        settings s = logging::parse_settings(strm);
-
-        BOOST_CHECK(s.has_section("Section1"));
-        BOOST_CHECK(s.has_section("Section2"));
-        BOOST_CHECK(!s.has_section("Section3"));
-
-        BOOST_CHECK(s.has_parameter("Section1", "Param1"));
-        BOOST_CHECK(s.has_parameter("Section1", "Param2"));
-
-        BOOST_CHECK(s.has_parameter("Section2", "Param1"));
-        BOOST_CHECK(s.has_parameter("Section2", "Param2"));
-
-        BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
-        BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
-
-        BOOST_CHECK_EQUAL(s["Section2"]["Param1"].or_default(std::string()), "10");
-        BOOST_CHECK_EQUAL(s["Section2"]["Param2"].or_default(std::string()), "-2.2");
-    }
-}
-
-// Tests for multi-level settings
-BOOST_AUTO_TEST_CASE(multi_level)
-{
-    {
-        std::istringstream strm
-        (
-            "  [Section1]\n"
-            "\n"
-            "Param1 = Value1 \n"
-            "Param2=\"hello, \\\"world\\\"\"   \n"
-            "\n"
-            "[Section1.Subsection2]  \n"
-            "\n"
-            "Param1=10\n"
-            "Param2=-2.2\n"
-        );
-        settings s = logging::parse_settings(strm);
-
-        BOOST_CHECK(s.has_section("Section1"));
-        BOOST_CHECK(s.has_section("Section1.Subsection2"));
-        BOOST_CHECK(!s.has_section("Subsection2"));
-
-        BOOST_CHECK(s.has_parameter("Section1", "Param1"));
-        BOOST_CHECK(s.has_parameter("Section1", "Param2"));
-
-        BOOST_CHECK(s.has_parameter("Section1.Subsection2", "Param1"));
-        BOOST_CHECK(s.has_parameter("Section1.Subsection2", "Param2"));
-        BOOST_CHECK(!s.has_parameter("Subsection2", "Param1"));
-        BOOST_CHECK(!s.has_parameter("Subsection2", "Param2"));
-
-        BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
-        BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
-
-        BOOST_CHECK_EQUAL(s["Section1.Subsection2"]["Param1"].or_default(std::string()), "10");
-        BOOST_CHECK_EQUAL(s["Section1.Subsection2"]["Param2"].or_default(std::string()), "-2.2");
-    }
-}
-
-// Tests for comments
-BOOST_AUTO_TEST_CASE(comments)
-{
-    {
-        std::istringstream strm
-        (
-            "# Some comment\n"
-            "[ Section1 ] # another comment\n"
-            "\n"
-            "Param1 = Value1 ### yet another comment \n"
-            "Param2=\"hello, \\\"world\\\"\" # comment after a quoted string\n"
-            "\n"
-            "[ Section2 ]\n"
-            "\n"
-            "Param1=10#comment after a number\n"
-            "Param2=-2.2#comment without a terminating newline"
-            "\n"
-            "#[Section3]\n"
-            "#\n"
-            "#Param1=10#comment after a number\n"
-            "#Param2=-2.2#comment without a terminating newline"
-        );
-        settings s = logging::parse_settings(strm);
-
-        BOOST_CHECK(s.has_section("Section1"));
-        BOOST_CHECK(s.has_section("Section2"));
-        BOOST_CHECK(!s.has_section("Section3"));
-
-        BOOST_CHECK(s.has_parameter("Section1", "Param1"));
-        BOOST_CHECK(s.has_parameter("Section1", "Param2"));
-
-        BOOST_CHECK(s.has_parameter("Section2", "Param1"));
-        BOOST_CHECK(s.has_parameter("Section2", "Param2"));
-
-        BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
-        BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
-
-        BOOST_CHECK_EQUAL(s["Section2"]["Param1"].or_default(std::string()), "10");
-        BOOST_CHECK_EQUAL(s["Section2"]["Param2"].or_default(std::string()), "-2.2");
-    }
-}
-
-// Tests for invalid settings
-BOOST_AUTO_TEST_CASE(invalid)
-{
-    {
-        std::istringstream strm
-        (
-            "Param1 = Value1\n" // parameters outside sections
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "[Section1\n" // missing closing brace
-            "\n"
-            "Param1 = Value1\n"
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "Section1]\n" // missing opening brace
-            "\n"
-            "Param1 = Value1\n"
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "[Section1=xyz]\n" // invalid characters in the section name
-            "\n"
-            "Param1 = Value1\n"
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "[Section1# hello?]\n" // invalid characters in the section name
-            "\n"
-            "Param1 = Value1\n"
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "(Section1)\n" // invalid braces
-            "\n"
-            "Param1 = Value1\n"
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "[Section1]\n"
-            "\n"
-            "Param1 =\n" // no parameter value
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "[Section1]\n"
-            "\n"
-            "Param1\n" // no parameter value
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "[Section1]\n"
-            "\n"
-            "Param1 = Value1\n"
-            "Param2 = \"hello, \\\"world\\\"\n" // unterminated quote
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-    {
-        std::istringstream strm
-        (
-            "[Section1]\n"
-            "\n"
-            "Param1 = Value1 Value2\n" // multi-word value
-            "Param2 = \"hello, \\\"world\\\"\"\n"
-            "\n"
-            "[Section2]\n"
-            "\n"
-            "Param1 = 10\n"
-            "Param2 = -2.2\n"
-        );
-        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
-    }
-}
-
-#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS)
Copied: trunk/libs/log/test/run/util_stp_filter_parser.cpp (from r85460, trunk/libs/log/test/run/setup_filter_parser.cpp)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/libs/log/test/run/util_stp_filter_parser.cpp	2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)	(r85476, copy of r85460, trunk/libs/log/test/run/setup_filter_parser.cpp)
@@ -0,0 +1,794 @@
+/*
+ *          Copyright Andrey Semashev 2007 - 2013.
+ * 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   setup_filter_parser.cpp
+ * \author Andrey Semashev
+ * \date   24.08.2013
+ *
+ * \brief  This header contains tests for the filter parser.
+ */
+
+#define BOOST_TEST_MODULE setup_filter_parser
+
+#include <string>
+#include <boost/test/unit_test.hpp>
+#include <boost/log/utility/setup/filter_parser.hpp>
+
+#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+
+#include <boost/shared_ptr.hpp>
+#include <boost/log/exceptions.hpp>
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/attributes/attribute_set.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/expressions/filter.hpp>
+
+namespace logging = boost::log;
+namespace attrs = logging::attributes;
+
+typedef logging::attribute_set attr_set;
+typedef logging::attribute_value_set attr_values;
+
+// Tests for attribute presence check
+BOOST_AUTO_TEST_CASE(attr_presence)
+{
+    attrs::constant< int > attr1(10);
+    attr_set set1, set2, set3;
+
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    set1["MyAttr"] = attr1;
+    attr_values values2(set1, set2, set3);
+    values2.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyAttr%");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter(" % MyAttr % ");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+}
+
+// Tests for integer relation filter
+BOOST_AUTO_TEST_CASE(int_relation)
+{
+    attrs::constant< int > attr1(10);
+    attrs::constant< long > attr2(20);
+    attrs::constant< int > attr3(-2);
+    attr_set set1, set2, set3;
+
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    set1["MyAttr"] = attr1;
+    attr_values values2(set1, set2, set3);
+    values2.freeze();
+
+    set1["MyAttr"] = attr2;
+    attr_values values3(set1, set2, set3);
+    values3.freeze();
+
+    set1["MyAttr"] = attr3;
+    attr_values values4(set1, set2, set3);
+    values4.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% = 10");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(!f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% != 10");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% < 20");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% < -7");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(!f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > 10");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(!f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > -5");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% <= 20");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% >= 20");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(!f(values4));
+    }
+}
+
+// Tests for floating point relation filter
+BOOST_AUTO_TEST_CASE(fp_relation)
+{
+    attrs::constant< float > attr1(2.5);
+    attrs::constant< float > attr2(8.8);
+    attrs::constant< double > attr3(-9.1);
+    attrs::constant< float > attr4(0);
+    attr_set set1, set2, set3;
+
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    set1["MyAttr"] = attr1;
+    attr_values values2(set1, set2, set3);
+    values2.freeze();
+
+    set1["MyAttr"] = attr2;
+    attr_values values3(set1, set2, set3);
+    values3.freeze();
+
+    set1["MyAttr"] = attr3;
+    attr_values values4(set1, set2, set3);
+    values4.freeze();
+
+    set1["MyAttr"] = attr4;
+    attr_values values5(set1, set2, set3);
+    values5.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% = 10.3");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(!f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% != 10");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% < 5.5");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% < -7");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > 5.6");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(!f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > -5");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(!f(values4));
+        BOOST_CHECK(f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% <= 20");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% >= 20");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(!f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+}
+
+// Tests for string relation filter
+BOOST_AUTO_TEST_CASE(string_relation)
+{
+    attrs::constant< std::string > attr1("hello");
+    attr_set set1, set2, set3;
+
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    set1["MyStr"] = attr1;
+    attr_values values2(set1, set2, set3);
+    values2.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyStr% = hello");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% = \"hello\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter(" % MyStr % = \"hello\" ");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% = \" hello\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% = \"hello \"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% = \"world\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% = \"Hello\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% != hello");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% != world");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% < world");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% > world");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+
+    // Check that strings that look like numbers can still be used in filters
+    attrs::constant< std::string > attr2("55");
+    set1["MyStr"] = attr2;
+    attr_values values3(set1, set2, set3);
+    values3.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyStr% = \"55\"");
+        BOOST_CHECK(f(values3));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% < \"555\"");
+        BOOST_CHECK(f(values3));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% > \"44\"");
+        BOOST_CHECK(f(values3));
+    }
+}
+
+// Tests for multiple expression filter
+BOOST_AUTO_TEST_CASE(multi_expression)
+{
+    attrs::constant< int > attr1(10);
+    attrs::constant< int > attr2(20);
+    attrs::constant< std::string > attr3("hello");
+    attrs::constant< std::string > attr4("world");
+    attr_set set1, set2, set3;
+
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    set1["MyAttr"] = attr1;
+    attr_values values2(set1, set2, set3);
+    values2.freeze();
+
+    set1["MyAttr"] = attr2;
+    attr_values values3(set1, set2, set3);
+    values3.freeze();
+
+    set1["MyStr"] = attr3;
+    attr_values values4(set1, set2, set3);
+    values4.freeze();
+
+    set1["MyStr"] = attr4;
+    attr_values values5(set1, set2, set3);
+    values5.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% = 10 & %MyStr% = \"hello\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(!f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > 10 & %MyStr% = \"hello\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > 10 and %MyStr% = \"hello\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% = 10 | %MyStr% = \"world\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(!f(values4));
+        BOOST_CHECK(f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > 10 | %MyStr% = \"world\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% = 10 or %MyStr% = \"world\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(!f(values4));
+        BOOST_CHECK(f(values5));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyAttr% > 0 & %MyAttr% < 20 | %MyStr% = \"hello\"");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(!f(values3));
+        BOOST_CHECK(f(values4));
+        BOOST_CHECK(!f(values5));
+    }
+}
+
+// Tests for negation
+BOOST_AUTO_TEST_CASE(negation)
+{
+    attrs::constant< int > attr1(10);
+    attrs::constant< int > attr2(20);
+    attrs::constant< std::string > attr3("hello");
+    attr_set set1, set2, set3;
+
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    set1["MyAttr"] = attr1;
+    attr_values values2(set1, set2, set3);
+    values2.freeze();
+
+    set1["MyAttr"] = attr2;
+    attr_values values3(set1, set2, set3);
+    values3.freeze();
+
+    set1["MyStr"] = attr3;
+    attr_values values4(set1, set2, set3);
+    values4.freeze();
+
+    // Test with presence filter
+    {
+        logging::filter f = logging::parse_filter("!%MyAttr%");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter(" ! % MyAttr % ");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("not %MyAttr%");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(!f(values2));
+    }
+    {
+        logging::filter f = logging::parse_filter("!!%MyAttr%");
+        BOOST_CHECK(!f(values1));
+        BOOST_CHECK(f(values2));
+    }
+
+    // Test with relations
+    {
+        logging::filter f = logging::parse_filter("!(%MyAttr% = 10)");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+    }
+    {
+        logging::filter f = logging::parse_filter("not ( %MyAttr% = 10 ) ");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+    }
+    {
+        logging::filter f = logging::parse_filter("!(%MyAttr% < 20)");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+    }
+
+    // Test with multiple subexpressions
+    {
+        logging::filter f = logging::parse_filter("!(%MyAttr% = 20 & %MyStr% = hello)");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(!f(values4));
+    }
+    {
+        logging::filter f = logging::parse_filter("!(%MyAttr% = 10 | %MyStr% = hello)");
+        BOOST_CHECK(f(values1));
+        BOOST_CHECK(!f(values2));
+        BOOST_CHECK(f(values3));
+        BOOST_CHECK(!f(values4));
+    }
+}
+
+// Tests for begins_with relation filter
+BOOST_AUTO_TEST_CASE(begins_with_relation)
+{
+    attrs::constant< std::string > attr1("abcdABCD");
+    attr_set set1, set2, set3;
+
+    set1["MyStr"] = attr1;
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyStr% begins_with \"abcd\"");
+        BOOST_CHECK(f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% begins_with \"ABCD\"");
+        BOOST_CHECK(!f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% begins_with \"efgh\"");
+        BOOST_CHECK(!f(values1));
+    }
+}
+
+// Tests for ends_with relation filter
+BOOST_AUTO_TEST_CASE(ends_with_relation)
+{
+    attrs::constant< std::string > attr1("abcdABCD");
+    attr_set set1, set2, set3;
+
+    set1["MyStr"] = attr1;
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyStr% ends_with \"abcd\"");
+        BOOST_CHECK(!f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% ends_with \"ABCD\"");
+        BOOST_CHECK(f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% ends_with \"efgh\"");
+        BOOST_CHECK(!f(values1));
+    }
+}
+
+// Tests for contains relation filter
+BOOST_AUTO_TEST_CASE(contains_relation)
+{
+    attrs::constant< std::string > attr1("abcdABCD");
+    attr_set set1, set2, set3;
+
+    set1["MyStr"] = attr1;
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyStr% contains \"abcd\"");
+        BOOST_CHECK(f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% contains \"ABCD\"");
+        BOOST_CHECK(f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% contains \"cdAB\"");
+        BOOST_CHECK(f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% contains \"efgh\"");
+        BOOST_CHECK(!f(values1));
+    }
+}
+
+// Tests for regex matching relation filter
+BOOST_AUTO_TEST_CASE(matches_relation)
+{
+    attrs::constant< std::string > attr1("hello");
+    attr_set set1, set2, set3;
+
+    set1["MyStr"] = attr1;
+    attr_values values1(set1, set2, set3);
+    values1.freeze();
+
+    {
+        logging::filter f = logging::parse_filter("%MyStr% matches \"h.*\"");
+        BOOST_CHECK(f(values1));
+    }
+    {
+        logging::filter f = logging::parse_filter("%MyStr% matches \"w.*\"");
+        BOOST_CHECK(!f(values1));
+    }
+}
+
+namespace {
+
+class test_filter_factory :
+    public logging::filter_factory< char >
+{
+private:
+    typedef logging::filter_factory< char > base_type;
+
+public:
+    enum relation_type
+    {
+        custom,
+        exists,
+        equality,
+        inequality,
+        less,
+        greater,
+        less_or_equal,
+        greater_or_equal
+    };
+
+    typedef base_type::string_type string_type;
+
+public:
+    explicit test_filter_factory(logging::attribute_name const& name) : m_name(name), m_rel(custom), m_called(false)
+    {
+    }
+
+    void expect_relation(relation_type rel, string_type const& arg)
+    {
+        m_rel = rel;
+        m_arg = arg;
+        m_custom_rel.clear();
+    }
+
+    void expect_relation(string_type const& rel, string_type const& arg)
+    {
+        m_rel = custom;
+        m_arg = arg;
+        m_custom_rel = rel;
+    }
+
+    void check_called()
+    {
+        BOOST_CHECK(m_called);
+        m_called = false;
+    }
+
+    logging::filter on_exists_test(logging::attribute_name const& name)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, exists);
+        m_called = true;
+        return logging::filter();
+    }
+    logging::filter on_equality_relation(logging::attribute_name const& name, string_type const& arg)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, equality);
+        BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
+        return logging::filter();
+    }
+    logging::filter on_inequality_relation(logging::attribute_name const& name, string_type const& arg)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, inequality);
+        BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
+        return logging::filter();
+    }
+    logging::filter on_less_relation(logging::attribute_name const& name, string_type const& arg)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, less);
+        BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
+        return logging::filter();
+    }
+    logging::filter on_greater_relation(logging::attribute_name const& name, string_type const& arg)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, greater);
+        BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
+        return logging::filter();
+    }
+    logging::filter on_less_or_equal_relation(logging::attribute_name const& name, string_type const& arg)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, less_or_equal);
+        BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
+        return logging::filter();
+    }
+    logging::filter on_greater_or_equal_relation(logging::attribute_name const& name, string_type const& arg)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, greater_or_equal);
+        BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
+        return logging::filter();
+    }
+    logging::filter on_custom_relation(logging::attribute_name const& name, string_type const& rel, string_type const& arg)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_rel, custom);
+        BOOST_CHECK_EQUAL(m_custom_rel, rel);
+        BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
+        return logging::filter();
+    }
+
+private:
+    logging::attribute_name m_name;
+    relation_type m_rel;
+    string_type m_arg;
+    string_type m_custom_rel;
+    bool m_called;
+};
+
+} // namespace
+
+// Tests for filter factory
+BOOST_AUTO_TEST_CASE(filter_factory)
+{
+    logging::attribute_name attr_name("MyCustomAttr");
+    boost::shared_ptr< test_filter_factory > factory(new test_filter_factory(attr_name));
+    logging::register_filter_factory(attr_name, factory);
+
+    BOOST_TEST_CHECKPOINT("filter_factory::exists");
+    factory->expect_relation(test_filter_factory::exists, "");
+    logging::parse_filter("%MyCustomAttr%");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::equality");
+    factory->expect_relation(test_filter_factory::equality, "15");
+    logging::parse_filter("%MyCustomAttr% = 15");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::equality");
+    factory->expect_relation(test_filter_factory::equality, "hello");
+    logging::parse_filter("%MyCustomAttr% = hello");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::equality");
+    factory->expect_relation(test_filter_factory::equality, "hello");
+    logging::parse_filter("%MyCustomAttr% = \"hello\"");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::equality");
+    factory->expect_relation(test_filter_factory::equality, "hello\nworld");
+    logging::parse_filter("%MyCustomAttr% = \"hello\\nworld\"");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::inequality");
+    factory->expect_relation(test_filter_factory::inequality, "hello");
+    logging::parse_filter("%MyCustomAttr% != \"hello\"");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::less");
+    factory->expect_relation(test_filter_factory::less, "hello");
+    logging::parse_filter("%MyCustomAttr% < \"hello\"");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::greater");
+    factory->expect_relation(test_filter_factory::greater, "hello");
+    logging::parse_filter("%MyCustomAttr% > \"hello\"");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::less_or_equal");
+    factory->expect_relation(test_filter_factory::less_or_equal, "hello");
+    logging::parse_filter("%MyCustomAttr% <= \"hello\"");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::greater_or_equal");
+    factory->expect_relation(test_filter_factory::greater_or_equal, "hello");
+    logging::parse_filter("%MyCustomAttr% >= \"hello\"");
+    factory->check_called();
+
+    BOOST_TEST_CHECKPOINT("filter_factory::custom");
+    factory->expect_relation("my_relation", "hello");
+    logging::parse_filter("%MyCustomAttr% my_relation \"hello\"");
+    factory->check_called();
+}
+
+// Tests for invalid filters
+BOOST_AUTO_TEST_CASE(invalid)
+{
+    BOOST_CHECK_THROW(logging::parse_filter("%MyStr"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("MyStr%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% abcd"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("(%MyStr%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%MyStr%)"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("!"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("!()"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("\"xxx\" == %MyStr%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% == \"xxx"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% === \"xxx\""), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% ! \"xxx\""), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_filter("%MyStr% %MyStr2%"), logging::parse_error);
+}
+
+#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
Copied: trunk/libs/log/test/run/util_stp_formatter_parser.cpp (from r85460, trunk/libs/log/test/run/setup_formatter_parser.cpp)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/libs/log/test/run/util_stp_formatter_parser.cpp	2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)	(r85476, copy of r85460, trunk/libs/log/test/run/setup_formatter_parser.cpp)
@@ -0,0 +1,257 @@
+/*
+ *          Copyright Andrey Semashev 2007 - 2013.
+ * 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   setup_formatter_parser.cpp
+ * \author Andrey Semashev
+ * \date   25.08.2013
+ *
+ * \brief  This header contains tests for the formatter parser.
+ */
+
+#define BOOST_TEST_MODULE setup_formatter_parser
+
+#include <string>
+#include <boost/test/unit_test.hpp>
+#include <boost/log/utility/setup/formatter_parser.hpp>
+
+#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+
+#include <boost/shared_ptr.hpp>
+#include <boost/log/exceptions.hpp>
+#include <boost/log/core/record.hpp>
+#include <boost/log/core/record_view.hpp>
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/attributes/attribute_set.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/expressions/formatter.hpp>
+#include "make_record.hpp"
+
+namespace logging = boost::log;
+namespace attrs = logging::attributes;
+
+typedef logging::attribute_set attr_set;
+typedef logging::attribute_value_set attr_values;
+typedef logging::record_view record_view;
+
+typedef logging::basic_formatting_ostream< char > osstream;
+typedef logging::basic_formatter< char > formatter;
+
+// Tests for simple attribute placeholders in formatters
+BOOST_AUTO_TEST_CASE(attr_placeholders)
+{
+    attrs::constant< int > attr1(10);
+    attrs::constant< std::string > attr2("hello");
+    attr_set set1;
+
+    set1["MyAttr"] = attr1;
+    set1["MyStr"] = attr2;
+
+    record_view rec = make_record_view(set1);
+
+    {
+        formatter f = logging::parse_formatter("String literal");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "String literal";
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MyStr: %MyStr%");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("MyAttr: % MyAttr %, MyStr: % MyStr %");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("%MyAttr%%MyStr%");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << attr1.get() << attr2.get();
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MissingAttr: %MissingAttr%");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "MyAttr: " << attr1.get() << ", MissingAttr: ";
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+}
+
+namespace {
+
+class test_formatter_factory :
+    public logging::formatter_factory< char >
+{
+private:
+    typedef logging::formatter_factory< char > base_type;
+
+public:
+    typedef base_type::string_type string_type;
+    typedef base_type::args_map args_map;
+    typedef base_type::formatter_type formatter_type;
+
+public:
+    explicit test_formatter_factory(logging::attribute_name const& name) : m_name(name), m_called(false)
+    {
+    }
+
+    void expect_args(args_map const& args)
+    {
+        m_args = args;
+    }
+
+    void check_called()
+    {
+        BOOST_CHECK(m_called);
+        m_called = false;
+    }
+
+    formatter_type create_formatter(logging::attribute_name const& name, args_map const& args)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_args.size(), args.size());
+
+        for (args_map::const_iterator it = m_args.begin(), end = m_args.end(); it != end; ++it)
+        {
+            args_map::const_iterator parsed_it = args.find(it->first);
+            if (parsed_it != args.end())
+            {
+                BOOST_TEST_CHECKPOINT(("Arg: " + it->first));
+                BOOST_CHECK_EQUAL(it->second, parsed_it->second);
+            }
+            else
+            {
+                BOOST_ERROR(("Arg not found: " + it->first));
+            }
+        }
+
+        m_called = true;
+        return formatter_type();
+    }
+
+private:
+    logging::attribute_name m_name;
+    args_map m_args;
+    bool m_called;
+};
+
+} // namespace
+
+// Tests for formatter factory
+BOOST_AUTO_TEST_CASE(formatter_factory)
+{
+    logging::attribute_name attr_name("MyCustomAttr");
+    boost::shared_ptr< test_formatter_factory > factory(new test_formatter_factory(attr_name));
+    logging::register_formatter_factory(attr_name, factory);
+
+    {
+        BOOST_TEST_CHECKPOINT("formatter 1");
+        test_formatter_factory::args_map args;
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 2");
+        test_formatter_factory::args_map args;
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr()%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 3");
+        test_formatter_factory::args_map args;
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr ( ) %");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 4");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1=10)%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 5");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: % MyCustomAttr ( param1 = 10 ) % ");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 6");
+        test_formatter_factory::args_map args;
+        args["param1"] = " 10 ";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1=\" 10 \")%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 7");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        args["param2"] = "abcd";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = abcd)%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 8");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        args["param2"] = "abcd";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1=10,param2=abcd)%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 9");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        args["param2"] = "abcd";
+        args["param_last"] = "-2.2";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = \"abcd\", param_last = -2.2)%");
+        factory->check_called();
+    }
+}
+
+// Tests for invalid formatters
+BOOST_AUTO_TEST_CASE(invalid)
+{
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("MyStr%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(=value)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param,param2)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,param2)%"), logging::parse_error);
+}
+
+#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
Copied: trunk/libs/log/test/run/util_stp_settings_parser.cpp (from r85460, trunk/libs/log/test/run/setup_settings_parser.cpp)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/libs/log/test/run/util_stp_settings_parser.cpp	2013-08-26 14:41:05 EDT (Mon, 26 Aug 2013)	(r85476, copy of r85460, trunk/libs/log/test/run/setup_settings_parser.cpp)
@@ -0,0 +1,294 @@
+/*
+ *          Copyright Andrey Semashev 2007 - 2013.
+ * 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   setup_settings_parser.cpp
+ * \author Andrey Semashev
+ * \date   25.08.2013
+ *
+ * \brief  This header contains tests for the settings parser.
+ */
+
+#define BOOST_TEST_MODULE setup_settings_parser
+
+#include <string>
+#include <sstream>
+#include <boost/test/unit_test.hpp>
+#include <boost/log/utility/setup/settings_parser.hpp>
+
+#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS)
+
+#include <boost/log/exceptions.hpp>
+
+namespace logging = boost::log;
+
+typedef logging::basic_settings< char > settings;
+
+// Tests for single-level settings
+BOOST_AUTO_TEST_CASE(single_level)
+{
+    {
+        std::istringstream strm
+        (
+            "[Section1]\n"
+            "\n"
+            "Param1 = Value1\n"
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        settings s = logging::parse_settings(strm);
+
+        BOOST_CHECK(s.has_section("Section1"));
+        BOOST_CHECK(s.has_section("Section2"));
+        BOOST_CHECK(!s.has_section("Section3"));
+
+        BOOST_CHECK(s.has_parameter("Section1", "Param1"));
+        BOOST_CHECK(s.has_parameter("Section1", "Param2"));
+
+        BOOST_CHECK(s.has_parameter("Section2", "Param1"));
+        BOOST_CHECK(s.has_parameter("Section2", "Param2"));
+
+        BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
+        BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
+
+        BOOST_CHECK_EQUAL(s["Section2"]["Param1"].or_default(std::string()), "10");
+        BOOST_CHECK_EQUAL(s["Section2"]["Param2"].or_default(std::string()), "-2.2");
+    }
+}
+
+// Tests for multi-level settings
+BOOST_AUTO_TEST_CASE(multi_level)
+{
+    {
+        std::istringstream strm
+        (
+            "  [Section1]\n"
+            "\n"
+            "Param1 = Value1 \n"
+            "Param2=\"hello, \\\"world\\\"\"   \n"
+            "\n"
+            "[Section1.Subsection2]  \n"
+            "\n"
+            "Param1=10\n"
+            "Param2=-2.2\n"
+        );
+        settings s = logging::parse_settings(strm);
+
+        BOOST_CHECK(s.has_section("Section1"));
+        BOOST_CHECK(s.has_section("Section1.Subsection2"));
+        BOOST_CHECK(!s.has_section("Subsection2"));
+
+        BOOST_CHECK(s.has_parameter("Section1", "Param1"));
+        BOOST_CHECK(s.has_parameter("Section1", "Param2"));
+
+        BOOST_CHECK(s.has_parameter("Section1.Subsection2", "Param1"));
+        BOOST_CHECK(s.has_parameter("Section1.Subsection2", "Param2"));
+        BOOST_CHECK(!s.has_parameter("Subsection2", "Param1"));
+        BOOST_CHECK(!s.has_parameter("Subsection2", "Param2"));
+
+        BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
+        BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
+
+        BOOST_CHECK_EQUAL(s["Section1.Subsection2"]["Param1"].or_default(std::string()), "10");
+        BOOST_CHECK_EQUAL(s["Section1.Subsection2"]["Param2"].or_default(std::string()), "-2.2");
+    }
+}
+
+// Tests for comments
+BOOST_AUTO_TEST_CASE(comments)
+{
+    {
+        std::istringstream strm
+        (
+            "# Some comment\n"
+            "[ Section1 ] # another comment\n"
+            "\n"
+            "Param1 = Value1 ### yet another comment \n"
+            "Param2=\"hello, \\\"world\\\"\" # comment after a quoted string\n"
+            "\n"
+            "[ Section2 ]\n"
+            "\n"
+            "Param1=10#comment after a number\n"
+            "Param2=-2.2#comment without a terminating newline"
+            "\n"
+            "#[Section3]\n"
+            "#\n"
+            "#Param1=10#comment after a number\n"
+            "#Param2=-2.2#comment without a terminating newline"
+        );
+        settings s = logging::parse_settings(strm);
+
+        BOOST_CHECK(s.has_section("Section1"));
+        BOOST_CHECK(s.has_section("Section2"));
+        BOOST_CHECK(!s.has_section("Section3"));
+
+        BOOST_CHECK(s.has_parameter("Section1", "Param1"));
+        BOOST_CHECK(s.has_parameter("Section1", "Param2"));
+
+        BOOST_CHECK(s.has_parameter("Section2", "Param1"));
+        BOOST_CHECK(s.has_parameter("Section2", "Param2"));
+
+        BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
+        BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
+
+        BOOST_CHECK_EQUAL(s["Section2"]["Param1"].or_default(std::string()), "10");
+        BOOST_CHECK_EQUAL(s["Section2"]["Param2"].or_default(std::string()), "-2.2");
+    }
+}
+
+// Tests for invalid settings
+BOOST_AUTO_TEST_CASE(invalid)
+{
+    {
+        std::istringstream strm
+        (
+            "Param1 = Value1\n" // parameters outside sections
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "[Section1\n" // missing closing brace
+            "\n"
+            "Param1 = Value1\n"
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "Section1]\n" // missing opening brace
+            "\n"
+            "Param1 = Value1\n"
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "[Section1=xyz]\n" // invalid characters in the section name
+            "\n"
+            "Param1 = Value1\n"
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "[Section1# hello?]\n" // invalid characters in the section name
+            "\n"
+            "Param1 = Value1\n"
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "(Section1)\n" // invalid braces
+            "\n"
+            "Param1 = Value1\n"
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "[Section1]\n"
+            "\n"
+            "Param1 =\n" // no parameter value
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "[Section1]\n"
+            "\n"
+            "Param1\n" // no parameter value
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "[Section1]\n"
+            "\n"
+            "Param1 = Value1\n"
+            "Param2 = \"hello, \\\"world\\\"\n" // unterminated quote
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+    {
+        std::istringstream strm
+        (
+            "[Section1]\n"
+            "\n"
+            "Param1 = Value1 Value2\n" // multi-word value
+            "Param2 = \"hello, \\\"world\\\"\"\n"
+            "\n"
+            "[Section2]\n"
+            "\n"
+            "Param1 = 10\n"
+            "Param2 = -2.2\n"
+        );
+        BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
+    }
+}
+
+#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS)