void limitation_error::throw_(const char* file, std::size_t line, std::string const& descr) { boost::throw_exception(boost::enable_error_info(limitation_error(descr)) << boost::throw_file(file) << boost::throw_line(line) ); }
BOOST_LOG_API format_description< CharT > parse_format(const CharT* begin, const CharT* end) { typedef CharT char_type; typedef format_description< char_type > description; typedef typename encoding< char_type >::type traits; const char_type* original_begin = begin; description descr; unsigned int literal_start_pos = 0; while (begin != end) { const char_type* p = std::find(begin, end, static_cast< char_type >('%')); descr.literal_chars.append(begin, p); if ((end - p) >= 2) { // Check for a percent placeholder char_type c = p[1]; if (c == static_cast< char_type >('%')) { descr.literal_chars.push_back(static_cast< char_type >('%')); begin = p + 2; continue; } // From here on, no more literals are possible. Append the literal element. { const unsigned int literal_chars_size = static_cast< unsigned int >(descr.literal_chars.size()); if (literal_start_pos < literal_chars_size) { descr.format_elements.push_back(format_element::literal(literal_start_pos, literal_chars_size - literal_start_pos)); literal_start_pos = literal_chars_size; } } // Check if this is a positional argument if (traits::isdigit(c)) { if (c != static_cast< char_type >('0')) { // Positional argument in the form "%N%" unsigned int n = 0; const char_type* pp = p + 1; qi::parse(pp, end, qi::uint_, n); if (n == 0 || pp == end || *pp != static_cast< char_type >('%')) { boost::throw_exception(boost::enable_error_info(parse_error("Invalid positional format placeholder")) << boost::throw_file(__FILE__) << boost::throw_line(__LINE__) << boost::log::position_info(static_cast< unsigned int >(p - original_begin)) ); } // Safety check against ridiculously large argument numbers which would lead to excessive memory consumption. // This could be useful if the format string is gathered from an external source (e.g. a config file). if (n > 1000) { boost::throw_exception(boost::enable_error_info(limitation_error("Positional format placeholder too big")) << boost::throw_file(__FILE__) << boost::throw_line(__LINE__) << boost::log::position_info(static_cast< unsigned int >(p - original_begin)) ); } // We count positional arguments from 0, not from 1 as in format strings descr.format_elements.push_back(format_element::positional_argument(n - 1)); begin = pp + 1; // skip the closing '%' continue; } else { // This must be the filler character, not supported yet } } // This must be something else, not supported yet boost::throw_exception(boost::enable_error_info(parse_error("Unsupported format placeholder")) << boost::throw_file(__FILE__) << boost::throw_line(__LINE__) << boost::log::position_info(static_cast< unsigned int >(p - original_begin)) ); } else { if (p != end) descr.literal_chars.push_back(static_cast< char_type >('%')); // a single '%' character at the end of the string begin = end; } } const unsigned int literal_chars_size = static_cast< unsigned int >(descr.literal_chars.size()); if (literal_start_pos < literal_chars_size) descr.format_elements.push_back(format_element::literal(literal_start_pos, literal_chars_size - literal_start_pos)); return boost::move(descr); }