• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 /*!
8  * \file   formatter_parser.hpp
9  * \author Andrey Semashev
10  * \date   07.04.2008
11  *
12  * The header contains definition of a formatter parser function, along with facilities to
13  * add support for custom formatters.
14  */
15 
16 #ifndef BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
17 #define BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
18 
19 #include <iosfwd>
20 #include <map>
21 #include <string>
22 #include <boost/smart_ptr/shared_ptr.hpp>
23 #include <boost/smart_ptr/make_shared_object.hpp>
24 #include <boost/core/enable_if.hpp>
25 #include <boost/type_traits/is_base_and_derived.hpp>
26 #include <boost/log/detail/setup_config.hpp>
27 #include <boost/log/attributes/attribute_name.hpp>
28 #include <boost/log/core/record.hpp>
29 #include <boost/log/expressions/formatter.hpp>
30 #include <boost/log/expressions/attr.hpp>
31 #include <boost/log/expressions/formatters/stream.hpp>
32 #include <boost/log/detail/header.hpp>
33 
34 #ifdef BOOST_HAS_PRAGMA_ONCE
35 #pragma once
36 #endif
37 
38 namespace boost {
39 
40 BOOST_LOG_OPEN_NAMESPACE
41 
42 /*!
43  * Formatter factory base interface.
44  */
45 template< typename CharT >
46 struct formatter_factory
47 {
48     //! Character type
49     typedef CharT char_type;
50     //! String type
51     typedef std::basic_string< char_type > string_type;
52     //! The formatter function object
53     typedef basic_formatter< char_type > formatter_type;
54     /*!
55      * Type of the map of formatter factory arguments [argument name -> argument value].
56      * This type of maps will be passed to formatter factories on attempt to create a formatter.
57      */
58     typedef std::map< string_type, string_type > args_map;
59 
60     /*!
61      * Default constructor
62      */
formatter_factoryboost::formatter_factory63     BOOST_DEFAULTED_FUNCTION(formatter_factory(), {})
64 
65     /*!
66      * Virtual destructor
67      */
68     virtual ~formatter_factory() {}
69 
70     /*!
71      * The function creates a formatter for the specified attribute.
72      *
73      * \param name Attribute name
74      * \param args Formatter arguments
75      */
76     virtual formatter_type create_formatter(attribute_name const& name, args_map const& args) = 0;
77 
78     BOOST_DELETED_FUNCTION(formatter_factory(formatter_factory const&))
79     BOOST_DELETED_FUNCTION(formatter_factory& operator= (formatter_factory const&))
80 };
81 
82 /*!
83  * Base class for formatter factories. This class provides default implementation of formatter expressions for
84  * types supporting stream output. The factory does not take into account any additional parameters that may be specified.
85  */
86 template< typename CharT, typename AttributeValueT >
87 class basic_formatter_factory :
88     public formatter_factory< CharT >
89 {
90 private:
91     typedef formatter_factory< CharT > base_type;
92 
93 public:
94     //! Attribute value type
95     typedef AttributeValueT value_type;
96     //  Type imports from the base class
97     typedef typename base_type::formatter_type formatter_type;
98     typedef typename base_type::args_map args_map;
99 
100     /*!
101      * The function creates a formatter for the specified attribute.
102      *
103      * \param name Attribute name
104      * \param args Formatter arguments
105      */
create_formatter(attribute_name const & name,args_map const & args)106     formatter_type create_formatter(attribute_name const& name, args_map const& args)
107     {
108         return formatter_type(expressions::stream << expressions::attr< value_type >(name));
109     }
110 };
111 
112 /*!
113  * \brief The function registers a user-defined formatter factory
114  *
115  * The function registers a user-defined formatter factory. The registered factory function will be
116  * called when the formatter parser detects the specified attribute name in the formatter string.
117  *
118  * \pre <tt>!!attr_name && !!factory</tt>.
119  *
120  * \param attr_name Attribute name
121  * \param factory Pointer to the formatter factory
122  */
123 template< typename CharT >
124 BOOST_LOG_SETUP_API void register_formatter_factory(
125     attribute_name const& attr_name, shared_ptr< formatter_factory< CharT > > const& factory);
126 
127 /*!
128  * \brief The function registers a user-defined formatter factory
129  *
130  * The function registers a user-defined formatter factory. The registered factory function will be
131  * called when the formatter parser detects the specified attribute name in the formatter string.
132  *
133  * \pre <tt>!!attr_name && !!factory</tt>.
134  *
135  * \param attr_name Attribute name
136  * \param factory Pointer to the formatter factory
137  */
138 template< typename FactoryT >
139 inline typename boost::enable_if_c<
140     is_base_and_derived< formatter_factory< typename FactoryT::char_type >, FactoryT >::value
register_formatter_factory(attribute_name const & attr_name,shared_ptr<FactoryT> const & factory)141 >::type register_formatter_factory(attribute_name const& attr_name, shared_ptr< FactoryT > const& factory)
142 {
143     typedef formatter_factory< typename FactoryT::char_type > factory_base;
144     register_formatter_factory(attr_name, boost::static_pointer_cast< factory_base >(factory));
145 }
146 
147 /*!
148  * \brief The function registers a simple formatter factory
149  *
150  * The function registers a simple formatter factory. The registered factory will generate formatters
151  * that will be equivalent to the <tt>log::expressions::attr</tt> formatter (i.e. that will use the
152  * native \c operator<< to format the attribute value). The factory does not use any arguments from the format string,
153  * if specified.
154  *
155  * \pre <tt>!!attr_name</tt>.
156  *
157  * \param attr_name Attribute name
158  */
159 template< typename AttributeValueT, typename CharT >
register_simple_formatter_factory(attribute_name const & attr_name)160 inline void register_simple_formatter_factory(attribute_name const& attr_name)
161 {
162     shared_ptr< formatter_factory< CharT > > factory =
163         boost::make_shared< basic_formatter_factory< CharT, AttributeValueT > >();
164     register_formatter_factory(attr_name, factory);
165 }
166 
167 /*!
168  * The function parses a formatter from the sequence of characters
169  *
170  * \pre <tt>begin <= end</tt>, both pointers must not be NULL
171  * \param begin Pointer to the first character of the sequence
172  * \param end Pointer to the after-the-last character of the sequence
173  * \return The parsed formatter.
174  *
175  * \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
176  */
177 template< typename CharT >
178 BOOST_LOG_SETUP_API basic_formatter< CharT > parse_formatter(const CharT* begin, const CharT* end);
179 
180 /*!
181  * The function parses a formatter from the string
182  *
183  * \param str A string that contains format description
184  * \return The parsed formatter.
185  *
186  * \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
187  */
188 template< typename CharT, typename TraitsT, typename AllocatorT >
parse_formatter(std::basic_string<CharT,TraitsT,AllocatorT> const & str)189 inline basic_formatter< CharT > parse_formatter(std::basic_string< CharT, TraitsT, AllocatorT > const& str)
190 {
191     const CharT* p = str.c_str();
192     return parse_formatter(p, p + str.size());
193 }
194 
195 /*!
196  * The function parses a formatter from the string
197  *
198  * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string
199  * \param str A string that contains format description.
200  * \return The parsed formatter.
201  *
202  * \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
203  */
204 template< typename CharT >
parse_formatter(const CharT * str)205 inline basic_formatter< CharT > parse_formatter(const CharT* str)
206 {
207     return parse_formatter(str, str + std::char_traits< CharT >::length(str));
208 }
209 
210 BOOST_LOG_CLOSE_NAMESPACE // namespace log
211 
212 } // namespace boost
213 
214 #include <boost/log/detail/footer.hpp>
215 
216 #endif // BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
217