filter_parser.hpp 13 KB

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