annotate DEPENDENCIES/generic/include/boost/log/expressions/formatters/c_decorator.hpp @ 77:2e60b888e526

Try distclean before clean (otherwise we can end up trying to add to archives of the wrong arch for example)
author Chris Cannam
date Thu, 30 Oct 2014 16:06:26 +0000
parents 2665513ce2d3
children c530137014c0
rev   line source
Chris@16 1 /*
Chris@16 2 * Copyright Andrey Semashev 2007 - 2013.
Chris@16 3 * Distributed under the Boost Software License, Version 1.0.
Chris@16 4 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 */
Chris@16 7 /*!
Chris@16 8 * \file formatters/c_decorator.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 18.11.2012
Chris@16 11 *
Chris@16 12 * The header contains implementation of C-style character decorators.
Chris@16 13 */
Chris@16 14
Chris@16 15 #ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
Chris@16 16 #define BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
Chris@16 17
Chris@16 18 #include <limits>
Chris@16 19 #include <boost/range/iterator_range_core.hpp>
Chris@16 20 #include <boost/log/detail/config.hpp>
Chris@16 21 #include <boost/log/detail/snprintf.hpp>
Chris@16 22 #include <boost/log/expressions/formatters/char_decorator.hpp>
Chris@16 23 #include <boost/log/detail/header.hpp>
Chris@16 24
Chris@16 25 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@16 26 #pragma once
Chris@16 27 #endif
Chris@16 28
Chris@16 29 namespace boost {
Chris@16 30
Chris@16 31 BOOST_LOG_OPEN_NAMESPACE
Chris@16 32
Chris@16 33 namespace expressions {
Chris@16 34
Chris@16 35 namespace aux {
Chris@16 36
Chris@16 37 template< typename >
Chris@16 38 struct c_decorator_traits;
Chris@16 39
Chris@16 40 #ifdef BOOST_LOG_USE_CHAR
Chris@16 41 template< >
Chris@16 42 struct c_decorator_traits< char >
Chris@16 43 {
Chris@16 44 static boost::iterator_range< const char* const* > get_patterns()
Chris@16 45 {
Chris@16 46 static const char* const patterns[] =
Chris@16 47 {
Chris@16 48 "\\", "\a", "\b", "\f", "\n", "\r", "\t", "\v", "'", "\"", "?"
Chris@16 49 };
Chris@16 50 return boost::make_iterator_range(patterns);
Chris@16 51 }
Chris@16 52 static boost::iterator_range< const char* const* > get_replacements()
Chris@16 53 {
Chris@16 54 static const char* const replacements[] =
Chris@16 55 {
Chris@16 56 "\\\\", "\\a", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\'", "\\\"", "\\?"
Chris@16 57 };
Chris@16 58 return boost::make_iterator_range(replacements);
Chris@16 59 }
Chris@16 60 template< unsigned int N >
Chris@16 61 static std::size_t print_escaped(char (&buf)[N], char c)
Chris@16 62 {
Chris@16 63 return static_cast< std::size_t >(
Chris@16 64 boost::log::aux::snprintf(buf, N, "\\x%0.2X", static_cast< unsigned int >(static_cast< uint8_t >(c))));
Chris@16 65 }
Chris@16 66 };
Chris@16 67 #endif // BOOST_LOG_USE_CHAR
Chris@16 68
Chris@16 69 #ifdef BOOST_LOG_USE_WCHAR_T
Chris@16 70 template< >
Chris@16 71 struct c_decorator_traits< wchar_t >
Chris@16 72 {
Chris@16 73 static boost::iterator_range< const wchar_t* const* > get_patterns()
Chris@16 74 {
Chris@16 75 static const wchar_t* const patterns[] =
Chris@16 76 {
Chris@16 77 L"\\", L"\a", L"\b", L"\f", L"\n", L"\r", L"\t", L"\v", L"'", L"\"", L"?"
Chris@16 78 };
Chris@16 79 return boost::make_iterator_range(patterns);
Chris@16 80 }
Chris@16 81 static boost::iterator_range< const wchar_t* const* > get_replacements()
Chris@16 82 {
Chris@16 83 static const wchar_t* const replacements[] =
Chris@16 84 {
Chris@16 85 L"\\\\", L"\\a", L"\\b", L"\\f", L"\\n", L"\\r", L"\\t", L"\\v", L"\\'", L"\\\"", L"\\?"
Chris@16 86 };
Chris@16 87 return boost::make_iterator_range(replacements);
Chris@16 88 }
Chris@16 89 template< unsigned int N >
Chris@16 90 static std::size_t print_escaped(wchar_t (&buf)[N], wchar_t c)
Chris@16 91 {
Chris@16 92 const wchar_t* format;
Chris@16 93 register unsigned int val;
Chris@16 94 if (sizeof(wchar_t) == 1)
Chris@16 95 {
Chris@16 96 format = L"\\x%0.2X";
Chris@16 97 val = static_cast< uint8_t >(c);
Chris@16 98 }
Chris@16 99 else if (sizeof(wchar_t) == 2)
Chris@16 100 {
Chris@16 101 format = L"\\x%0.4X";
Chris@16 102 val = static_cast< uint16_t >(c);
Chris@16 103 }
Chris@16 104 else
Chris@16 105 {
Chris@16 106 format = L"\\x%0.8X";
Chris@16 107 val = static_cast< uint32_t >(c);
Chris@16 108 }
Chris@16 109
Chris@16 110 return static_cast< std::size_t >(boost::log::aux::swprintf(buf, N, format, val));
Chris@16 111 }
Chris@16 112 };
Chris@16 113 #endif // BOOST_LOG_USE_WCHAR_T
Chris@16 114
Chris@16 115 template< typename CharT >
Chris@16 116 struct c_decorator_gen
Chris@16 117 {
Chris@16 118 typedef CharT char_type;
Chris@16 119
Chris@16 120 template< typename SubactorT >
Chris@16 121 BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
Chris@16 122 {
Chris@16 123 typedef c_decorator_traits< char_type > traits_type;
Chris@16 124 typedef pattern_replacer< char_type > replacer_type;
Chris@16 125 typedef char_decorator_actor< SubactorT, replacer_type > result_type;
Chris@16 126 typedef typename result_type::terminal_type terminal_type;
Chris@16 127 typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
Chris@16 128 return result_type(act);
Chris@16 129 }
Chris@16 130 };
Chris@16 131
Chris@16 132 } // namespace aux
Chris@16 133
Chris@16 134 /*!
Chris@16 135 * C-style decorator generator object. The decorator replaces characters with specific meaning in C
Chris@16 136 * language with the corresponding escape sequences. The generator provides <tt>operator[]</tt> that
Chris@16 137 * can be used to construct the actual decorator. For example:
Chris@16 138 *
Chris@16 139 * <code>
Chris@16 140 * c_decor[ attr< std::string >("MyAttr") ]
Chris@16 141 * </code>
Chris@16 142 *
Chris@16 143 * For wide-character formatting there is the similar \c wc_decor decorator generator object.
Chris@16 144 */
Chris@16 145 #ifdef BOOST_LOG_USE_CHAR
Chris@16 146 const aux::c_decorator_gen< char > c_decor = {};
Chris@16 147 #endif
Chris@16 148 #ifdef BOOST_LOG_USE_WCHAR_T
Chris@16 149 const aux::c_decorator_gen< wchar_t > wc_decor = {};
Chris@16 150 #endif
Chris@16 151
Chris@16 152 /*!
Chris@16 153 * The function creates a C-style decorator generator for arbitrary character type.
Chris@16 154 */
Chris@16 155 template< typename CharT >
Chris@16 156 BOOST_FORCEINLINE aux::c_decorator_gen< CharT > make_c_decor()
Chris@16 157 {
Chris@16 158 return aux::c_decorator_gen< CharT >();
Chris@16 159 }
Chris@16 160
Chris@16 161 /*!
Chris@16 162 * A character decorator implementation that escapes all non-prontable and non-ASCII characters
Chris@16 163 * in the output with C-style escape sequences.
Chris@16 164 */
Chris@16 165 template< typename CharT >
Chris@16 166 class c_ascii_pattern_replacer :
Chris@16 167 public pattern_replacer< CharT >
Chris@16 168 {
Chris@16 169 private:
Chris@16 170 //! Base type
Chris@16 171 typedef pattern_replacer< CharT > base_type;
Chris@16 172
Chris@16 173 public:
Chris@16 174 //! Result type
Chris@16 175 typedef typename base_type::result_type result_type;
Chris@16 176 //! Character type
Chris@16 177 typedef typename base_type::char_type char_type;
Chris@16 178 //! String type
Chris@16 179 typedef typename base_type::string_type string_type;
Chris@16 180
Chris@16 181 private:
Chris@16 182 //! Traits type
Chris@16 183 typedef aux::c_decorator_traits< char_type > traits_type;
Chris@16 184
Chris@16 185 public:
Chris@16 186 //! Default constructor
Chris@16 187 c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
Chris@16 188 {
Chris@16 189 }
Chris@16 190
Chris@16 191 //! Applies string replacements starting from the specified position
Chris@16 192 result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
Chris@16 193 {
Chris@16 194 base_type::operator() (str, start_pos);
Chris@16 195
Chris@16 196 typedef typename string_type::iterator string_iterator;
Chris@16 197 for (string_iterator it = str.begin() + start_pos, end = str.end(); it != end; ++it)
Chris@16 198 {
Chris@16 199 char_type c = *it;
Chris@16 200 if (c < 0x20 || c > 0x7e)
Chris@16 201 {
Chris@16 202 char_type buf[(std::numeric_limits< char_type >::digits + 3) / 4 + 3];
Chris@16 203 std::size_t n = traits_type::print_escaped(buf, c);
Chris@16 204 std::size_t pos = it - str.begin();
Chris@16 205 str.replace(pos, 1, buf, n);
Chris@16 206 it = str.begin() + n - 1;
Chris@16 207 end = str.end();
Chris@16 208 }
Chris@16 209 }
Chris@16 210 }
Chris@16 211 };
Chris@16 212
Chris@16 213 namespace aux {
Chris@16 214
Chris@16 215 template< typename CharT >
Chris@16 216 struct c_ascii_decorator_gen
Chris@16 217 {
Chris@16 218 typedef CharT char_type;
Chris@16 219
Chris@16 220 template< typename SubactorT >
Chris@16 221 BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
Chris@16 222 {
Chris@16 223 typedef c_decorator_traits< char_type > traits_type;
Chris@16 224 typedef c_ascii_pattern_replacer< char_type > replacer_type;
Chris@16 225 typedef char_decorator_actor< SubactorT, replacer_type > result_type;
Chris@16 226 typedef typename result_type::terminal_type terminal_type;
Chris@16 227 typename result_type::base_type act = {{ terminal_type(subactor, replacer_type()) }};
Chris@16 228 return result_type(act);
Chris@16 229 }
Chris@16 230 };
Chris@16 231
Chris@16 232 } // namespace aux
Chris@16 233
Chris@16 234 /*!
Chris@16 235 * C-style decorator generator object. Acts similarly to \c c_decor, except that \c c_ascii_decor also
Chris@16 236 * converts all non-ASCII and non-printable ASCII characters, except for space character, into
Chris@16 237 * C-style hexadecimal escape sequences. The generator provides <tt>operator[]</tt> that
Chris@16 238 * can be used to construct the actual decorator. For example:
Chris@16 239 *
Chris@16 240 * <code>
Chris@16 241 * c_ascii_decor[ attr< std::string >("MyAttr") ]
Chris@16 242 * </code>
Chris@16 243 *
Chris@16 244 * For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
Chris@16 245 */
Chris@16 246 #ifdef BOOST_LOG_USE_CHAR
Chris@16 247 const aux::c_ascii_decorator_gen< char > c_ascii_decor = {};
Chris@16 248 #endif
Chris@16 249 #ifdef BOOST_LOG_USE_WCHAR_T
Chris@16 250 const aux::c_ascii_decorator_gen< wchar_t > wc_ascii_decor = {};
Chris@16 251 #endif
Chris@16 252
Chris@16 253 /*!
Chris@16 254 * The function creates a C-style decorator generator for arbitrary character type.
Chris@16 255 */
Chris@16 256 template< typename CharT >
Chris@16 257 BOOST_FORCEINLINE aux::c_ascii_decorator_gen< CharT > make_c_ascii_decor()
Chris@16 258 {
Chris@16 259 return aux::c_ascii_decorator_gen< CharT >();
Chris@16 260 }
Chris@16 261
Chris@16 262 } // namespace expressions
Chris@16 263
Chris@16 264 BOOST_LOG_CLOSE_NAMESPACE // namespace log
Chris@16 265
Chris@16 266 } // namespace boost
Chris@16 267
Chris@16 268 #include <boost/log/detail/footer.hpp>
Chris@16 269
Chris@16 270 #endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_