]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 filter_parser.hpp | |
9 | * \author Andrey Semashev | |
10 | * \date 31.03.2008 | |
11 | * | |
12 | * The header contains definition of a filter parser function. | |
13 | */ | |
14 | ||
15 | #ifndef BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_ | |
16 | #define BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_ | |
17 | ||
18 | #include <string> | |
19 | #include <boost/lexical_cast.hpp> | |
20 | #include <boost/smart_ptr/shared_ptr.hpp> | |
21 | #include <boost/smart_ptr/make_shared_object.hpp> | |
22 | #include <boost/phoenix/operator/comparison.hpp> | |
23 | #include <boost/type_traits/is_base_and_derived.hpp> | |
24 | #include <boost/core/enable_if.hpp> | |
25 | #include <boost/log/detail/setup_config.hpp> | |
26 | #include <boost/log/detail/code_conversion.hpp> | |
27 | #include <boost/log/exceptions.hpp> | |
28 | #include <boost/log/attributes/attribute_name.hpp> | |
29 | #include <boost/log/attributes/attribute_value_set.hpp> | |
30 | #include <boost/log/expressions/filter.hpp> | |
31 | #include <boost/log/expressions/keyword_fwd.hpp> | |
32 | #include <boost/log/expressions/attr.hpp> | |
33 | #include <boost/log/expressions/predicates/has_attr.hpp> | |
34 | #include <boost/log/core/core.hpp> | |
35 | #include <boost/log/detail/header.hpp> | |
36 | ||
37 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
38 | #pragma once | |
39 | #endif | |
40 | ||
41 | namespace boost { | |
42 | ||
43 | BOOST_LOG_OPEN_NAMESPACE | |
44 | ||
45 | /*! | |
46 | * The interface class for all filter factories. | |
47 | */ | |
48 | template< typename CharT > | |
49 | struct filter_factory | |
50 | { | |
51 | //! Character type | |
52 | typedef CharT char_type; | |
53 | //! String type | |
54 | typedef std::basic_string< char_type > string_type; | |
55 | ||
56 | /*! | |
57 | * Default constructor | |
58 | */ | |
59 | BOOST_DEFAULTED_FUNCTION(filter_factory(), {}) | |
60 | ||
61 | /*! | |
62 | * Virtual destructor | |
63 | */ | |
64 | virtual ~filter_factory() {} | |
65 | ||
66 | /*! | |
67 | * The callback for filter for the attribute existence test | |
68 | */ | |
69 | virtual filter on_exists_test(attribute_name const& name) | |
70 | { | |
71 | return filter(expressions::has_attr(name)); | |
72 | } | |
73 | ||
74 | /*! | |
75 | * The callback for equality relation filter | |
76 | */ | |
77 | virtual filter on_equality_relation(attribute_name const& name, string_type const& arg) | |
78 | { | |
79 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The equality attribute value relation is not supported", (name)); | |
80 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
81 | } | |
82 | /*! | |
83 | * The callback for inequality relation filter | |
84 | */ | |
85 | virtual filter on_inequality_relation(attribute_name const& name, string_type const& arg) | |
86 | { | |
87 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The inequality attribute value relation is not supported", (name)); | |
88 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
89 | } | |
90 | /*! | |
91 | * The callback for less relation filter | |
92 | */ | |
93 | virtual filter on_less_relation(attribute_name const& name, string_type const& arg) | |
94 | { | |
95 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The less attribute value relation is not supported", (name)); | |
96 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
97 | } | |
98 | /*! | |
99 | * The callback for greater relation filter | |
100 | */ | |
101 | virtual filter on_greater_relation(attribute_name const& name, string_type const& arg) | |
102 | { | |
103 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The greater attribute value relation is not supported", (name)); | |
104 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
105 | } | |
106 | /*! | |
107 | * The callback for less or equal relation filter | |
108 | */ | |
109 | virtual filter on_less_or_equal_relation(attribute_name const& name, string_type const& arg) | |
110 | { | |
111 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The less-or-equal attribute value relation is not supported", (name)); | |
112 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
113 | } | |
114 | /*! | |
115 | * The callback for greater or equal relation filter | |
116 | */ | |
117 | virtual filter on_greater_or_equal_relation(attribute_name const& name, string_type const& arg) | |
118 | { | |
119 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The greater-or-equal attribute value relation is not supported", (name)); | |
120 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
121 | } | |
122 | ||
123 | /*! | |
124 | * The callback for custom relation filter | |
125 | */ | |
126 | virtual filter on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg) | |
127 | { | |
128 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The custom attribute value relation \"" + boost::log::aux::to_narrow(arg) + "\" is not supported", (name)); | |
129 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
130 | } | |
131 | ||
132 | BOOST_DELETED_FUNCTION(filter_factory(filter_factory const&)) | |
133 | BOOST_DELETED_FUNCTION(filter_factory& operator= (filter_factory const&)) | |
134 | }; | |
135 | ||
136 | /*! | |
137 | * The base class for filter factories. The class defines default implementations for most | |
138 | * filter expressions. In order to be able to construct filters, the attribute value type must | |
139 | * support reading from a stream. Also, the default filters will rely on relational operators for | |
140 | * the type, so these operators must also be defined. | |
141 | */ | |
142 | template< typename CharT, typename AttributeValueT > | |
143 | class basic_filter_factory : | |
144 | public filter_factory< CharT > | |
145 | { | |
146 | //! Base type | |
147 | typedef filter_factory< CharT > base_type; | |
148 | ||
149 | public: | |
150 | //! The type(s) of the attribute value expected | |
151 | typedef AttributeValueT value_type; | |
152 | // Type imports | |
153 | typedef typename base_type::string_type string_type; | |
154 | ||
155 | /*! | |
156 | * The callback for filter for the attribute existence test | |
157 | */ | |
158 | virtual filter on_exists_test(attribute_name const& name) | |
159 | { | |
160 | return filter(expressions::has_attr< value_type >(name)); | |
161 | } | |
162 | ||
163 | /*! | |
164 | * The callback for equality relation filter | |
165 | */ | |
166 | virtual filter on_equality_relation(attribute_name const& name, string_type const& arg) | |
167 | { | |
168 | return filter(expressions::attr< value_type >(name) == parse_argument(arg)); | |
169 | } | |
170 | /*! | |
171 | * The callback for inequality relation filter | |
172 | */ | |
173 | virtual filter on_inequality_relation(attribute_name const& name, string_type const& arg) | |
174 | { | |
175 | return filter(expressions::attr< value_type >(name) != parse_argument(arg)); | |
176 | } | |
177 | /*! | |
178 | * The callback for less relation filter | |
179 | */ | |
180 | virtual filter on_less_relation(attribute_name const& name, string_type const& arg) | |
181 | { | |
182 | return filter(expressions::attr< value_type >(name) < parse_argument(arg)); | |
183 | } | |
184 | /*! | |
185 | * The callback for greater relation filter | |
186 | */ | |
187 | virtual filter on_greater_relation(attribute_name const& name, string_type const& arg) | |
188 | { | |
189 | return filter(expressions::attr< value_type >(name) > parse_argument(arg)); | |
190 | } | |
191 | /*! | |
192 | * The callback for less or equal relation filter | |
193 | */ | |
194 | virtual filter on_less_or_equal_relation(attribute_name const& name, string_type const& arg) | |
195 | { | |
196 | return filter(expressions::attr< value_type >(name) <= parse_argument(arg)); | |
197 | } | |
198 | /*! | |
199 | * The callback for greater or equal relation filter | |
200 | */ | |
201 | virtual filter on_greater_or_equal_relation(attribute_name const& name, string_type const& arg) | |
202 | { | |
203 | return filter(expressions::attr< value_type >(name) >= parse_argument(arg)); | |
204 | } | |
205 | ||
206 | /*! | |
207 | * The callback for custom relation filter | |
208 | */ | |
209 | virtual filter on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg) | |
210 | { | |
211 | BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The custom attribute value relation \"" + boost::log::aux::to_narrow(arg) + "\" is not supported", (name)); | |
212 | BOOST_LOG_UNREACHABLE_RETURN(filter()); | |
213 | } | |
214 | ||
215 | /*! | |
216 | * The function parses the argument value for a binary relation | |
217 | */ | |
218 | virtual value_type parse_argument(string_type const& arg) | |
219 | { | |
220 | return boost::lexical_cast< value_type >(arg); | |
221 | } | |
222 | }; | |
223 | ||
224 | /*! | |
225 | * The function registers a filter factory object for the specified attribute name. The factory will be | |
226 | * used to construct a filter during parsing the filter string. | |
227 | * | |
228 | * \pre <tt>name != NULL && factory != NULL</tt>, <tt>name</tt> points to a zero-terminated string | |
229 | * \param name Attribute name to associate the factory with | |
230 | * \param factory The filter factory | |
231 | */ | |
232 | template< typename CharT > | |
233 | BOOST_LOG_SETUP_API void register_filter_factory( | |
234 | attribute_name const& name, shared_ptr< filter_factory< CharT > > const& factory); | |
235 | ||
236 | /*! | |
237 | * The function registers a filter factory object for the specified attribute name. The factory will be | |
238 | * used to construct a filter during parsing the filter string. | |
239 | * | |
240 | * \pre <tt>name != NULL && factory != NULL</tt>, <tt>name</tt> points to a zero-terminated string | |
241 | * \param name Attribute name to associate the factory with | |
242 | * \param factory The filter factory | |
243 | */ | |
244 | template< typename FactoryT > | |
245 | inline typename boost::enable_if_c< | |
246 | is_base_and_derived< filter_factory< typename FactoryT::char_type >, FactoryT >::value | |
247 | >::type register_filter_factory(attribute_name const& name, shared_ptr< FactoryT > const& factory) | |
248 | { | |
249 | typedef filter_factory< typename FactoryT::char_type > factory_base; | |
250 | register_filter_factory(name, boost::static_pointer_cast< factory_base >(factory)); | |
251 | } | |
252 | ||
253 | /*! | |
254 | * The function registers a simple filter factory object for the specified attribute name. The factory will | |
255 | * support attribute values of type \c AttributeValueT, which must support all relation operations, such as | |
256 | * equality comparison and less/greater ordering, and also extraction from stream. | |
257 | * | |
258 | * \pre <tt>name != NULL</tt>, <tt>name</tt> points to a zero-terminated string | |
259 | * \param name Attribute name to associate the factory with | |
260 | */ | |
261 | template< typename AttributeValueT, typename CharT > | |
262 | inline void register_simple_filter_factory(attribute_name const& name) | |
263 | { | |
264 | shared_ptr< filter_factory< CharT > > factory = | |
265 | boost::make_shared< basic_filter_factory< CharT, AttributeValueT > >(); | |
266 | register_filter_factory(name, factory); | |
267 | } | |
268 | ||
269 | /*! | |
270 | * The function registers a simple filter factory object for the specified attribute name. The factory will | |
271 | * support attribute values of type \c AttributeValueT, which must support all relation operations, such as | |
272 | * equality comparison and less/greater ordering, and also extraction from stream. | |
273 | * | |
274 | * \pre <tt>name != NULL</tt>, <tt>name</tt> points to a zero-terminated string | |
275 | * \param name Attribute name to associate the factory with | |
276 | */ | |
277 | template< typename AttributeValueT > | |
278 | inline void register_simple_filter_factory(attribute_name const& name) | |
279 | { | |
280 | register_simple_filter_factory< AttributeValueT, char >(name); | |
281 | } | |
282 | ||
283 | /*! | |
284 | * The function registers a simple filter factory object for the specified attribute keyword. The factory will | |
285 | * support attribute values described by the keyword. The values must support all relation operations, such as | |
286 | * equality comparison and less/greater ordering, and also extraction from stream. | |
287 | * | |
288 | * \pre <tt>name != NULL</tt>, <tt>name</tt> points to a zero-terminated string | |
289 | * \param keyword Attribute keyword to associate the factory with | |
290 | */ | |
291 | template< typename CharT, typename DescriptorT, template< typename > class ActorT > | |
292 | inline void register_simple_filter_factory(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) | |
293 | { | |
294 | register_simple_filter_factory< typename DescriptorT::value_type, CharT >(keyword.get_name()); | |
295 | } | |
296 | ||
297 | /*! | |
298 | * The function parses a filter from the sequence of characters | |
299 | * | |
300 | * \pre <tt>begin <= end</tt>, both pointers must not be \c NULL | |
301 | * \param begin Pointer to the first character of the sequence | |
302 | * \param end Pointer to the after-the-last character of the sequence | |
303 | * \return A function object that can be used as a filter. | |
304 | * | |
305 | * \b Throws: An <tt>std::exception</tt>-based exception, if a filter cannot be recognized in the character sequence. | |
306 | */ | |
307 | template< typename CharT > | |
308 | BOOST_LOG_SETUP_API filter parse_filter(const CharT* begin, const CharT* end); | |
309 | ||
310 | /*! | |
311 | * The function parses a filter from the string | |
312 | * | |
313 | * \param str A string that contains filter description | |
314 | * \return A function object that can be used as a filter. | |
315 | * | |
316 | * \b Throws: An <tt>std::exception</tt>-based exception, if a filter cannot be recognized in the character sequence. | |
317 | */ | |
318 | template< typename CharT, typename TraitsT, typename AllocatorT > | |
319 | inline filter parse_filter(std::basic_string< CharT, TraitsT, AllocatorT > const& str) | |
320 | { | |
321 | const CharT* p = str.c_str(); | |
322 | return parse_filter(p, p + str.size()); | |
323 | } | |
324 | ||
325 | /*! | |
326 | * The function parses a filter from the string | |
327 | * | |
328 | * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string. | |
329 | * \param str A string that contains filter description. | |
330 | * \return A function object that can be used as a filter. | |
331 | * | |
332 | * \b Throws: An <tt>std::exception</tt>-based exception, if a filter cannot be recognized in the character sequence. | |
333 | */ | |
334 | template< typename CharT > | |
335 | inline filter parse_filter(const CharT* str) | |
336 | { | |
337 | return parse_filter(str, str + std::char_traits< CharT >::length(str)); | |
338 | } | |
339 | ||
340 | BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
341 | ||
342 | } // namespace boost | |
343 | ||
344 | #include <boost/log/detail/footer.hpp> | |
345 | ||
346 | #endif // BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_ |