2
0
mirror of https://github.com/boostorg/log.git synced 2026-01-26 06:32:24 +00:00

Removed most of Boost.Spirit from the parameter partsers to speedup compilation and reduce binary sizes. This also significantly reduces memory consumption in case of Intel Compiler (down by ~600MiB).

This commit is contained in:
Andrey Semashev
2014-06-22 02:01:23 +04:00
parent da1f448fd5
commit a0ec391663
2 changed files with 160 additions and 91 deletions

View File

@@ -37,10 +37,7 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/spirit/include/qi_core.hpp>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_eoi.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
#include <boost/log/detail/code_conversion.hpp>
#include <boost/log/detail/singleton.hpp>
#include <boost/log/detail/default_attribute_names.hpp>
@@ -50,11 +47,10 @@
#include <boost/log/sinks/frontend_requirements.hpp>
#include <boost/log/expressions/filter.hpp>
#include <boost/log/expressions/formatter.hpp>
#include <boost/log/utility/string_literal.hpp>
#include <boost/log/utility/setup/from_settings.hpp>
#include <boost/log/utility/setup/filter_parser.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>
#include <boost/log/utility/functional/bind_assign.hpp>
#include <boost/log/utility/functional/as_action.hpp>
#if !defined(BOOST_LOG_NO_ASIO)
#include <boost/asio/ip/address.hpp>
#endif
@@ -90,26 +86,57 @@ inline IntT param_cast_to_int(const char* param_name, std::basic_string< CharT >
IntT res = 0;
typedef typename mpl::if_<
is_unsigned< IntT >,
qi::uint_parser< IntT >,
qi::int_parser< IntT >
>::type int_parser_t;
if (qi::parse(value.begin(), value.end(), int_parser_t() >> qi::eoi, res))
qi::extract_uint< IntT, 10, 1, -1 >,
qi::extract_int< IntT, 10, 1, -1 >
>::type extract;
const CharT* begin = value.c_str(), *end = begin + value.size();
if (extract::call(begin, end, res) && begin == end)
return res;
else
throw_invalid_value(param_name);
}
//! Case-insensitive character comparison predicate
struct is_case_insensitive_equal
{
typedef bool result_type;
template< typename CharT >
result_type operator() (CharT left, CharT right) const BOOST_NOEXCEPT
{
typedef typename boost::log::aux::encoding< CharT >::type encoding;
return encoding::tolower(left) == encoding::tolower(right);
}
};
//! Extracts a boolean value from parameter value
template< typename CharT >
inline bool param_cast_to_bool(const char* param_name, std::basic_string< CharT > const& value)
{
typedef boost::log::aux::encoding_specific< typename boost::log::aux::encoding< CharT >::type > encoding_specific;
typedef CharT char_type;
typedef boost::log::aux::char_constants< char_type > constants;
typedef boost::log::basic_string_literal< char_type > literal_type;
unsigned int res = 0;
if (qi::parse(value.begin(), value.end(), encoding_specific::no_case[ qi::uint_ | qi::bool_ ] >> qi::eoi, res))
return res != 0;
const char_type* begin = value.c_str(), *end = begin + value.size();
std::size_t len = end - begin;
literal_type keyword = constants::true_keyword();
if (keyword.size() == len && std::equal(begin, end, keyword.c_str(), is_case_insensitive_equal()))
{
return true;
}
else
throw_invalid_value(param_name);
{
keyword = constants::false_keyword();
if (keyword.size() == len && std::equal(begin, end, keyword.c_str(), is_case_insensitive_equal()))
{
return false;
}
else
{
return param_cast_to_int< unsigned int >(param_name, value) != 0;
}
}
}
#if !defined(BOOST_LOG_NO_ASIO)
@@ -121,64 +148,103 @@ inline std::string param_cast_to_address(const char* param_name, std::basic_stri
}
#endif // !defined(BOOST_LOG_NO_ASIO)
template< typename CharT >
inline bool is_weekday(const CharT* str, std::size_t len, boost::log::basic_string_literal< CharT > const& weekday, boost::log::basic_string_literal< CharT > const& short_weekday)
{
return (len == weekday.size() && std::equal(weekday.begin(), weekday.end(), str)) ||
(len == short_weekday.size() && std::equal(short_weekday.begin(), short_weekday.end(), str));
}
//! The function extracts the file rotation time point predicate from the parameter
template< typename CharT >
sinks::file::rotation_at_time_point param_cast_to_rotation_time_point(const char* param_name, std::basic_string< CharT > const& value)
{
typedef CharT char_type;
typedef boost::log::aux::encoding_specific< typename boost::log::aux::encoding< char_type >::type > encoding_specific;
typedef boost::log::aux::char_constants< char_type > constants;
typedef std::basic_string< char_type > string_type;
typedef typename boost::log::aux::encoding< char_type >::type encoding;
typedef boost::log::aux::encoding_specific< encoding > encoding_specific;
typedef boost::log::basic_string_literal< char_type > literal_type;
typedef qi::extract_uint< unsigned short, 10, 1, 2 > day_extract;
typedef qi::extract_uint< unsigned char, 10, 2, 2 > time_component_extract;
const char_type colon = static_cast< char_type >(':');
qi::uint_parser< unsigned char, 10, 2, 2 > time_component_p;
qi::uint_parser< unsigned short, 10, 1, 2 > day_p;
qi::symbols< CharT, date_time::weekdays > weekday_p;
weekday_p.add
(constants::monday_keyword(), date_time::Monday)
(constants::tuesday_keyword(), date_time::Tuesday)
(constants::wednesday_keyword(), date_time::Wednesday)
(constants::thursday_keyword(), date_time::Thursday)
(constants::friday_keyword(), date_time::Friday)
(constants::saturday_keyword(), date_time::Saturday)
(constants::sunday_keyword(), date_time::Sunday);
weekday_p.add
(constants::short_monday_keyword(), date_time::Monday)
(constants::short_tuesday_keyword(), date_time::Tuesday)
(constants::short_wednesday_keyword(), date_time::Wednesday)
(constants::short_thursday_keyword(), date_time::Thursday)
(constants::short_friday_keyword(), date_time::Friday)
(constants::short_saturday_keyword(), date_time::Saturday)
(constants::short_sunday_keyword(), date_time::Sunday);
optional< date_time::weekdays > weekday;
optional< unsigned short > day;
unsigned char hour = 0, minute = 0, second = 0;
const char_type* begin = value.c_str(), *end = begin + value.size();
bool result = qi::parse
(
value.begin(), value.end(),
(
-(
// First check for a weekday
(weekday_p >> qi::omit[ +encoding_specific::space ])[boost::log::as_action(boost::log::bind_assign(weekday))] |
// ... or a day in month
(day_p >> qi::omit[ +encoding_specific::space ])[boost::log::as_action(boost::log::bind_assign(day))]
) >>
// Then goes the time of day
(
time_component_p[boost::log::as_action(boost::log::bind_assign(hour))] >> colon >>
time_component_p[boost::log::as_action(boost::log::bind_assign(minute))] >> colon >>
time_component_p[boost::log::as_action(boost::log::bind_assign(second))]
) >>
qi::eoi
)
);
if (!result)
if (!encoding::isalnum(*begin)) // begin is null-terminated, so we also check that the string is not empty here
throw_invalid_value(param_name);
const char_type* p = begin + 1;
if (encoding::isalpha(*begin))
{
// This must be a weekday
while (encoding::isalpha(*p))
++p;
std::size_t len = p - begin;
if (is_weekday(begin, len, constants::monday_keyword(), constants::short_monday_keyword()))
weekday = date_time::Monday;
else if (is_weekday(begin, len, constants::tuesday_keyword(), constants::short_tuesday_keyword()))
weekday = date_time::Tuesday;
else if (is_weekday(begin, len, constants::wednesday_keyword(), constants::short_wednesday_keyword()))
weekday = date_time::Wednesday;
else if (is_weekday(begin, len, constants::thursday_keyword(), constants::short_thursday_keyword()))
weekday = date_time::Thursday;
else if (is_weekday(begin, len, constants::friday_keyword(), constants::short_friday_keyword()))
weekday = date_time::Friday;
else if (is_weekday(begin, len, constants::saturday_keyword(), constants::short_saturday_keyword()))
weekday = date_time::Saturday;
else if (is_weekday(begin, len, constants::sunday_keyword(), constants::short_sunday_keyword()))
weekday = date_time::Sunday;
else
throw_invalid_value(param_name);
}
else
{
// This may be either a month day or an hour
while (encoding::isdigit(*p))
++p;
if (encoding::isspace(*p))
{
// This is a month day
unsigned short mday = 0;
const char_type* b = begin;
if (!day_extract::call(b, p, mday) || b != p)
throw_invalid_value(param_name);
day = mday;
}
else if (*p == colon)
{
// This is an hour, reset the pointer
p = begin;
}
else
throw_invalid_value(param_name);
}
// Skip spaces
while (encoding::isspace(*p))
++p;
// Parse hour
if (!time_component_extract::call(p, end, hour) || *p != colon)
throw_invalid_value(param_name);
++p;
// Parse minute
if (!time_component_extract::call(p, end, minute) || *p != colon)
throw_invalid_value(param_name);
++p;
// Parse second
if (!time_component_extract::call(p, end, second) || p != end)
throw_invalid_value(param_name);
// Construct the predicate
if (weekday)
return sinks::file::rotation_at_time_point(weekday.get(), hour, minute, second);
else if (day)

View File

@@ -20,6 +20,7 @@
#include <iostream>
#include <cctype>
#include <boost/log/detail/config.hpp>
#include <boost/log/utility/string_literal.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -41,6 +42,7 @@ struct char_constants< char >
{
typedef char char_type;
typedef std::basic_string< char_type > string_type;
typedef boost::log::basic_string_literal< char_type > literal_type;
static const char_type char_comment = '#';
static const char_type char_comma = ',';
@@ -76,8 +78,8 @@ struct char_constants< char >
static const char_type* message_text_keyword() { return "_"; }
static const char_type* true_keyword() { return "true"; }
static const char_type* false_keyword() { return "false"; }
static literal_type true_keyword() { return literal_type("true"); }
static literal_type false_keyword() { return literal_type("false"); }
static const char_type* default_level_attribute_name() { return "Severity"; }
@@ -120,20 +122,20 @@ struct char_constants< char >
static const char_type* simple_event_log_destination() { return "SimpleEventLog"; }
static const char_type* debugger_destination() { return "Debugger"; }
static const char_type* monday_keyword() { return "Monday"; }
static const char_type* short_monday_keyword() { return "Mon"; }
static const char_type* tuesday_keyword() { return "Tuesday"; }
static const char_type* short_tuesday_keyword() { return "Tue"; }
static const char_type* wednesday_keyword() { return "Wednesday"; }
static const char_type* short_wednesday_keyword() { return "Wed"; }
static const char_type* thursday_keyword() { return "Thursday"; }
static const char_type* short_thursday_keyword() { return "Thu"; }
static const char_type* friday_keyword() { return "Friday"; }
static const char_type* short_friday_keyword() { return "Fri"; }
static const char_type* saturday_keyword() { return "Saturday"; }
static const char_type* short_saturday_keyword() { return "Sat"; }
static const char_type* sunday_keyword() { return "Sunday"; }
static const char_type* short_sunday_keyword() { return "Sun"; }
static literal_type monday_keyword() { return literal_type("Monday"); }
static literal_type short_monday_keyword() { return literal_type("Mon"); }
static literal_type tuesday_keyword() { return literal_type("Tuesday"); }
static literal_type short_tuesday_keyword() { return literal_type("Tue"); }
static literal_type wednesday_keyword() { return literal_type("Wednesday"); }
static literal_type short_wednesday_keyword() { return literal_type("Wed"); }
static literal_type thursday_keyword() { return literal_type("Thursday"); }
static literal_type short_thursday_keyword() { return literal_type("Thu"); }
static literal_type friday_keyword() { return literal_type("Friday"); }
static literal_type short_friday_keyword() { return literal_type("Fri"); }
static literal_type saturday_keyword() { return literal_type("Saturday"); }
static literal_type short_saturday_keyword() { return literal_type("Sat"); }
static literal_type sunday_keyword() { return literal_type("Sunday"); }
static literal_type short_sunday_keyword() { return literal_type("Sun"); }
static std::ostream& get_console_log_stream() { return std::clog; }
@@ -169,6 +171,7 @@ struct char_constants< wchar_t >
{
typedef wchar_t char_type;
typedef std::basic_string< char_type > string_type;
typedef boost::log::basic_string_literal< char_type > literal_type;
static const char_type char_comment = L'#';
static const char_type char_comma = L',';
@@ -204,8 +207,8 @@ struct char_constants< wchar_t >
static const char_type* message_text_keyword() { return L"_"; }
static const char_type* true_keyword() { return L"true"; }
static const char_type* false_keyword() { return L"false"; }
static literal_type true_keyword() { return literal_type(L"true"); }
static literal_type false_keyword() { return literal_type(L"false"); }
static const char_type* default_level_attribute_name() { return L"Severity"; }
@@ -248,20 +251,20 @@ struct char_constants< wchar_t >
static const char_type* simple_event_log_destination() { return L"SimpleEventLog"; }
static const char_type* debugger_destination() { return L"Debugger"; }
static const char_type* monday_keyword() { return L"Monday"; }
static const char_type* short_monday_keyword() { return L"Mon"; }
static const char_type* tuesday_keyword() { return L"Tuesday"; }
static const char_type* short_tuesday_keyword() { return L"Tue"; }
static const char_type* wednesday_keyword() { return L"Wednesday"; }
static const char_type* short_wednesday_keyword() { return L"Wed"; }
static const char_type* thursday_keyword() { return L"Thursday"; }
static const char_type* short_thursday_keyword() { return L"Thu"; }
static const char_type* friday_keyword() { return L"Friday"; }
static const char_type* short_friday_keyword() { return L"Fri"; }
static const char_type* saturday_keyword() { return L"Saturday"; }
static const char_type* short_saturday_keyword() { return L"Sat"; }
static const char_type* sunday_keyword() { return L"Sunday"; }
static const char_type* short_sunday_keyword() { return L"Sun"; }
static literal_type monday_keyword() { return literal_type(L"Monday"); }
static literal_type short_monday_keyword() { return literal_type(L"Mon"); }
static literal_type tuesday_keyword() { return literal_type(L"Tuesday"); }
static literal_type short_tuesday_keyword() { return literal_type(L"Tue"); }
static literal_type wednesday_keyword() { return literal_type(L"Wednesday"); }
static literal_type short_wednesday_keyword() { return literal_type(L"Wed"); }
static literal_type thursday_keyword() { return literal_type(L"Thursday"); }
static literal_type short_thursday_keyword() { return literal_type(L"Thu"); }
static literal_type friday_keyword() { return literal_type(L"Friday"); }
static literal_type short_friday_keyword() { return literal_type(L"Fri"); }
static literal_type saturday_keyword() { return literal_type(L"Saturday"); }
static literal_type short_saturday_keyword() { return literal_type(L"Sat"); }
static literal_type sunday_keyword() { return literal_type(L"Sunday"); }
static literal_type short_sunday_keyword() { return literal_type(L"Sun"); }
static std::wostream& get_console_log_stream() { return std::wclog; }