BIND 10 trac826, updated. 01493a27e861561f8b83dd9b95711cbfbe5b0929 [trac826] some updates
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Sep 28 15:17:15 UTC 2011
The branch, trac826 has been updated
via 01493a27e861561f8b83dd9b95711cbfbe5b0929 (commit)
from 66c822947a9999794df4b6a88451d04ed3b66d51 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 01493a27e861561f8b83dd9b95711cbfbe5b0929
Author: Francis Dupont <fdupont at isc.org>
Date: Wed Sep 28 17:09:58 2011 +0200
[trac826] some updates
use %BOOST% env var in VS2010 project files
update lib/exception (including tests)
update lib/log (note: still have to get back syslog in log4cplus on win32
and to update sub directories)
update lib/asiolink (including tests, no yet checked)
The goal is to be able to port lib/dhcp aka Kea to win32
-----------------------------------------------------------------------
Summary of changes:
src/lib/asiolink/README | 7 +
src/lib/asiolink/interval_timer.cc | 69 ++--
src/lib/asiolink/interval_timer.h | 10 +-
src/lib/asiolink/io_endpoint.h | 44 ++
src/lib/asiolink/simple_callback.h | 2 +-
src/lib/asiolink/tcp_endpoint.h | 8 +
src/lib/asiolink/tests/Makefile.am | 11 +-
src/lib/asiolink/tests/interval_timer_unittest.cc | 64 ++--
src/lib/asiolink/tests/io_endpoint_unittest.cc | 208 +++++++--
src/lib/asiolink/tests/run_unittests.cc | 10 +-
src/lib/asiolink/tests/udp_socket_unittest.cc | 4 +-
src/lib/asiolink/udp_endpoint.h | 8 +
src/lib/exceptions/exceptions.h | 36 ++-
src/lib/exceptions/tests/run_unittests.cc | 3 +
src/lib/log/Makefile.am | 30 +-
src/lib/log/README | 482 +++++++++++++-------
src/lib/log/debug_levels.h | 29 --
.../log/{root_logger_name.cc => log_formatter.cc} | 42 +-
src/lib/log/log_formatter.h | 219 +++++++++
src/lib/log/log_messages.cc | 63 +++
src/lib/log/log_messages.h | 35 ++
src/lib/log/log_messages.mes | 146 ++++++
src/lib/log/logger.cc | 100 +++--
src/lib/log/logger.h | 187 ++++----
src/lib/log/logger_impl.cc | 218 +++-------
src/lib/log/logger_impl.h | 202 +++------
src/lib/log/logger_impl_log4cxx.cc | 242 ----------
src/lib/log/logger_impl_log4cxx.h | 315 -------------
src/lib/log/logger_level.cc | 48 ++
src/lib/log/logger_level.h | 80 ++++
src/lib/log/logger_level_impl.cc | 234 ++++++++++
src/lib/log/logger_level_impl.h | 127 +++++
src/lib/log/logger_levels.h | 46 --
src/lib/log/logger_manager.cc | 184 ++++++++
src/lib/log/logger_manager.h | 141 ++++++
src/lib/log/logger_manager_impl.cc | 236 ++++++++++
src/lib/log/logger_manager_impl.h | 171 +++++++
.../log/{root_logger_name.cc => logger_name.cc} | 17 +-
src/lib/log/{root_logger_name.h => logger_name.h} | 25 +-
src/lib/log/logger_specification.h | 156 +++++++
src/lib/log/logger_support.cc | 118 +----
src/lib/log/logger_support.h | 35 ++-
src/lib/log/logger_unittest_support.cc | 179 ++++++++
src/lib/log/logger_unittest_support.h | 126 +++++
src/lib/log/logimpl_messages.cc | 29 ++
src/lib/log/logimpl_messages.h | 18 +
src/lib/log/logimpl_messages.mes | 43 ++
src/lib/log/macros.h | 50 ++
src/lib/log/message_exception.cc | 26 -
src/lib/log/message_exception.h | 37 +-
src/lib/log/message_reader.cc | 184 +++++---
src/lib/log/message_reader.h | 19 +-
src/lib/log/messagedef.cc | 57 ---
src/lib/log/messagedef.h | 32 --
src/lib/log/messagedef.mes | 119 -----
src/lib/log/output_option.cc | 55 +++
src/lib/log/output_option.h | 85 ++++
src/lib/log/xdebuglevel.cc | 146 ------
src/lib/log/xdebuglevel.h | 162 -------
win32build/VS2010/libasiodns/libasiodns.vcxproj | 6 +-
.../libasiodns_tests/libasiodns_tests.vcxproj | 10 +-
win32build/VS2010/libasiolink/libasiolink.vcxproj | 6 +-
.../libasiolink_tests/libasiolink_tests.vcxproj | 10 +-
win32build/VS2010/libbench/libbench.vcxproj | 6 +-
.../VS2010/libbench_tests/libbench_tests.vcxproj | 6 +-
win32build/VS2010/libcache/libcache.vcxproj | 6 +-
.../VS2010/libcache_tests/libcache_tests.vcxproj | 6 +-
win32build/VS2010/libcc/libcc.vcxproj | 6 +-
win32build/VS2010/libcc_tests/libcc_tests.vcxproj | 10 +-
.../VS2010/libcfgclient/libcfgclient.vcxproj | 6 +-
.../libcfgclient_tests/libcfgclient_tests.vcxproj | 6 +-
.../VS2010/libcryptolink/libcryptolink.vcxproj | 6 +-
.../libcryptolink_tests.vcxproj | 6 +-
win32build/VS2010/libdatasrc/libdatasrc.vcxproj | 6 +-
.../libdatasrc_tests/libdatasrc_tests.vcxproj | 6 +-
win32build/VS2010/libdns++/libdns++.vcxproj | 6 +-
.../libdns++_benchmarks.vcxproj | 6 +-
.../VS2010/libdns++_python/libdns++_python.vcxproj | 6 +-
.../VS2010/libdns++_tests/libdns++_tests.vcxproj | 6 +-
win32build/VS2010/liblog/liblog.vcxproj | 35 +-
win32build/VS2010/liblog/liblog.vcxproj.filters | 73 +++-
.../VS2010/liblog_compiler/liblog_compiler.vcxproj | 6 +-
.../VS2010/liblog_tests/liblog_tests.vcxproj | 6 +-
win32build/VS2010/libnsas/libnsas.vcxproj | 6 +-
.../VS2010/libnsas_tests/libnsas_tests.vcxproj | 10 +-
win32build/VS2010/libresolve/libresolve.vcxproj | 6 +-
.../libresolve_tests/libresolve_tests.vcxproj | 10 +-
.../libserver_common/libserver_common.vcxproj | 6 +-
.../libserver_common_tests.vcxproj | 10 +-
.../VS2010/libtestutils/libtestutils.vcxproj | 6 +-
win32build/VS2010/libutil/libutil.vcxproj | 6 +-
.../VS2010/libutil_tests/libutil_tests.vcxproj | 6 +-
win32build/VS2010/libxfr/libxfr.vcxproj | 6 +-
93 files changed, 3847 insertions(+), 2256 deletions(-)
delete mode 100644 src/lib/log/debug_levels.h
copy src/lib/log/{root_logger_name.cc => log_formatter.cc} (55%)
create mode 100644 src/lib/log/log_formatter.h
create mode 100644 src/lib/log/log_messages.cc
create mode 100644 src/lib/log/log_messages.h
create mode 100644 src/lib/log/log_messages.mes
delete mode 100644 src/lib/log/logger_impl_log4cxx.cc
delete mode 100644 src/lib/log/logger_impl_log4cxx.h
create mode 100644 src/lib/log/logger_level.cc
create mode 100644 src/lib/log/logger_level.h
create mode 100644 src/lib/log/logger_level_impl.cc
create mode 100644 src/lib/log/logger_level_impl.h
delete mode 100644 src/lib/log/logger_levels.h
create mode 100644 src/lib/log/logger_manager.cc
create mode 100644 src/lib/log/logger_manager.h
create mode 100644 src/lib/log/logger_manager_impl.cc
create mode 100644 src/lib/log/logger_manager_impl.h
rename src/lib/log/{root_logger_name.cc => logger_name.cc} (71%)
rename src/lib/log/{root_logger_name.h => logger_name.h} (66%)
create mode 100644 src/lib/log/logger_specification.h
create mode 100644 src/lib/log/logger_unittest_support.cc
create mode 100644 src/lib/log/logger_unittest_support.h
create mode 100644 src/lib/log/logimpl_messages.cc
create mode 100644 src/lib/log/logimpl_messages.h
create mode 100644 src/lib/log/logimpl_messages.mes
create mode 100644 src/lib/log/macros.h
delete mode 100644 src/lib/log/message_exception.cc
delete mode 100644 src/lib/log/messagedef.cc
delete mode 100644 src/lib/log/messagedef.h
delete mode 100644 src/lib/log/messagedef.mes
create mode 100644 src/lib/log/output_option.cc
create mode 100644 src/lib/log/output_option.h
delete mode 100644 src/lib/log/xdebuglevel.cc
delete mode 100644 src/lib/log/xdebuglevel.h
-----------------------------------------------------------------------
diff --git a/src/lib/asiolink/README b/src/lib/asiolink/README
index 66091b1..b9e38f9 100644
--- a/src/lib/asiolink/README
+++ b/src/lib/asiolink/README
@@ -20,3 +20,10 @@ Some of the classes defined here--for example, IOSocket, IOEndpoint,
and IOAddress--are to be used by BIND 10 modules as wrappers around
ASIO-specific classes.
+
+Logging
+-------
+
+At this point, nothing is logged by this low-level library. We may
+revisit that in the future, if we find suitable messages to log, but
+right now there are also no loggers initialized or called.
diff --git a/src/lib/asiolink/interval_timer.cc b/src/lib/asiolink/interval_timer.cc
index d85488d..9873e9b 100644
--- a/src/lib/asiolink/interval_timer.cc
+++ b/src/lib/asiolink/interval_timer.cc
@@ -14,15 +14,9 @@
#include <config.h>
-#ifdef _WIN32
-#include <ws2tcpip.h>
-#else
-#include <unistd.h> // for some IPC/network system calls
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
#include <exceptions/exceptions.h>
@@ -33,7 +27,16 @@
namespace isc {
namespace asiolink {
-class IntervalTimerImpl {
+/// This class holds a call back function of asynchronous operations.
+/// To ensure the object is alive while an asynchronous operation refers
+/// to it, we use shared_ptr and enable_shared_from_this.
+/// The object will be destructed in case IntervalTimer has been destructed
+/// and no asynchronous operation refers to it.
+/// Please follow the link to get an example:
+/// http://think-async.com/asio/asio-1.4.8/doc/asio/tutorial/tutdaytime3.html#asio.tutorial.tutdaytime3.the_tcp_connection_class
+class IntervalTimerImpl :
+ public boost::enable_shared_from_this<IntervalTimerImpl>
+{
private:
// prohibit copy
IntervalTimerImpl(const IntervalTimerImpl& source);
@@ -57,14 +60,18 @@ private:
long interval_;
// asio timer
asio::deadline_timer timer_;
+ // interval_ will be set to this value in destructor in order to detect
+ // use-after-free type of bugs.
+ static const long INVALIDATED_INTERVAL = -1;
};
IntervalTimerImpl::IntervalTimerImpl(IOService& io_service) :
interval_(0), timer_(io_service.get_io_service())
{}
-IntervalTimerImpl::~IntervalTimerImpl()
-{}
+IntervalTimerImpl::~IntervalTimerImpl() {
+ interval_ = INVALIDATED_INTERVAL;
+}
void
IntervalTimerImpl::setup(const IntervalTimer::Callback& cbfunc,
@@ -85,42 +92,46 @@ IntervalTimerImpl::setup(const IntervalTimer::Callback& cbfunc,
// At this point the timer is not running yet and will not expire.
// After calling IOService::run(), the timer will expire.
update();
- return;
}
void
IntervalTimerImpl::update() {
- if (interval_ == 0) {
- // timer has been canceled. Do nothing.
- return;
- }
try {
// Update expire time to (current time + interval_).
timer_.expires_from_now(boost::posix_time::millisec(interval_));
- } catch (const asio::system_error&) {
- isc_throw(isc::Unexpected, "Failed to update timer");
+ // Reset timer.
+ // Pass a function bound with a shared_ptr to this.
+ timer_.async_wait(boost::bind(&IntervalTimerImpl::callback,
+ shared_from_this(),
+ asio::placeholders::error));
+ } catch (const asio::system_error& e) {
+ isc_throw(isc::Unexpected, "Failed to update timer: " << e.what());
+ } catch (const boost::bad_weak_ptr&) {
+ // Can't happen. It means a severe internal bug.
+ assert(0);
}
- // Reset timer.
- timer_.async_wait(boost::bind(&IntervalTimerImpl::callback, this, _1));
}
void
-IntervalTimerImpl::callback(const asio::error_code& cancelled) {
- // Do not call cbfunc_ in case the timer was cancelled.
- // The timer will be canelled in the destructor of asio::deadline_timer.
- if (!cancelled) {
- cbfunc_();
+IntervalTimerImpl::callback(const asio::error_code& ec) {
+ assert(interval_ != INVALIDATED_INTERVAL);
+ if (interval_ == 0 || ec) {
+ // timer has been canceled. Do nothing.
+ } else {
// Set next expire time.
update();
+ // Invoke the call back function.
+ cbfunc_();
}
}
-IntervalTimer::IntervalTimer(IOService& io_service) {
- impl_ = new IntervalTimerImpl(io_service);
-}
+IntervalTimer::IntervalTimer(IOService& io_service) :
+ impl_(new IntervalTimerImpl(io_service))
+{}
IntervalTimer::~IntervalTimer() {
- delete impl_;
+ // Cancel the timer to make sure cbfunc_() will not be called any more.
+ cancel();
}
void
diff --git a/src/lib/asiolink/interval_timer.h b/src/lib/asiolink/interval_timer.h
index 8de16cb..57ec1c3 100644
--- a/src/lib/asiolink/interval_timer.h
+++ b/src/lib/asiolink/interval_timer.h
@@ -16,6 +16,7 @@
#define __ASIOLINK_INTERVAL_TIMER_H 1
#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
#include <asiolink/io_service.h>
@@ -42,9 +43,6 @@ class IntervalTimerImpl;
/// The call back function will not be called if the instance of this class is
/// destroyed before the timer is expired.
///
-/// Note: Destruction of an instance of this class while call back is pending
-/// causes throwing an exception from \c IOService.
-///
/// Sample code:
/// \code
/// void function_to_call_back() {
@@ -100,12 +98,12 @@ public:
/// \param interval Interval in milliseconds (greater than 0)
///
/// Note: IntervalTimer will not pass \c asio::error_code to
- /// call back function. In case the timer is cancelled, the function
+ /// call back function. In case the timer is canceled, the function
/// will not be called.
///
/// \throw isc::InvalidParameter cbfunc is empty
/// \throw isc::BadValue interval is less than or equal to 0
- /// \throw isc::Unexpected ASIO library error
+ /// \throw isc::Unexpected internal runtime error
void setup(const Callback& cbfunc, const long interval);
/// Cancel the timer.
@@ -127,7 +125,7 @@ public:
long getInterval() const;
private:
- IntervalTimerImpl* impl_;
+ boost::shared_ptr<IntervalTimerImpl> impl_;
};
} // namespace asiolink
diff --git a/src/lib/asiolink/io_endpoint.h b/src/lib/asiolink/io_endpoint.h
index 5a3be84..14d76b6 100644
--- a/src/lib/asiolink/io_endpoint.h
+++ b/src/lib/asiolink/io_endpoint.h
@@ -20,6 +20,8 @@
// See the description of the namespace below.
#ifndef _WIN32
#include <unistd.h> // for some network system calls
+
+#include <sys/socket.h> // for sockaddr
#endif
#include <functional>
@@ -92,6 +94,44 @@ public:
/// \brief Returns the address family of the endpoint.
virtual short getFamily() const = 0;
+ /// \brief Returns the address of the endpoint in the form of sockaddr
+ /// structure.
+ ///
+ /// The actual instance referenced by the returned value of this method
+ /// is of per address family structure: For IPv4 (AF_INET), it's
+ /// \c sockaddr_in; for IPv6 (AF_INET6), it's \c sockaddr_in6.
+ /// The corresponding port and address members of the underlying structure
+ /// will be set in the network byte order.
+ ///
+ /// This method is "redundant" in that all information to construct the
+ /// \c sockaddr is available via the other "get" methods.
+ /// It is still defined for performance sensitive applications that need
+ /// to get the address information, such as for address based access
+ /// control at a high throughput. Internally it is implemented with
+ /// minimum overhead such as data copy (this is another reason why this
+ /// method returns a reference).
+ ///
+ /// As a tradeoff, this method is more fragile; it assumes that the
+ /// underlying ASIO implementation stores the address information in
+ /// the form of \c sockaddr and it can be accessed in an efficient way.
+ /// This is the case as of this writing, but if the underlying
+ /// implementation changes this method may become much slower or its
+ /// interface may have to be changed, too.
+ ///
+ /// It is therefore discouraged for normal applications to use this
+ /// method. Unless the application is very performance sensitive, it
+ /// should use the other "get" method to retrieve specific information
+ /// of the endpoint.
+ ///
+ /// The returned reference is only valid while the corresponding
+ /// \c IOEndpoint is valid. Once it's destructed the reference will
+ /// become invalid.
+ ///
+ /// \exception None
+ /// \return Reference to a \c sockaddr structure corresponding to the
+ /// endpoint.
+ virtual const struct sockaddr& getSockAddr() const = 0;
+
bool operator==(const IOEndpoint& other) const;
bool operator!=(const IOEndpoint& other) const;
@@ -123,3 +163,7 @@ public:
} // namespace asiolink
} // namespace isc
#endif // __IO_ENDPOINT_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/asiolink/simple_callback.h b/src/lib/asiolink/simple_callback.h
index 6cb07e2..92093ec 100644
--- a/src/lib/asiolink/simple_callback.h
+++ b/src/lib/asiolink/simple_callback.h
@@ -49,7 +49,7 @@ protected:
///
/// This is intentionally defined as \c protected as this base class
/// should never be instantiated (except as part of a derived class).
- SimpleCallback() { self_ = this; }
+ SimpleCallback() : self_(this) {}
public:
/// \brief The destructor
virtual ~SimpleCallback() {}
diff --git a/src/lib/asiolink/tcp_endpoint.h b/src/lib/asiolink/tcp_endpoint.h
index 3e420f3..a54f6b2 100644
--- a/src/lib/asiolink/tcp_endpoint.h
+++ b/src/lib/asiolink/tcp_endpoint.h
@@ -84,6 +84,10 @@ public:
return (asio_endpoint_.address());
}
+ virtual const struct sockaddr& getSockAddr() const {
+ return (*asio_endpoint_.data());
+ }
+
virtual uint16_t getPort() const {
return (asio_endpoint_.port());
}
@@ -113,3 +117,7 @@ private:
} // namespace asiolink
} // namespace isc
#endif // __TCP_ENDPOINT_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/asiolink/tests/Makefile.am b/src/lib/asiolink/tests/Makefile.am
index bfdf7c1..984cf07 100644
--- a/src/lib/asiolink/tests/Makefile.am
+++ b/src/lib/asiolink/tests/Makefile.am
@@ -10,6 +10,12 @@ if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
+# Some versions of GCC warn about some versions of Boost regarding
+# missing initializer for members in its posix_time.
+# https://svn.boost.org/trac/boost/ticket/3477
+# But older GCC compilers don't have the flag.
+AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
+
CLEANFILES = *.gcno *.gcda
TESTS =
@@ -28,13 +34,12 @@ run_unittests_SOURCES += udp_socket_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDADD = $(GTEST_LDADD)
-run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
-run_unittests_LDADD += $(top_builddir)/src/lib/util/libutil.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
+run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
diff --git a/src/lib/asiolink/tests/interval_timer_unittest.cc b/src/lib/asiolink/tests/interval_timer_unittest.cc
index e89c129..d75f855 100644
--- a/src/lib/asiolink/tests/interval_timer_unittest.cc
+++ b/src/lib/asiolink/tests/interval_timer_unittest.cc
@@ -19,7 +19,7 @@
#include <asio.hpp>
#include <asiolink/asiolink.h>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
namespace {
// TODO: Consider this margin
@@ -29,7 +29,7 @@ const boost::posix_time::time_duration TIMER_MARGIN_MSEC =
using namespace isc::asiolink;
-// This fixture is for testing IntervalTimer. Some callback functors are
+// This fixture is for testing IntervalTimer. Some callback functors are
// registered as callback function of the timer to test if they are called
// or not.
class IntervalTimerTest : public ::testing::Test {
@@ -51,7 +51,9 @@ protected:
};
class TimerCallBackCounter : public std::unary_function<void, void> {
public:
- TimerCallBackCounter(IntervalTimerTest* test_obj) : test_obj_(test_obj) {
+ TimerCallBackCounter(IntervalTimerTest* test_obj) :
+ test_obj_(test_obj)
+ {
counter_ = 0;
}
void operator()() {
@@ -98,8 +100,8 @@ protected:
int prev_counter_;
// silence MSVC warning C4512:
// assignment operator could not be generated
- TimerCallBackCancelDeleter& operator=(TimerCallBackCancelDeleter const&);
-
+ TimerCallBackCancelDeleter&
+ operator=(TimerCallBackCancelDeleter const&);
};
class TimerCallBackCanceller {
public:
@@ -116,7 +118,6 @@ protected:
// silence MSVC warning C4512:
// assignment operator could not be generated
TimerCallBackCanceller& operator=(TimerCallBackCanceller const&);
-
};
class TimerCallBackOverwriter : public std::unary_function<void, void> {
public:
@@ -176,18 +177,20 @@ TEST_F(IntervalTimerTest, startIntervalTimer) {
itimer.setup(TimerCallBack(this), 100);
EXPECT_EQ(100, itimer.getInterval());
io_service_.run();
- // reaches here after timer expired
+ // Control reaches here after io_service_ was stopped by TimerCallBack.
+
// delta: difference between elapsed time and 100 milliseconds.
- boost::posix_time::time_duration delta =
- (boost::posix_time::microsec_clock::universal_time() - start)
- - boost::posix_time::millisec(100);
- if (delta.is_negative()) {
- delta.invert_sign();
- }
- // expect TimerCallBack is called; timer_called_ is true
+ boost::posix_time::time_duration test_runtime =
+ boost::posix_time::microsec_clock::universal_time() - start;
+ EXPECT_FALSE(test_runtime.is_negative()) <<
+ "test duration " << test_runtime <<
+ " negative - clock skew?";
+ // Expect TimerCallBack is called; timer_called_ is true
EXPECT_TRUE(timer_called_);
- // expect interval is 100 milliseconds +/- TIMER_MARGIN_MSEC.
- EXPECT_TRUE(delta < TIMER_MARGIN_MSEC);
+ // Expect test_runtime is 100 milliseconds or longer.
+ EXPECT_TRUE(test_runtime > boost::posix_time::milliseconds(100)) <<
+ "test runtime " << test_runtime.total_milliseconds() <<
+ "msec " << ">= 100";
}
TEST_F(IntervalTimerTest, destructIntervalTimer) {
@@ -250,7 +253,7 @@ TEST_F(IntervalTimerTest, cancel) {
}
TEST_F(IntervalTimerTest, overwriteIntervalTimer) {
- // Calling setup() multiple times updates call back function and interval.
+ // Call setup() multiple times to update call back function and interval.
//
// There are two timers:
// itimer (A)
@@ -272,7 +275,7 @@ TEST_F(IntervalTimerTest, overwriteIntervalTimer) {
// 0 100 200 300 400 500 600 700 800 (ms)
// (A) i-------------+----C----s
// ^ ^stop io_service
- // |change call back function
+ // |change call back function and interval
// (B) i------------------+-------------------S
// ^(stop io_service on fail)
//
@@ -285,24 +288,11 @@ TEST_F(IntervalTimerTest, overwriteIntervalTimer) {
itimer.setup(TimerCallBackCounter(this), 300);
itimer_overwriter.setup(TimerCallBackOverwriter(this, itimer), 400);
io_service_.run();
- // reaches here after timer expired
- // if interval is updated, it takes
- // 400 milliseconds for TimerCallBackOverwriter
- // + 100 milliseconds for TimerCallBack (stop)
- // = 500 milliseconds.
- // otherwise (test fails), it takes
- // 400 milliseconds for TimerCallBackOverwriter
- // + 400 milliseconds for TimerCallBackOverwriter (stop)
- // = 800 milliseconds.
- // delta: difference between elapsed time and 400 + 100 milliseconds
- boost::posix_time::time_duration delta =
- (boost::posix_time::microsec_clock::universal_time() - start)
- - boost::posix_time::millisec(400 + 100);
- if (delta.is_negative()) {
- delta.invert_sign();
- }
- // expect callback function is updated: TimerCallBack is called
+ // Control reaches here after io_service_ was stopped by
+ // TimerCallBackCounter or TimerCallBackOverwriter.
+
+ // Expect callback function is updated: TimerCallBack is called
EXPECT_TRUE(timer_called_);
- // expect interval is updated
- EXPECT_TRUE(delta < TIMER_MARGIN_MSEC);
+ // Expect interval is updated: return value of getInterval() is updated
+ EXPECT_EQ(itimer.getInterval(), 100);
}
diff --git a/src/lib/asiolink/tests/io_endpoint_unittest.cc b/src/lib/asiolink/tests/io_endpoint_unittest.cc
index 666c35b..5e347a3 100644
--- a/src/lib/asiolink/tests/io_endpoint_unittest.cc
+++ b/src/lib/asiolink/tests/io_endpoint_unittest.cc
@@ -16,14 +16,29 @@
#include <stdint.h>
#include <gtest/gtest.h>
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#endif
+#include <string.h>
+
+#include <boost/shared_ptr.hpp>
+
#include <asiolink/io_endpoint.h>
#include <asiolink/io_error.h>
+using boost::shared_ptr;
using namespace isc::asiolink;
+namespace {
+typedef shared_ptr<const IOEndpoint> ConstIOEndpointPtr;
+
TEST(IOEndpointTest, createUDPv4) {
- const IOEndpoint* ep;
- ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 53210);
+ ConstIOEndpointPtr ep(IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("192.0.2.1"), 53210));
EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
EXPECT_EQ(53210, ep->getPort());
EXPECT_EQ(AF_INET, ep->getFamily());
@@ -32,8 +47,8 @@ TEST(IOEndpointTest, createUDPv4) {
}
TEST(IOEndpointTest, createTCPv4) {
- const IOEndpoint* ep;
- ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5301);
+ ConstIOEndpointPtr ep(IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("192.0.2.1"), 5301));
EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
EXPECT_EQ(5301, ep->getPort());
EXPECT_EQ(AF_INET, ep->getFamily());
@@ -42,8 +57,9 @@ TEST(IOEndpointTest, createTCPv4) {
}
TEST(IOEndpointTest, createUDPv6) {
- const IOEndpoint* ep;
- ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5302);
+ ConstIOEndpointPtr ep(IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1234"),
+ 5302));
EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
EXPECT_EQ(5302, ep->getPort());
EXPECT_EQ(AF_INET6, ep->getFamily());
@@ -52,8 +68,9 @@ TEST(IOEndpointTest, createUDPv6) {
}
TEST(IOEndpointTest, createTCPv6) {
- const IOEndpoint* ep;
- ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5303);
+ ConstIOEndpointPtr ep(IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1234"),
+ 5303));
EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
EXPECT_EQ(5303, ep->getPort());
EXPECT_EQ(AF_INET6, ep->getFamily());
@@ -62,23 +79,55 @@ TEST(IOEndpointTest, createTCPv6) {
}
TEST(IOEndpointTest, equality) {
- std::vector<const IOEndpoint *> epv;
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5304));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5304));
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1235"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1235"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1235"), 5304));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1235"), 5304));
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5304));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 5304));
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.2"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.2"), 5303));
- epv.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.2"), 5304));
- epv.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.2"), 5304));
+ std::vector<ConstIOEndpointPtr> epv;
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1234"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1234"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1234"), 5304)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1234"), 5304)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1235"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1235"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1235"), 5304)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1235"), 5304)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("192.0.2.1"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("192.0.2.1"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("192.0.2.1"), 5304)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("192.0.2.1"), 5304)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("192.0.2.2"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("192.0.2.2"), 5303)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("192.0.2.2"), 5304)));
+ epv.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("192.0.2.2"), 5304)));
for (size_t i = 0; i < epv.size(); ++i) {
for (size_t j = 0; j < epv.size(); ++j) {
@@ -93,23 +142,55 @@ TEST(IOEndpointTest, equality) {
// Create a second array with exactly the same values. We use create()
// again to make sure we get different endpoints
- std::vector<const IOEndpoint *> epv2;
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5304));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5304));
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1235"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1235"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1235"), 5304));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1235"), 5304));
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5304));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 5304));
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.2"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.2"), 5303));
- epv2.push_back(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.2"), 5304));
- epv2.push_back(IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.2"), 5304));
+ std::vector<ConstIOEndpointPtr> epv2;
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1234"), 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1234"), 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1234"), 5304)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1234"), 5304)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1235"), 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1235"), 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("2001:db8::1235"), 5304)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("2001:db8::1235"), 5304)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP,
+ IOAddress("192.0.2.1"), 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("192.0.2.1"), 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"),
+ 5304)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"),
+ 5304)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.2"),
+ 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.2"),
+ 5303)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.2"),
+ 5304)));
+ epv2.push_back(ConstIOEndpointPtr(
+ IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.2"),
+ 5304)));
for (size_t i = 0; i < epv.size(); ++i) {
EXPECT_TRUE(*epv[i] == *epv2[i]);
@@ -123,3 +204,46 @@ TEST(IOEndpointTest, createIPProto) {
IOError);
}
+void
+sockAddrMatch(const struct sockaddr& actual_sa,
+ const char* const expected_addr_text,
+ const char* const expected_port_text)
+{
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM; // this shouldn't matter
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+
+ struct addrinfo* res;
+ ASSERT_EQ(0, getaddrinfo(expected_addr_text, expected_port_text, &hints,
+ &res));
+ EXPECT_EQ(res->ai_family, actual_sa.sa_family);
+#ifdef HAVE_SA_LEN
+ // ASIO doesn't seem to set sa_len, so we set it to the expected value
+ res->ai_addr->sa_len = actual_sa.sa_len;
+#endif
+ EXPECT_EQ(0, memcmp(res->ai_addr, &actual_sa, res->ai_addrlen));
+ free(res);
+}
+
+TEST(IOEndpointTest, getSockAddr) {
+ // UDP/IPv4
+ ConstIOEndpointPtr ep(IOEndpoint::create(IPPROTO_UDP,
+ IOAddress("192.0.2.1"), 53210));
+ sockAddrMatch(ep->getSockAddr(), "192.0.2.1", "53210");
+
+ // UDP/IPv6
+ ep.reset(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::53"), 53));
+ sockAddrMatch(ep->getSockAddr(), "2001:db8::53", "53");
+
+ // TCP/IPv4
+ ep.reset(IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.2"), 53211));
+ sockAddrMatch(ep->getSockAddr(), "192.0.2.2", "53211");
+
+ // TCP/IPv6
+ ep.reset(IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::5300"), 35));
+ sockAddrMatch(ep->getSockAddr(), "2001:db8::5300", "35");
+}
+
+}
diff --git a/src/lib/asiolink/tests/run_unittests.cc b/src/lib/asiolink/tests/run_unittests.cc
index 97bcb65..b07ce7e 100644
--- a/src/lib/asiolink/tests/run_unittests.cc
+++ b/src/lib/asiolink/tests/run_unittests.cc
@@ -13,15 +13,13 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <gtest/gtest.h>
-
-#include <log/root_logger_name.h>
-#include <dns/tests/unittest_util.h>
+#include <util/unittests/run_all.h>
+#include <log/logger_manager.h>
int
main(int argc, char* argv[])
{
::testing::InitGoogleTest(&argc, argv); // Initialize Google test
- isc::log::setRootLoggerName("unittest"); // Set a root logger name
-
- return (RUN_ALL_TESTS());
+ isc::log::LoggerManager::init("unittest"); // Set a root logger name
+ return (isc::util::unittests::run_all());
}
diff --git a/src/lib/asiolink/tests/udp_socket_unittest.cc b/src/lib/asiolink/tests/udp_socket_unittest.cc
index d4669f6..acf13de 100644
--- a/src/lib/asiolink/tests/udp_socket_unittest.cc
+++ b/src/lib/asiolink/tests/udp_socket_unittest.cc
@@ -331,9 +331,7 @@ TEST(UDPSocket, SequenceTest) {
// ...and check that the data was copied to the output client buffer.
const char* client_char_data = static_cast<const char*>(client_buffer->getData());
- EXPECT_TRUE(equal(&data[0],
- &data[client_cb.getLength() - 1],
- client_char_data));
+ EXPECT_TRUE(equal(&data[0], &data[client_cb.getLength() - 1], client_char_data));
// Close client and server.
EXPECT_NO_THROW(client.close());
diff --git a/src/lib/asiolink/udp_endpoint.h b/src/lib/asiolink/udp_endpoint.h
index 5c8a1fe..c5ba3bd 100644
--- a/src/lib/asiolink/udp_endpoint.h
+++ b/src/lib/asiolink/udp_endpoint.h
@@ -84,6 +84,10 @@ public:
return (asio_endpoint_.address());
}
+ virtual const struct sockaddr& getSockAddr() const {
+ return (*asio_endpoint_.data());
+ }
+
virtual uint16_t getPort() const {
return (asio_endpoint_.port());
}
@@ -113,3 +117,7 @@ private:
} // namespace asiolink
} // namespace isc
#endif // __UDP_ENDPOINT_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/exceptions/exceptions.h b/src/lib/exceptions/exceptions.h
index 61d5397..7819052 100644
--- a/src/lib/exceptions/exceptions.h
+++ b/src/lib/exceptions/exceptions.h
@@ -137,6 +137,18 @@ public:
};
///
+/// \brief A generic exception that is thrown when a function is
+/// not implemented.
+///
+/// This may be due to unfinished implementation or in case the
+/// function isn't even planned to be provided for that situation.
+class NotImplemented : public Exception {
+public:
+ NotImplemented(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+///
/// A shortcut macro to insert known values into exception arguments.
///
/// It allows the \c stream argument to be part of a statement using an
@@ -157,7 +169,6 @@ public:
/// this is defined as a macro. The convenience for the ostream is a secondary
/// purpose (if that were the only possible reason we should rather avoid
/// using a macro).
-/// Avoid C4127 warning: conditional expression is constant
#ifdef _MSC_VER
#define isc_throw(type, stream) \
__pragma(warning(push)) \
@@ -176,6 +187,29 @@ public:
throw type(__FILE__, __LINE__, oss__.str().c_str()); \
} while (1)
#endif
+
+///
+/// Similar as isc_throw, but allows the exception to have one additional
+/// parameter (the stream/text goes first)
+#ifdef _MSC_VER
+#define isc_throw_1(type, stream, param1) \
+ __pragma(warning(push)) \
+ __pragma(warning(disable: 4127)) \
+ do { \
+ std::ostringstream oss__; \
+ oss__ << stream; \
+ throw type(__FILE__, __LINE__, oss__.str().c_str(), param1); \
+ } while (1) \
+ __pragma(warning(pop))
+#else
+#define isc_throw_1(type, stream, param1) \
+ do { \
+ std::ostringstream oss__; \
+ oss__ << stream; \
+ throw type(__FILE__, __LINE__, oss__.str().c_str(), param1); \
+ } while (1)
+#endif
+
}
#endif // __EXCEPTIONS_H
diff --git a/src/lib/exceptions/tests/run_unittests.cc b/src/lib/exceptions/tests/run_unittests.cc
index 0908071..6a0de4f 100644
--- a/src/lib/exceptions/tests/run_unittests.cc
+++ b/src/lib/exceptions/tests/run_unittests.cc
@@ -17,5 +17,8 @@
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
+
+ // Unlike other tests we cannot use our wrapper for RUN_ALL_TESTS()
+ // due to dependency.
return (RUN_ALL_TESTS());
}
diff --git a/src/lib/log/Makefile.am b/src/lib/log/Makefile.am
index 5770564..9f52724 100644
--- a/src/lib/log/Makefile.am
+++ b/src/lib/log/Makefile.am
@@ -2,30 +2,37 @@ SUBDIRS = . compiler tests
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = liblog.la
liblog_la_SOURCES =
-liblog_la_SOURCES += debug_levels.h logger_levels.h
liblog_la_SOURCES += dummylog.h dummylog.cc
+liblog_la_SOURCES += logimpl_messages.cc logimpl_messages.h
+liblog_la_SOURCES += log_formatter.h log_formatter.cc
liblog_la_SOURCES += logger.cc logger.h
liblog_la_SOURCES += logger_impl.cc logger_impl.h
+liblog_la_SOURCES += logger_level.h
+liblog_la_SOURCES += logger_level.cc logger_level.h
+liblog_la_SOURCES += logger_level_impl.cc logger_level_impl.h
+liblog_la_SOURCES += logger_manager.cc logger_manager.h
+liblog_la_SOURCES += logger_manager_impl.cc logger_manager_impl.h
+liblog_la_SOURCES += logger_name.cc logger_name.h
+liblog_la_SOURCES += logger_specification.h
liblog_la_SOURCES += logger_support.cc logger_support.h
-liblog_la_SOURCES += messagedef.cc messagedef.h
+liblog_la_SOURCES += logger_unittest_support.cc logger_unittest_support.h
+liblog_la_SOURCES += macros.h
+liblog_la_SOURCES += log_messages.cc log_messages.h
liblog_la_SOURCES += message_dictionary.cc message_dictionary.h
-liblog_la_SOURCES += message_exception.h message_exception.cc
+liblog_la_SOURCES += message_exception.h
liblog_la_SOURCES += message_initializer.cc message_initializer.h
liblog_la_SOURCES += message_reader.cc message_reader.h
liblog_la_SOURCES += message_types.h
-liblog_la_SOURCES += root_logger_name.cc root_logger_name.h
+liblog_la_SOURCES += output_option.cc output_option.h
EXTRA_DIST = README
-EXTRA_DIST += messagedef.mes
-EXTRA_DIST += logger_impl_log4cxx.cc logger_impl_log4cxx.h
-EXTRA_DIST += xdebuglevel.cc xdebuglevel.h
+EXTRA_DIST += logimpl_messages.mes
+EXTRA_DIST += log_messages.mes
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
@@ -37,5 +44,6 @@ if USE_CLANGPP
# Same for clang++, but we need to turn off -Werror completely.
liblog_la_CXXFLAGS += -Wno-error
endif
-liblog_la_CPPFLAGS = $(AM_CPPFLAGS)
-liblog_la_LIBADD = $(top_builddir)/src/lib/util/libutil.la
+liblog_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+liblog_la_LDFLAGS = $(LOG4CPLUS_LDFLAGS)
+liblog_la_LIBADD = $(top_builddir)/src/lib/util/libutil.la
diff --git a/src/lib/log/README b/src/lib/log/README
index ed11b5b..3747cb1 100644
--- a/src/lib/log/README
+++ b/src/lib/log/README
@@ -1,11 +1,12 @@
This directory holds the first release of the logging system.
+
Basic Ideas
===========
The BIND-10 logging system merges two ideas:
* A hierarchical logging system similar to that used in Java (i.e. log4j)
-* Separation of message definitions and text
+* Separation of message use from message text
Hierarchical Logging System
@@ -28,23 +29,26 @@ above, the INFO/Syslog attributes could be associated with the root logger
while the DEBUG/file attributes are associated with the "cache" logger.
-Separation of Messages Definitions And Text
-===========================================
-The reason for this is to allow the message text to be overridden by versions
-in a local language. To do this, each message is identified by an identifier
-e.g. "OPENIN". Within the program, this is the symbol passed to the logging
-system. The logger system uses the symbol as an index into a dictionary to
-retrieve the message associated with it (e.g. "unable to open %s for input").
-substitutes any message parameters (in this example, the string that is an
-invalid filename) and logs it to the destination.
+Separation of Messages Use from Message Text
+============================================
+By separating the use of the message from the text associated with this -
+in essence, defining message text in an external file - it is possible to
+replace the supplied text of the messages with a local language version.
-In the BIND-10 system, a set of default messages are linked into the
-program. At run-time. each program reads a message file, updating the
-stored definitions; this updated text is logged. However, to aid support,
-the message identifier so in the example above, the message finally logged
-would be something like:
+Each message is identified by an identifier e.g. "LOG_WRITE_ERROR".
+Within the program, this is the symbol passed to the logging system.
+The logger system uses the symbol as an index into a dictionary to
+retrieve the message associated with it (e.g. "unable to open %s for
+input"). It then substitutes any message parameters (in this example,
+the name of the file where the write operation failed) and logs it to
+the destination.
- OPENIN, unable to open a.txt for input
+In BIND-10, a the default text for each message is linked into the
+program. Each program is able to read a locally-defined message file
+when it starts, updating the stored definitions with site-specific text.
+When the message is logged, the updated text is output. However, the
+message identifier is always included in the output so that the origin
+of the message can be identified even if the text has been changed.
Using The System
@@ -52,20 +56,19 @@ Using The System
The steps in using the system are:
1. Create a message file. This defines messages by an identification - a
- mnemonic for the message, typically 6-12 characters long - and a message.
- The file is described in more detail below.
-
- Ideally the file should have a file type of ".msg".
+ mnemonic for the message, the convention being that these are a few
+ words separated by underscores - and text that explains the message in
+ more detail. The file is described in more detail below.
-2. Run it through the message compiler to produce the .h and .cc files. It
- is intended that this step be included in the build process. However,
- for now run the compiler (found in the "compiler" subdirectory) manually.
- The only argument is the name of the message file: it will produce as
- output two files, having the same name as the input file but with file
- types of ".h" and ".cc".
+ Ideally the file should have a file type of ".mes".
- The compiler is built in the "compiler" subdirectory of the "src/lib/log"
- directory.
+2. Run it through the message compiler to produce the .h and .cc files. This
+ step should be included in the build process. (For an example of how to
+ do this, see src/lib/nsas/Makefile.am.) During development though, the
+ message compiler (found in the "src/lib/log/compiler" directory) will need
+ to be run manually. The only argument is the name of the message file: it
+ will produce as output two files in the default directory, having the same
+ name as the input file but with file types of ".h" and ".cc".
3. Include the .h file in your source code to define message symbols, and
make sure that the .cc file is compiled and linked into your program -
@@ -75,9 +78,7 @@ The steps in using the system are:
described in more detail below.
5. To set the debug level and run-time message file, call initLogger (declared
- in logger_support.h) in the main program unit. This is a temporary solution
- for Year 2, and will be replaced at a later date, the information coming
- from the configuration database.
+ in logger_support.h) in the main program unit.
Message Files
@@ -92,15 +93,16 @@ An example file could be:
-- BEGIN --
# Example message file
-# $ID:$
-$PREFIX TEST_
$NAMESPACE isc::log
-TEST1 message %s is much too large
-+ This message is a test for the general message code
-UNKNOWN unknown message
-+ Issued when the message is unknown.
+% LOG_UNRECOGNISED_DIRECTIVE line %1: unrecognised directive '%2'
+A line starting with a dollar symbol was found, but the first word on the line
+(shown in the message) was not a recognised message compiler directive.
+
+% LOG_WRITE_ERROR error writing to %1: %2
+The specified error was encountered by the message compiler when writing to
+the named output file.
-- END --
@@ -115,60 +117,82 @@ Points to note:
a line by themselves - inline comments will be interpreted as part of the
text of the line.
-* Lines starting $ are directives. At present, two directives are recognised:
+* Lines starting $ are directives. At present, just one directive is
+ recognised:
- * $PREFIX, which has one argument: the string used to prefix symbols. If
- absent, there is no prefix to the symbols. (Prefixes are explained below.)
* $NAMESPACE, which has one argument: the namespace in which the symbols are
- created. In the absence of a $NAMESPACE directive, symbols will be put
- in the global namespace.
-
-* Lines starting + indicate an explanation for the preceding message. These
+ created. In the absence of a $NAMESPACE directive, symbols will be put in
+ the anonymous namespace.
+
+* Message lines. These start with a "%" and are followed by the message
+ identification and the message text, the latter including zero or more
+ replacement tokens, e.g.
+
+ % LOG_WRITE_ERROR error writing to %1: %2
+
+ * There may be zero or more spaces between the leading "%" and the message
+ identification (which, in the example above, is the string
+ "LOG_WRITE_ERROR").
+
+ * The message identification can be any string of letters, digits and
+ underscores, but should not start with a digit. The convention adopted
+ in BIND 10 is for the first component (before the first underscore) to be
+ a string indicating the origin of the message, and the remainder to
+ describe the message. So in the example above, the LOG_ indicates that
+ the error originated from the logging library and the "WRITE_ERROR"
+ indicates that there was a problem in a write operation.
+
+ * The rest of the line - from the first non-space character to the
+ last non- space character - is taken exactly for the text
+ of the message. There are no restrictions on what characters may
+ be in this text, other than they be printable. (This means that
+ both single-quote (') and double-quote (") characters are allowed.)
+ The message text may include replacement tokens (the strings "%1",
+ "%2" etc.). When a message is logged, these are replaced with the
+ arguments passed to the logging call: %1 refers to the first argument,
+ %2 to the second etc. Within the message text, the placeholders
+ can appear in any order and placeholders can be repeated. Otherwise,
+ the message is printed unmodified.
+
+* Remaining lines indicate an explanation for the preceding message. These
are intended to be processed by a separate program and used to generate
- an error messages manual. However they are treated like comments by the
- message compiler. As with comments, these must be on a line by themselves;
- if inline, the text (including the leading "+") will be interpreted as
- part of the line.
-
-* Message lines. These comprise a symbol name and a message, which may
- include zero or more printf-style tokens. Symbol names will be upper-cased
- by the compiler.
-
+ an error messages manual. They are ignored by the message compiler.
Message Compiler
----------------
The message compiler is a program built in the src/log/compiler directory.
It is invoked by the command:
- message [-h] [-v] <message-file>
+ message [-h] [-v] -p] <message-file>
+
+("-v" prints the version number and exits; "-h" prints brief help text.) The
+compiler produces source files for C++ and Python.
-("-v" prints the version number and exits; "-h" prints brief help text.)
-The message compiler processes the message file to produce two files:
+C++ Files
+---------
+Without the "-p" option, the message compiler processes the message file
+to produce two files:
1) A C++ header file (called <message-file-name>.h) that holds lines of
the form:
namespace <namespace> {
- extern const isc::log::MessageID PREFIX_IDENTIFIER;
+ extern const isc::log::MessageID LOG_WRITE_ERROR;
:
}
-The symbols define the keys in the global message dictionary.
+The symbols define the keys in the global message dictionary, with the
+namespace enclosing the symbols set by the $NAMESPACE directive.
-The namespace enclosing the symbols is set by the $NAMESPACE directive.
-
-The "PREFIX_" part of the symbol name is the string defined in the $PREFIX
-the argument to the directive. So "$PREFIX MSG_" would prefix the identifier
-ABC with "MSG_" to give the symbol MSG_ABC. Similarly "$PREFIX E" would
-prefix it with "E" to give the symbol EABC. If no $PREFIX is given, no
-prefix appears (so the symbol in this example would be ABC).
+(This is the reason for the restriction on message identifiers - they
+have to be valid C++ symbol names.)
2) A C++ source file (called <message-file-name>.cc) that holds the definitions
of the global symbols and code to insert the symbols and messages into the map.
Symbols are defined to be equal to strings holding the identifier, e.g.
- extern const isc::log::MessageID MSG_DUPLNS = "DUPLNS";
+ extern const isc::log::MessageID LOG_WRITE_ERROR = "LOG_WRITE_ERROR";
(The implementation allows symbols to be compared. However, use of strings
should not be assumed - a future implementation may change this.)
@@ -194,123 +218,252 @@ A check is made as each is added; if the identifier already exists, it is
added to "overflow" vector; the vector is printed to the main logging output
when logging is finally enabled (to indicate a programming error).
+Python Files
+------------
+If the "-p" option is given, the compiler produces a Python module defining
+the messages. The format of this is:
+
+import isc.log
+ :
+LOG_WRITE_ERROR = isc.log.create_message("LOG_WRITE_ERROR",
+ "error writing to %1 : %2")
-Using the Logging
-=================
-To use the current version of the logging:
+(The definition is output on one line - it is split across two lines in this
+document for readability.)
+The module can be imported into other Python code, and messages logged
+in a similar way to C++ using the Python logging library.
+
+Using the Logging - C++
+=======================
1. Build message header file and source file as describe above.
-2. In the main module of the program, declare an instance of the
- RootLoggerName class to define the name of the program's root logger, e.g.
+2. The main program unit must include a call to isc::log::initLogger()
+ (described in more detail below) to set the logging severity, debug log
+ level, and external message file:
+
+ a) The logging severity is one of the enum defined in logger.h, i.e.
+
+ isc::log::DEBUG
+ isc::log::INFO
+ isc::log::WARN
+ isc::log::ERROR
+ isc::log::FATAL
+ isc::log::NONE
+
+ b) The debug log level is only interpreted when the severity is
+ DEBUG and is an integer ranging from 0 to 99. 0 should be used
+ for the highest-level debug messages and 99 for the lowest-level
+ (and typically more verbose) messages.
- #include <log/root_logger_name.h>
+ c) The external message file. If present, this is the same as a
+ standard message file, although it should not include any
+ directives. (A single directive of a particular type will be
+ ignored; multiple directives will cause the read of the file to
+ fail with an error.)
- isc::log::RootLoggerName("b10-auth");
+ The settings remain in effect until the logging configuration is read,
+ and so provide the default logging during program initialization.
- This can be declared inside or outside an execution unit.
+3. Declare a logger through which the message will be logged.
-2. In the code that needs to do logging, declare a logger with a given name,
- e.g.
+ isc::log::Logger logger("name");
- #include <log/logger.h>
- :
- isc::log::Logger logger("myname"); // "myname" can be anything
+ The string passed to the constructor is the name of the logger (it
+ can be any string) and is used when configuring it. Loggers with
+ the same name share the same configuration.
- The above example assumes declaration outside a function. If declaring
- non-statically within a function, declare it as:
+4. Issue logging calls using supplied macros in "log/macros.h", e.g.
- isc::log::Logger logger("myname", true);
+ LOG_ERROR(logger, LOG_WRITE_ERROR).arg("output.txt");
- (The argument is required to support a possible future implementation of
- logging. Currently it has no effect.)
+ (The macros are more efficient that calls to the methods on the logger
+ class: they avoid the overhead of evaluating the parameters to arg()
+ if the settings are such that the message is not going to be output.)
-3. The main program unit should include a call to isc::log::initLogger()
- (defined in logger_support.h) to set the logging severity, debug log level,
- and external message file.
+Using the Logging - Python
+==========================
+1. Build message module as describe above.
- a) The logging severity is one of the enum defined in logger.h, i.e.
+2. The main program unit must include a call to isc.log.init()
+ (described in more detail below) to set the to set the logging
+ severity, debug log level, and external message file:
- isc::log::DEBUG
- isc::log::INFO
- isc::log::WARN
- isc::log::ERROR
- isc::log::FATAL
- isc::log::NONE
+ a) The logging severity is one of the strings:
+
+ DEBUG
+ INFO
+ WARN
+ ERROR
+ FATAL
+ NONE
- b) The debug log level is only interpreted when the severity is DEBUG and
- is an integer ranging from 0 to 99. 0 should be used for the
- highest-level debug messages and 99 for the lowest-level (and typically
- more verbose) messages.
+ b) The debug log level is only interpreted when the severity is
+ DEBUG and is an integer ranging from 0 to 99. 0 should be used
+ for the highest-level debug messages and 99 for the lowest-level
+ (and typically more verbose) messages.
- c) Name of an external message file. This is the same as a standard message
- file, although it should not include any directives. (A single directive
- of a particular type will be ignored; multiple directives will cause the
- read of the file to fail with an error.) If a message is replaced, the
- message should include the same printf-format directives in the same order
- as the original message.
+ c) The external message file. If present, this is the same as a
+ standard message file, although it should not include any
+ directives. (Any that are there will be ignored.)
-4. Issue logging calls using methods on logger, e.g.
+ The settings remain in effect until the logging configuration is read,
+ and so provide the default logging during program initialization.
- logger.error(DPS_NSTIMEOUT, "isc.org");
+3. Declare a logger through which the message will be logged.
- (where, in the example above we might have defined the symbol in the message
- file with something along the lines of:
+ isc.log.Logger logger("name")
- $PREFIX DPS_
- :
- NSTIMEOUT queries to all nameservers for %s have timed out
+ The string passed to the constructor is the name of the logger (it
+ can be any string) and is used when configuring it. Loggers with
+ the same name share the same configuration.
- At present, the only logging is to the console.
+4. Issue calls to the logging methods:
+
+ logger.error(LOG_WRITE_ERROR, "output.txt");
+
+Logging Initialization
+======================
+In all cases, if an attempt is made to use a logging method before the logging
+has been initialized, the program will terminate with a LoggingNotInitialized
+exception.
+
+C++
+---
+Logging Initialization is carried out by calling initLogger(). There are two
+variants to the call, one for use by production programs and one for use by
+unit tests.
+
+Variant #1, Used by Production Programs
+---------------------------------------
+void isc::log::initLogger(const std::string& root,
+ isc::log::Severity severity = isc::log::INFO,
+ int dbglevel = 0, const char* file = NULL);
+
+This is the call that should be used by production programs:
+
+root
+Name of the program (e.g. "b10-auth"). This is also the name of the root
+logger and is used when configuring logging.
+
+severity
+Default severity that the program will start logging with. Although this may
+be overridden when the program obtains its configuration from the configuration
+database, this is the severity that it used until then. (This may be set by
+a command-line parameter.)
+
+dbglevel
+The debug level used if "severity" is set to isc::log::DEBUG.
+
+file
+The name of a local message file. This will be read and its definitions used
+to replace the compiled-in text of the messages.
+
+
+Variant #2, Used by Unit Tests
+------------------------------
+ void isc::log::initLogger()
+
+This is the call that should be used by unit tests. In this variant, all the
+options are supplied by environment variables. (It should not be used for
+production programs to avoid the chance that the program operation is affected
+by inadvertently-defined environment variables.)
+
+The environment variables are:
+
+B10_LOGGER_ROOT
+Sets the "root" for the unit test. If not defined, the name "bind10" is used.
+
+B10_LOGGER_SEVERITY
+The severity to set for the root logger in the unit test. Valid values are
+"DEBUG", "INFO", "WARN", "ERROR", "FATAL" and "NONE". If not defined, "INFO"
+is used.
+
+B10_LOGGER_DBGLEVEL
+If B10_LOGGER_SEVERITY is set to "DEBUG", the debug level. This can be a
+number between 0 and 99, and defaults to 0.
+
+B10_LOGGER_LOCALMSG
+If defined, points to a local message file. The default is not to use a local
+message file.
+
+B10_LOGGER_DESTINATION
+The location to which log message are written. This can be one of:
+
+ stdout Message are written to stdout
+ stderr Messages are written to stderr
+ syslog[:facility] Messages are written to syslog. If the optional
+ "facility" is used, the messages are written using
+ that facility. (This defaults to "local0" if not
+ specified.)
+ Anything else Interpreted as the name of a file to which output
+ is appended. If the file does not exist, a new one
+ is opened.
+
+In the case of "stdout", "stderr" and "syslog", they must be written exactly
+as is - no leading or trailing spaces, and in lower-case.
+
+Python
+------
+To be supplied
Severity Guidelines
===================
-When using logging, the question arises, what severity should a message be
-logged at? The following is a suggestion - as always, the decision must be
-made in the context of which the message is logged.
+When using logging, the question arises, what severity should a message
+be logged at? The following is a suggestion - as always, the decision
+must be made in the context of which the message is logged.
+
+One thing that should always be borne in mind is whether the logging
+could be used as a vector for a DOS attack. For example, if a warning
+message is logged every time an invalid packet is received, an attacker
+could simply send large numbers of invalid packets. (Of course, warnings
+could be disabled (or just warnings for that that particular logger),
+but nevertheless the message is an attack vector.)
FATAL
-----
The program has encountered an error that is so severe that it cannot
-continue (or there is no point in continuing). When a fatal error has been
-logged, the program will usually exit immediately (via a call to abort()) or
-shortly afterwards, after dumping some diagnostic information.
+continue (or there is no point in continuing). When a fatal error
+has been logged, the program will usually exit immediately (or shortly
+afterwards) after dumping some diagnostic information.
ERROR
-----
-Something has happened such that the program can continue but the results
-for the current (or future) operations cannot be guaranteed to be correct,
-or the results will be correct but the service is impaired. For example,
-the program started but attempts to open one or more network interfaces failed.
+Something has happened such that the program can continue but the
+results for the current (or future) operations cannot be guaranteed to
+be correct, or the results will be correct but the service is impaired.
+For example, the program started but attempts to open one or more network
+interfaces failed.
WARN
----
An unusual event happened. Although the program will continue working
-normally, the event was sufficiently out of the ordinary to warrant drawing
-attention to it. For example, at program start-up a zone was loaded that
-contained no resource records,
+normally, the event was sufficiently out of the ordinary to warrant
+drawing attention to it. For example, at program start-up a zone was
+loaded that contained no resource records,
INFO
----
A normal but significant event has occurred that should be recorded,
-e.g. the program has started or is just about to terminate, a new zone has
-been created, etc.
+e.g. the program has started or is just about to terminate, a new zone
+has been created, etc.
DEBUG
-----
This severity is only enabled on for debugging purposes. A debug level is
associated with debug messages, level 0 (the default) being for high-level
-messages and level 99 (the maximum) for the lowest level. How the messages
-are distributed between the levels is up to the developer. So if debugging
-the NSAS (for example), a level 0 message might record the creation of a new
-zone, a level 10 recording a timeout when trying to get a nameserver address,
-but a level 50 would record every query for an address. (And we might add
-level 51 to record every update of the RTT.)
-
-Note that like severities, levels are cumulative; so if level 25 is set as the
-debug level, all debug levels from 0 to 25 will be output. In fact, it is
-probably easier to visualise the debug levels as part of the severity system:
+messages and level 99 (the maximum) for the lowest level. How the
+messages are distributed between the levels is up to the developer.
+So if debugging the NSAS (for example), a level 0 message might record
+the creation of a new zone, a level 10 recording a timeout when trying
+to get a nameserver address, but a level 50 would record every query for
+an address. (And we might add level 70 to record every update of the RTT.)
+
+Note that like severities, levels are cumulative; so if level 25 is
+set as the debug level, all debug levels from 0 to 25 will be output.
+In fact, it is probably easier to visualise the debug levels as part of
+the severity system:
FATAL High
ERROR
@@ -326,51 +479,34 @@ levels above it - will be logged.
Logging Sources v Logging Severities
------------------------------------
-When logging events, make a distinction between events related to the server
-and events related to DNS messages received. Caution needs to be exercised
-with the latter as, if the logging is enabled in the normal course of events,
-such logging could be a denial of service vector. For example, suppose that
-the main authoritative service logger were to log both zone loading and
-unloading as INFO and a warning message if it received an invalid packet. An
-attacker could make the INFO messages unusable by flooding the server with
-malformed packets.
+When logging events, make a distinction between events related to the
+server and events related to DNS messages received. Caution needs to
+be exercised with the latter as, if the logging is enabled in the normal
+course of events, such logging could be a denial of service vector. For
+example, suppose that the main authoritative service logger were to
+log both zone loading and unloading as INFO and a warning message if
+it received an invalid packet. An attacker could make the INFO messages
+unusable by flooding the server with malformed packets.
There are two approaches to get round this:
a) Make the logging of packet-dependent events a DEBUG-severity message.
-DEBUG is not enabled by default, so these events will not be recorded unless
-DEBUG is specifically chosen.
+DEBUG is not enabled by default, so these events will not be recorded
+unless DEBUG is specifically chosen.
b) Record system-related and packet-related messages via different loggers
-(e.g. in the example given, server events could be logged using the logger
-"auth" and packet-related events at that level logged using the logger
-"pkt-auth".) As the loggers are independent and the severity levels
-independent, fine-tuning of what and what is not recorded can be achieved.
+(e.g. in the example given, server events could be logged using the
+logger "auth" and packet-related events at that level logged using the
+logger "pkt-auth".) As the loggers are independent and the severity
+levels independent, fine-tuning of what and what is not recorded can
+be achieved.
Notes
=====
The message compiler is written in C++ (instead of Python) because it
contains a component that reads the message file. This component is used
-in both the message compiler and the server; in the server it is used when
-the server starts up (or when triggered by a command) to read in a message
-file to overwrite the internal dictionary. Writing it in C++ means there
-is only one piece of code that does this functionality.
-
-
-Outstanding Issues
-==================
-* Ability to configure system according to configuration database.
-* Update the build procedure to create .cc and .h files from the .msg file
- during the build process. (Requires that the message compiler is built
- first.)
-
-
-log4cxx Issues
-==============
-Some experimental code to utilise log4cxx as an underlying implementation
-is present in the source code directory although it is not currently used.
-The files are:
-
- logger_impl_log4cxx.{cc,h}
- xdebuglevel.{cc,h}
+in both the message compiler and the server; in the server it is used
+when the server starts up (or when triggered by a command) to read in
+a message file to overwrite the internal dictionary. Writing it in C++
+means there is only one piece of code that does this functionality.
diff --git a/src/lib/log/debug_levels.h b/src/lib/log/debug_levels.h
deleted file mode 100644
index bb2b524..0000000
--- a/src/lib/log/debug_levels.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __DEBUG_LEVELS_H
-#define __DEBUG_LEVELS_H
-
-/// \brief Defines Debug Levels
-///
-/// Defines the maximum and minimum debug levels and the number of levels.
-/// These are defined using #define as they are referenced in the construction
-/// of variables declared outside execution units. (In this way we avoid the
-/// "static initialization fiasco" problem.)
-
-#define MIN_DEBUG_LEVEL (0)
-#define MAX_DEBUG_LEVEL (99)
-#define NUM_DEBUG_LEVEL (MAX_DEBUG_LEVEL - MIN_DEBUG_LEVEL + 1)
-
-#endif // __DEBUG_LEVELS_H
diff --git a/src/lib/log/log_formatter.cc b/src/lib/log/log_formatter.cc
new file mode 100644
index 0000000..18c4741
--- /dev/null
+++ b/src/lib/log/log_formatter.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <log/log_formatter.h>
+
+using namespace std;
+using namespace boost;
+
+namespace isc {
+namespace log {
+
+void
+replacePlaceholder(string* message, const string& arg,
+ const unsigned placeholder)
+{
+ string mark("%" + lexical_cast<string>(placeholder));
+ size_t pos(message->find(mark));
+ if (pos != string::npos) {
+ do {
+ message->replace(pos, mark.size(), arg);
+ pos = message->find(mark, pos + arg.size());
+ } while (pos != string::npos);
+ } else {
+ // We're missing the placeholder, so add some complain
+ message->append(" @@Missing placeholder " + mark + " for '" + arg +
+ "'@@");
+ }
+}
+
+}
+}
diff --git a/src/lib/log/log_formatter.h b/src/lib/log/log_formatter.h
new file mode 100644
index 0000000..ca23844
--- /dev/null
+++ b/src/lib/log/log_formatter.h
@@ -0,0 +1,219 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOG_FORMATTER_H
+#define __LOG_FORMMATER_H
+
+#include <cstddef>
+#include <string>
+#include <iostream>
+
+#include <exceptions/exceptions.h>
+#include <boost/lexical_cast.hpp>
+#include <log/logger_level.h>
+
+namespace isc {
+namespace log {
+
+/// \brief Format Failure
+///
+/// This exception is used to wrap a bad_lexical_cast exception thrown during
+/// formatting an argument.
+
+class FormatFailure : public isc::Exception {
+public:
+ FormatFailure(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what)
+ {}
+};
+
+
+///
+/// \brief The internal replacement routine
+///
+/// This is used internally by the Formatter. Replaces a placeholder
+/// in the message by replacement. If the placeholder is not found,
+/// it adds a complain at the end.
+void
+replacePlaceholder(std::string* message, const std::string& replacement,
+ const unsigned placeholder);
+
+///
+/// \brief The log message formatter
+///
+/// This class allows us to format logging messages conveniently. We
+/// call something like logger.warn(WARN_MSG).arg(15).arg(dnsMsg). This
+/// outputs some text with placeholders replaced by the arguments, if
+/// the logging verbosity is at WARN level or more.
+///
+/// To make this work, we use the Formatter. The warn (or whatever logging
+/// function) returns a Formatter object. That one holds the string to be
+/// output with the placeholders. It also remembers if there should be any
+/// output at all (eg. if the logging is enabled for this level). When there's
+/// no .arg call on the object, it is destroyed right away and we use the
+/// destructor to output the text (but only in case we should output anything).
+///
+/// If there's an .arg call, we return reference to the same object, so another
+/// .arg can be called on it. After the last .arg call is done, the object is
+/// destroyed and, again, we can produce the output.
+///
+/// Of course, if the logging is turned off, we don't bother with any replacing
+/// and just return.
+///
+/// User of logging code should not really care much about this class, only
+/// call the .arg method to generate the correct output.
+///
+/// The class is a template to allow easy testing. Also, we want everything
+/// here in the header anyway and it doesn't depend on the details of what
+/// Logger really is, so it doesn't hurt anything.
+///
+/// Also, if you are interested in the internals, you might find the copy
+/// constructor a bit strange. It deactivates the original formatter. We don't
+/// really want to support copying of the Formatter by user, but C++ needs a
+/// copy constructor when returning from the logging functions, so we need one.
+/// And if we did not deactivate the original Formatter, that one would get
+/// destroyed before any call to .arg, producing an output, and then the one
+/// the .arg calls are called on would get destroyed as well, producing output
+/// again. So, think of this behaviour as soul moving from one to another.
+template<class Logger> class Formatter {
+private:
+ /// \brief The logger we will use to output the final message.
+ ///
+ /// If NULL, we are not active and should not produce anything.
+ mutable Logger* logger_;
+
+ /// \brief Message severity
+ Severity severity_;
+
+ /// \brief The messages with %1, %2... placeholders
+ std::string* message_;
+
+ /// \brief Which will be the next placeholder to replace
+ unsigned nextPlaceholder_;
+
+
+public:
+ /// \brief Constructor of "active" formatter
+ ///
+ /// This will create a formatter. If the arguments are set, it
+ /// will be active (will produce output). If you leave them all as NULL,
+ /// it will create an inactive Formatter -- one that'll produce no output.
+ ///
+ /// It is not expected to be called by user of logging system directly.
+ ///
+ /// \param severity The severity of the message (DEBUG, ERROR etc.)
+ /// \param message The message with placeholders. We take ownership of
+ /// it and we will modify the string. Must not be NULL unless
+ /// logger is also NULL, but it's not checked.
+ /// \param logger The logger where the final output will go, or NULL
+ /// if no output is wanted.
+ Formatter(const Severity& severity = NONE, std::string* message = NULL,
+ Logger* logger = NULL) :
+ logger_(logger), severity_(severity), message_(message),
+ nextPlaceholder_(0)
+ {
+ }
+
+ /// \brief Copy constructor
+ ///
+ /// "Control" is passed to the created object in that it is the created object
+ /// that will have responsibility for outputting the formatted message - the
+ /// object being copied relinquishes that responsibility.
+ Formatter(const Formatter& other) :
+ logger_(other.logger_), severity_(other.severity_),
+ message_(other.message_), nextPlaceholder_(other.nextPlaceholder_)
+ {
+ other.logger_ = NULL;
+ }
+
+ /// \brief Destructor.
+ //
+ /// This is the place where output happens if the formatter is active.
+ ~ Formatter() {
+ if (logger_) {
+ logger_->output(severity_, *message_);
+ delete message_;
+ }
+ }
+
+ /// \brief Assignment operator
+ ///
+ /// Essentially the same function as the assignment operator - the object being
+ /// assigned to takes responsibility for outputting the message.
+ Formatter& operator =(const Formatter& other) {
+ if (&other != this) {
+ logger_ = other.logger_;
+ severity_ = other.severity_;
+ message_ = other.message_;
+ nextPlaceholder_ = other.nextPlaceholder_;
+ other.logger_ = NULL;
+ }
+
+ return *this;
+ }
+
+ /// \brief Replaces another placeholder
+ ///
+ /// Replaces another placeholder and returns a new formatter with it.
+ /// Deactivates the current formatter. In case the formatter is not active,
+ /// only produces another inactive formatter.
+ ///
+ /// \param arg The argument to place into the placeholder.
+ template<class Arg> Formatter& arg(const Arg& value) {
+ if (logger_) {
+ try {
+ return (arg(boost::lexical_cast<std::string>(value)));
+ } catch (const boost::bad_lexical_cast& ex) {
+
+ // A bad_lexical_cast during a conversion to a string is
+ // *extremely* unlikely to fail. However, there is nothing
+ // in the documentation that rules it out, so we need to handle
+ // it. As it is a potentially very serious problem, throw the
+ // exception detailing the problem with as much information as
+ // we can. (Note that this does not include 'value' -
+ // boost::lexical_cast failed to convert it to a string, so an
+ // attempt to do so here would probably fail as well.)
+ isc_throw(FormatFailure, "bad_lexical_cast in call to "
+ "Formatter::arg(): " << ex.what());
+ }
+ } else {
+ return (*this);
+ }
+ }
+
+ /// \brief String version of arg.
+ ///
+ /// \param arg The text to place into the placeholder.
+ Formatter& arg(const std::string& arg) {
+ if (logger_) {
+ // Note that this method does a replacement and returns the
+ // modified string. If there are multiple invocations of arg() (e.g.
+ // logger.info(msgid).arg(xxx).arg(yyy)...), each invocation
+ // operates on the string returned by the previous one. This
+ // sequential operation means that if we had a message like "%1 %2",
+ // and called .arg("%2").arg(42), we would get "42 42"; the first
+ // call replaces the %1" with "%2" and the second replaces all
+ // occurrences of "%2" with 42. (Conversely, the sequence
+ // .arg(42).arg("%1") would return "42 %1" - there are no recursive
+ // replacements).
+ replacePlaceholder(message_, arg, ++nextPlaceholder_ );
+ }
+ return (*this);
+ }
+};
+
+}
+}
+
+#endif
diff --git a/src/lib/log/log_messages.cc b/src/lib/log/log_messages.cc
new file mode 100644
index 0000000..f60898c
--- /dev/null
+++ b/src/lib/log/log_messages.cc
@@ -0,0 +1,63 @@
+// File created from log_messages.mes on Thu Jul 7 15:32:06 2011
+
+#include <cstddef>
+#include <log/message_types.h>
+#include <log/message_initializer.h>
+
+namespace isc {
+namespace log {
+
+extern const isc::log::MessageID LOG_BAD_DESTINATION = "LOG_BAD_DESTINATION";
+extern const isc::log::MessageID LOG_BAD_SEVERITY = "LOG_BAD_SEVERITY";
+extern const isc::log::MessageID LOG_BAD_STREAM = "LOG_BAD_STREAM";
+extern const isc::log::MessageID LOG_DUPLICATE_MESSAGE_ID = "LOG_DUPLICATE_MESSAGE_ID";
+extern const isc::log::MessageID LOG_DUPLICATE_NAMESPACE = "LOG_DUPLICATE_NAMESPACE";
+extern const isc::log::MessageID LOG_INPUT_OPEN_FAIL = "LOG_INPUT_OPEN_FAIL";
+extern const isc::log::MessageID LOG_INVALID_MESSAGE_ID = "LOG_INVALID_MESSAGE_ID";
+extern const isc::log::MessageID LOG_NAMESPACE_EXTRA_ARGS = "LOG_NAMESPACE_EXTRA_ARGS";
+extern const isc::log::MessageID LOG_NAMESPACE_INVALID_ARG = "LOG_NAMESPACE_INVALID_ARG";
+extern const isc::log::MessageID LOG_NAMESPACE_NO_ARGS = "LOG_NAMESPACE_NO_ARGS";
+extern const isc::log::MessageID LOG_NO_MESSAGE_ID = "LOG_NO_MESSAGE_ID";
+extern const isc::log::MessageID LOG_NO_MESSAGE_TEXT = "LOG_NO_MESSAGE_TEXT";
+extern const isc::log::MessageID LOG_NO_SUCH_MESSAGE = "LOG_NO_SUCH_MESSAGE";
+extern const isc::log::MessageID LOG_OPEN_OUTPUT_FAIL = "LOG_OPEN_OUTPUT_FAIL";
+extern const isc::log::MessageID LOG_PREFIX_EXTRA_ARGS = "LOG_PREFIX_EXTRA_ARGS";
+extern const isc::log::MessageID LOG_PREFIX_INVALID_ARG = "LOG_PREFIX_INVALID_ARG";
+extern const isc::log::MessageID LOG_READING_LOCAL_FILE = "LOG_READING_LOCAL_FILE";
+extern const isc::log::MessageID LOG_READ_ERROR = "LOG_READ_ERROR";
+extern const isc::log::MessageID LOG_UNRECOGNISED_DIRECTIVE = "LOG_UNRECOGNISED_DIRECTIVE";
+extern const isc::log::MessageID LOG_WRITE_ERROR = "LOG_WRITE_ERROR";
+
+} // namespace log
+} // namespace isc
+
+namespace {
+
+const char* values[] = {
+ "LOG_BAD_DESTINATION", "unrecognized log destination: %1",
+ "LOG_BAD_SEVERITY", "unrecognized log severity: %1",
+ "LOG_BAD_STREAM", "bad log console output stream: %1",
+ "LOG_DUPLICATE_MESSAGE_ID", "duplicate message ID (%1) in compiled code",
+ "LOG_DUPLICATE_NAMESPACE", "line %1: duplicate $NAMESPACE directive found",
+ "LOG_INPUT_OPEN_FAIL", "unable to open message file %1 for input: %2",
+ "LOG_INVALID_MESSAGE_ID", "line %1: invalid message identification '%2'",
+ "LOG_NAMESPACE_EXTRA_ARGS", "line %1: $NAMESPACE directive has too many arguments",
+ "LOG_NAMESPACE_INVALID_ARG", "line %1: $NAMESPACE directive has an invalid argument ('%2')",
+ "LOG_NAMESPACE_NO_ARGS", "line %1: no arguments were given to the $NAMESPACE directive",
+ "LOG_NO_MESSAGE_ID", "line %1: message definition line found without a message ID",
+ "LOG_NO_MESSAGE_TEXT", "line %1: line found containing a message ID ('%2') and no text",
+ "LOG_NO_SUCH_MESSAGE", "could not replace message text for '%1': no such message",
+ "LOG_OPEN_OUTPUT_FAIL", "unable to open %1 for output: %2",
+ "LOG_PREFIX_EXTRA_ARGS", "line %1: $PREFIX directive has too many arguments",
+ "LOG_PREFIX_INVALID_ARG", "line %1: $PREFIX directive has an invalid argument ('%2')",
+ "LOG_READING_LOCAL_FILE", "reading local message file %1",
+ "LOG_READ_ERROR", "error reading from message file %1: %2",
+ "LOG_UNRECOGNISED_DIRECTIVE", "line %1: unrecognised directive '%2'",
+ "LOG_WRITE_ERROR", "error writing to %1: %2",
+ NULL
+};
+
+const isc::log::MessageInitializer initializer(values);
+
+} // Anonymous namespace
+
diff --git a/src/lib/log/log_messages.h b/src/lib/log/log_messages.h
new file mode 100644
index 0000000..10e1501
--- /dev/null
+++ b/src/lib/log/log_messages.h
@@ -0,0 +1,35 @@
+// File created from log_messages.mes on Thu Jul 7 15:32:06 2011
+
+#ifndef __LOG_MESSAGES_H
+#define __LOG_MESSAGES_H
+
+#include <log/message_types.h>
+
+namespace isc {
+namespace log {
+
+extern const isc::log::MessageID LOG_BAD_DESTINATION;
+extern const isc::log::MessageID LOG_BAD_SEVERITY;
+extern const isc::log::MessageID LOG_BAD_STREAM;
+extern const isc::log::MessageID LOG_DUPLICATE_MESSAGE_ID;
+extern const isc::log::MessageID LOG_DUPLICATE_NAMESPACE;
+extern const isc::log::MessageID LOG_INPUT_OPEN_FAIL;
+extern const isc::log::MessageID LOG_INVALID_MESSAGE_ID;
+extern const isc::log::MessageID LOG_NAMESPACE_EXTRA_ARGS;
+extern const isc::log::MessageID LOG_NAMESPACE_INVALID_ARG;
+extern const isc::log::MessageID LOG_NAMESPACE_NO_ARGS;
+extern const isc::log::MessageID LOG_NO_MESSAGE_ID;
+extern const isc::log::MessageID LOG_NO_MESSAGE_TEXT;
+extern const isc::log::MessageID LOG_NO_SUCH_MESSAGE;
+extern const isc::log::MessageID LOG_OPEN_OUTPUT_FAIL;
+extern const isc::log::MessageID LOG_PREFIX_EXTRA_ARGS;
+extern const isc::log::MessageID LOG_PREFIX_INVALID_ARG;
+extern const isc::log::MessageID LOG_READING_LOCAL_FILE;
+extern const isc::log::MessageID LOG_READ_ERROR;
+extern const isc::log::MessageID LOG_UNRECOGNISED_DIRECTIVE;
+extern const isc::log::MessageID LOG_WRITE_ERROR;
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOG_MESSAGES_H
diff --git a/src/lib/log/log_messages.mes b/src/lib/log/log_messages.mes
new file mode 100644
index 0000000..f150f39
--- /dev/null
+++ b/src/lib/log/log_messages.mes
@@ -0,0 +1,146 @@
+# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# \brief Message Utility Message File
+#
+# This is the source of the set of messages generated by the message and
+# logging components. The associated .h and .cc files are created by hand from
+# this file though and are not built during the build process; this is to avoid
+# the chicken-and-egg situation where we need the files to build the message
+# compiler, yet we need the compiler to build the files.
+
+$NAMESPACE isc::log
+
+% LOG_BAD_DESTINATION unrecognized log destination: %1
+A logger destination value was given that was not recognized. The
+destination should be one of "console", "file", or "syslog".
+
+% LOG_BAD_SEVERITY unrecognized log severity: %1
+A logger severity value was given that was not recognized. The severity
+should be one of "DEBUG", "INFO", "WARN", "ERROR", "FATAL" or "NONE".
+
+% LOG_BAD_STREAM bad log console output stream: %1
+Logging has been configured so that output is written to the terminal
+(console) but the stream on which it is to be written is not recognised.
+Allowed values are "stdout" and "stderr".
+
+% LOG_DUPLICATE_MESSAGE_ID duplicate message ID (%1) in compiled code
+During start-up, BIND 10 detected that the given message identification
+had been defined multiple times in the BIND 10 code. This indicates a
+programming error; please submit a bug report.
+
+% LOG_DUPLICATE_NAMESPACE line %1: duplicate $NAMESPACE directive found
+When reading a message file, more than one $NAMESPACE directive was found.
+(This directive is used to set a C++ namespace when generating header
+files during software development.) Such a condition is regarded as an
+error and the read will be abandoned.
+
+% LOG_INPUT_OPEN_FAIL unable to open message file %1 for input: %2
+The program was not able to open the specified input message file for
+the reason given.
+
+% LOG_INVALID_MESSAGE_ID line %1: invalid message identification '%2'
+An invalid message identification (ID) has been found during the read of
+a message file. Message IDs should comprise only alphanumeric characters
+and the underscore, and should not start with a digit.
+
+% LOG_NAMESPACE_EXTRA_ARGS line %1: $NAMESPACE directive has too many arguments
+The $NAMESPACE directive in a message file takes a single argument, a
+namespace in which all the generated symbol names are placed. This error
+is generated when the compiler finds a $NAMESPACE directive with more
+than one argument.
+
+% LOG_NAMESPACE_INVALID_ARG line %1: $NAMESPACE directive has an invalid argument ('%2')
+The $NAMESPACE argument in a message file should be a valid C++ namespace.
+This message is output if the simple check on the syntax of the string
+carried out by the reader fails.
+
+% LOG_NAMESPACE_NO_ARGS line %1: no arguments were given to the $NAMESPACE directive
+The $NAMESPACE directive in a message file takes a single argument,
+a C++ namespace in which all the generated symbol names are placed.
+This error is generated when the compiler finds a $NAMESPACE directive
+with no arguments.
+
+% LOG_NO_MESSAGE_ID line %1: message definition line found without a message ID
+Within a message file, message are defined by lines starting with a "%".
+The rest of the line should comprise the message ID and text describing
+the message. This error indicates the message compiler found a line in
+the message file comprising just the "%" and nothing else.
+
+% LOG_NO_MESSAGE_TEXT line %1: line found containing a message ID ('%2') and no text
+Within a message file, message are defined by lines starting with a "%".
+The rest of the line should comprise the message ID and text describing
+the message. This error indicates the message compiler found a line
+in the message file comprising just the "%" and message identification,
+but no text.
+
+% LOG_NO_SUCH_MESSAGE could not replace message text for '%1': no such message
+During start-up a local message file was read. A line with the listed
+message identification was found in the file, but the identification is
+not one contained in the compiled-in message dictionary. This message
+may appear a number of times in the file, once for every such unknown
+message identification.
+
+There may be several reasons why this message may appear:
+
+- The message ID has been mis-spelled in the local message file.
+
+- The program outputting the message may not use that particular message
+(e.g. it originates in a module not used by the program.)
+
+- The local file was written for an earlier version of the BIND 10 software
+and the later version no longer generates that message.
+
+Whatever the reason, there is no impact on the operation of BIND 10.
+
+% LOG_OPEN_OUTPUT_FAIL unable to open %1 for output: %2
+Originating within the logging code, the program was not able to open
+the specified output file for the reason given.
+
+% LOG_PREFIX_EXTRA_ARGS line %1: $PREFIX directive has too many arguments
+Within a message file, the $PREFIX directive takes a single argument,
+a prefix to be added to the symbol names when a C++ file is created.
+This error is generated when the compiler finds a $PREFIX directive with
+more than one argument.
+
+Note: the $PREFIX directive is deprecated and will be removed in a future
+version of BIND 10.
+
+% LOG_PREFIX_INVALID_ARG line %1: $PREFIX directive has an invalid argument ('%2')
+Within a message file, the $PREFIX directive takes a single argument,
+a prefix to be added to the symbol names when a C++ file is created.
+As such, it must adhere to restrictions on C++ symbol names (e.g. may
+only contain alphanumeric characters or underscores, and may nor start
+with a digit). A $PREFIX directive was found with an argument (given
+in the message) that violates those restrictions.
+
+Note: the $PREFIX directive is deprecated and will be removed in a future
+version of BIND 10.
+
+% LOG_READING_LOCAL_FILE reading local message file %1
+This is an informational message output by BIND 10 when it starts to read
+a local message file. (A local message file may replace the text of
+one of more messages; the ID of the message will not be changed though.)
+
+% LOG_READ_ERROR error reading from message file %1: %2
+The specified error was encountered reading from the named message file.
+
+% LOG_UNRECOGNISED_DIRECTIVE line %1: unrecognised directive '%2'
+Within a message file, a line starting with a dollar symbol was found
+(indicating the presence of a directive) but the first word on the line
+(shown in the message) was not recognised.
+
+% LOG_WRITE_ERROR error writing to %1: %2
+The specified error was encountered by the message compiler when writing
+to the named output file.
diff --git a/src/lib/log/logger.cc b/src/lib/log/logger.cc
index 198efbd..5deebed 100644
--- a/src/lib/log/logger.cc
+++ b/src/lib/log/logger.cc
@@ -17,21 +17,30 @@
#include <log/logger.h>
#include <log/logger_impl.h>
+#include <log/logger_name.h>
+#include <log/logger_support.h>
#include <log/message_dictionary.h>
#include <log/message_types.h>
-#include <log/root_logger_name.h>
#include <util/strutil.h>
+#if defined(_WIN32) && defined(ERROR)
+#undef ERROR
+#endif
+
using namespace std;
namespace isc {
namespace log {
-// Initialize Logger implementation. Does not check whether the implementation
-// has already been initialized - that was done by the caller (getLoggerPtr()).
+// Initialize underlying logger, but only if logging has been initialized.
void Logger::initLoggerImpl() {
- loggerptr_ = new LoggerImpl(name_, infunc_);
+ if (isLoggingInitialized()) {
+ loggerptr_ = new LoggerImpl(name_);
+ } else {
+ isc_throw(LoggingNotInitialized, "attempt to access logging function "
+ "before logging has been initialized");
+ }
}
// Destructor.
@@ -75,6 +84,14 @@ Logger::getDebugLevel() {
return (getLoggerPtr()->getDebugLevel());
}
+// Effective debug level (only relevant if messages of severity DEBUG are being
+// logged).
+
+int
+Logger::getEffectiveDebugLevel() {
+ return (getLoggerPtr()->getEffectiveDebugLevel());
+}
+
// Check on the current severity settings
bool
@@ -112,64 +129,65 @@ Logger::isFatalEnabled() {
// Output methods
void
-Logger::debug(int dbglevel, const isc::log::MessageID ident, ...) {
+Logger::output(const Severity& severity, const std::string& message) {
+ getLoggerPtr()->outputRaw(severity, message);
+}
+
+Logger::Formatter
+Logger::debug(int dbglevel, const isc::log::MessageID& ident) {
if (isDebugEnabled(dbglevel)) {
- va_list ap;
- va_start(ap, ident);
- getLoggerPtr()->debug(ident, ap);
- va_end(ap);
+ return (Formatter(DEBUG, getLoggerPtr()->lookupMessage(ident),
+ this));
+ } else {
+ return (Formatter());
}
}
-void
-Logger::info(const isc::log::MessageID ident, ...) {
+Logger::Formatter
+Logger::info(const isc::log::MessageID& ident) {
if (isInfoEnabled()) {
- va_list ap;
- va_start(ap, ident);
- getLoggerPtr()->info(ident, ap);
- va_end(ap);
+ return (Formatter(INFO, getLoggerPtr()->lookupMessage(ident),
+ this));
+ } else {
+ return (Formatter());
}
}
-void
-Logger::warn(const isc::log::MessageID ident, ...) {
+Logger::Formatter
+Logger::warn(const isc::log::MessageID& ident) {
if (isWarnEnabled()) {
- va_list ap;
- va_start(ap, ident);
- getLoggerPtr()->warn(ident, ap);
- va_end(ap);
+ return (Formatter(WARN, getLoggerPtr()->lookupMessage(ident),
+ this));
+ } else {
+ return (Formatter());
}
}
-void
-Logger::error(const isc::log::MessageID ident, ...) {
+Logger::Formatter
+Logger::error(const isc::log::MessageID& ident) {
if (isErrorEnabled()) {
- va_list ap;
- va_start(ap, ident);
- getLoggerPtr()->error(ident, ap);
- va_end(ap);
+ return (Formatter(ERROR, getLoggerPtr()->lookupMessage(ident),
+ this));
+ } else {
+ return (Formatter());
}
}
-void
-Logger::fatal(const isc::log::MessageID ident, ...) {
+Logger::Formatter
+Logger::fatal(const isc::log::MessageID& ident) {
if (isFatalEnabled()) {
- va_list ap;
- va_start(ap, ident);
- getLoggerPtr()->fatal(ident, ap);
- va_end(ap);
+ return (Formatter(FATAL, getLoggerPtr()->lookupMessage(ident),
+ this));
+ } else {
+ return (Formatter());
}
}
-bool Logger::operator==(Logger& other) {
- return (*getLoggerPtr() == *other.getLoggerPtr());
-}
+// Comparison (testing only)
-// Protected methods (used for testing)
-
-void
-Logger::reset() {
- LoggerImpl::reset();
+bool
+Logger::operator==(Logger& other) {
+ return (*getLoggerPtr() == *other.getLoggerPtr());
}
} // namespace log
diff --git a/src/lib/log/logger.h b/src/lib/log/logger.h
index f35d5ac..96168c0 100644
--- a/src/lib/log/logger.h
+++ b/src/lib/log/logger.h
@@ -18,33 +18,85 @@
#include <cstdlib>
#include <string>
-#include <log/debug_levels.h>
-#include <log/logger_levels.h>
+#include <exceptions/exceptions.h>
+#include <log/logger_level.h>
#include <log/message_types.h>
+#include <log/log_formatter.h>
namespace isc {
namespace log {
-/// \brief Logging API
-///
-/// This module forms the interface into the logging subsystem. Features of the
-/// system and its implementation are:
-///
-/// # Multiple logging objects can be created, each given a name; those with the
-/// same name share characteristics (like destination, level being logged
-/// etc.)
-/// # Messages can be logged at severity levels of FATAL, ERROR, WARN, INFO or
-/// DEBUG. The DEBUG level has further sub-levels numbered 0 (least
-/// informative) to 99 (most informative).
-/// # Each logger has a severity level set associated with it. When a message
-/// is logged, it is output only if it is logged at a level equal to the
-/// logger severity level or greater, e.g. if the logger's severity is WARN,
-/// only messages logged at WARN, ERROR or FATAL will be output.
-/// # Messages are identified by message identifiers, which are keys into a
-/// message dictionary.
+/// \page LoggingApi Logging API
+/// \section LoggingApiOverview Overview
+/// BIND 10 logging uses the concepts of the widely-used Java logging
+/// package log4j (http://logging.apache.log/log4j), albeit implemented
+/// in C++ using an open-source port. Features of the system are:
+///
+/// - Within the code objects - known as loggers - can be created and
+/// used to log messages. These loggers have names; those with the
+/// same name share characteristics (such as output destination).
+/// - Loggers have a hierarchical relationship, with each logger being
+/// the child of another logger, except for the top of the hierarchy, the
+/// root logger. If a logger does not log a message, it is passed to the
+/// parent logger.
+/// - Messages can be logged at severity levels of FATAL, ERROR, WARN, INFO
+/// or DEBUG. The DEBUG level has further sub-levels numbered 0 (least
+/// informative) to 99 (most informative).
+/// - Each logger has a severity level set associated with it. When a
+/// message is logged, it is output only if it is logged at a level equal
+/// to the logger severity level or greater, e.g. if the logger's severity
+/// is WARN, only messages logged at WARN, ERROR or FATAL will be output.
+///
+/// \section LoggingApiLoggerNames BIND 10 Logger Names
+/// Within BIND 10, the root logger root logger is given the name of the
+/// program (via the stand-alone function setRootLoggerName()). Other loggers
+/// are children of the root logger and are named "<program>.<sublogger>".
+/// This name appears in logging output, allowing users to identify both
+/// the BIND 10 program and the component within the program that generated
+/// the message.
+///
+/// When creating a logger, the abbreviated name "<sublogger>" can be used;
+/// the program name will be prepended to it when the logger is created.
+/// In this way, individual libraries can have their own loggers without
+/// worrying about the program in which they are used, but:
+/// - The origin of the message will be clearly identified.
+/// - The same component can have different options (e.g. logging severity)
+/// in different programs at the same time.
+///
+/// \section LoggingApiLoggingMessages Logging Messages
+/// Instead of embedding the text of messages within the code, each message
+/// is referred to using a symbolic name. The logging code uses this name as
+/// a key in a dictionary from which the message text is obtained. Such a
+/// system allows for the optional replacement of message text at run time.
+/// More details about the message disction (and the compiler used to create
+/// the symbol definitions) can be found in other modules in the src/lib/log
+/// directory.
class LoggerImpl; // Forward declaration of the implementation class
+/// \brief Logging Not Initialized
+///
+/// Exception thrown if an attempt is made to access a logging function
+/// if the logging system has not been initialized.
+class LoggingNotInitialized : public isc::Exception {
+public:
+ LoggingNotInitialized(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what)
+ {}
+};
+
+/// \brief Logger Class
+///
+/// This class is the main class used for logging. Use comprises:
+///
+/// 1. Constructing a logger by instantiating it with a specific name. (If the
+/// same logger is in multiple functions within a file, overhead can be
+/// minimised by declaring it as a file-wide static variable.)
+/// 2. Using the error(), info() etc. methods to log an error. (However, it is
+/// recommended to use the LOG_ERROR, LOG_INFO etc. macros defined in macros.h.
+/// These will avoid the potentially-expensive evaluation of arguments if the
+/// severity is such that the message will be suppressed.)
+
class Logger {
public:
@@ -55,45 +107,20 @@ public:
/// \param name Name of the logger. If the name is that of the root name,
/// this creates an instance of the root logger; otherwise it creates a
/// child of the root logger.
- ///
- /// \param infunc This argument is present to get round a bug in some
- /// implementations of the logging system. If the logger is declared in
- /// a function (such that it will be deleted when the function exits,
- /// before the program ends), set this true. If declared outside a
- /// function (such that it gets deleted during program rundown), set false
- /// (the default).\n
- /// \n
- /// The problems encountered was that during program rundown, one logging
- /// implementation (log4cxx) threw a MutexException (this is described in
- /// https://issues.apache.org/jira/browse/LOGCXX-322). As this only occurs
- /// during program rundown, the issue is not serious - it just looks bad to
- /// have the program crash instead of shut down cleanly.\n
- /// \n
- /// If log4cxx is chosen as the implementation, this flag controls the
- /// deletion of the underlying log4cxx data structures when the logger is
- /// deleted. Setting it false for externally-declared loggers inhibits
- /// their deletion; so at program exit the memory is not reclaimed during
- /// program rundown, only when the process is selected. Setting it true
- /// for loggers that will be deleted in the normal running of the program
- /// enables their deletion - which causes no issues as the problem only
- /// manifests itself during program rundown.
- /// \n
- /// The flag has no effect on non-log4cxx implementations.
- Logger(const std::string& name, bool infunc = false) :
- loggerptr_(NULL), name_(name), infunc_(infunc)
+ Logger(const std::string& name) : loggerptr_(NULL), name_(name)
{}
-
/// \brief Destructor
virtual ~Logger();
+ /// \brief The formatter used to replace placeholders
+ typedef isc::log::Formatter<Logger> Formatter;
/// \brief Get Name of Logger
///
/// \return The full name of the logger (including the root name)
virtual std::string getName();
-
/// \brief Set Severity Level for Logger
///
/// Sets the level at which this logger will log messages. If none is set,
@@ -105,14 +132,12 @@ public:
/// outside these limits is silently coerced to the nearest boundary.
virtual void setSeverity(isc::log::Severity severity, int dbglevel = 1);
-
/// \brief Get Severity Level for Logger
///
/// \return The current logging level of this logger. In most cases though,
/// the effective logging level is what is required.
virtual isc::log::Severity getSeverity();
-
/// \brief Get Effective Severity Level for Logger
///
/// \return The effective severity level of the logger. This is the same
@@ -120,13 +145,18 @@ public:
/// is the severity of the parent.
virtual isc::log::Severity getEffectiveSeverity();
-
/// \brief Return DEBUG Level
///
/// \return Current setting of debug level. This is returned regardless of
/// whether the severity is set to debug.
virtual int getDebugLevel();
+ /// \brief Get Effective Debug Level for Logger
+ ///
+ /// \return The effective debug level of the logger. This is the same
+ /// as getDebugLevel() if the logger has a debug level set, but otherwise
+ /// is the debug level of the parent.
+ virtual int getEffectiveDebugLevel();
/// \brief Returns if Debug Message Should Be Output
///
@@ -135,76 +165,63 @@ public:
/// checked is less than or equal to the debug level set for the logger.
virtual bool isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL);
-
/// \brief Is INFO Enabled?
virtual bool isInfoEnabled();
-
/// \brief Is WARNING Enabled?
virtual bool isWarnEnabled();
-
/// \brief Is ERROR Enabled?
virtual bool isErrorEnabled();
-
/// \brief Is FATAL Enabled?
virtual bool isFatalEnabled();
-
/// \brief Output Debug Message
///
/// \param dbglevel Debug level, ranging between 0 and 99. Higher numbers
/// are used for more verbose output.
/// \param ident Message identification.
- /// \param ... Optional arguments for the message.
- void debug(int dbglevel, const MessageID ident, ...);
-
+ Formatter debug(int dbglevel, const MessageID& ident);
/// \brief Output Informational Message
///
/// \param ident Message identification.
- /// \param ... Optional arguments for the message.
- void info(const MessageID ident, ...);
-
+ Formatter info(const MessageID& ident);
/// \brief Output Warning Message
///
/// \param ident Message identification.
- /// \param ... Optional arguments for the message.
- void warn(const MessageID ident, ...);
-
+ Formatter warn(const MessageID& ident);
/// \brief Output Error Message
///
/// \param ident Message identification.
- /// \param ... Optional arguments for the message.
- void error(const MessageID ident, ...);
-
+ Formatter error(const MessageID& ident);
/// \brief Output Fatal Message
///
/// \param ident Message identification.
- /// \param ... Optional arguments for the message.
- void fatal(const MessageID ident, ...);
+ Formatter fatal(const MessageID& ident);
/// \brief Equality
///
/// Check if two instances of this logger refer to the same stream.
- /// (This method is principally for testing.)
///
/// \return true if the logger objects are instances of the same logger.
bool operator==(Logger& other);
-protected:
+private:
+ friend class isc::log::Formatter<Logger>;
- /// \brief Reset Global Data
+ /// \brief Raw output function
///
- /// Used for testing, this calls upon the underlying logger implementation
- /// to clear any global data.
- static void reset();
+ /// This is used by the formatter to output formatted output.
+ ///
+ /// \param severity Severity of the message being output.
+ /// \param message Text of the message to be output.
+ void output(const Severity& severity, const std::string& message);
-private:
/// \brief Copy Constructor
///
/// Disabled (marked private) as it makes no sense to copy the logger -
@@ -219,15 +236,14 @@ private:
/// \brief Initialize Implementation
///
- /// Returns the logger pointer. If not yet set, the underlying
- /// implementation class is initialized.\n
- /// \n
- /// The reason for this indirection is to avoid the "static initialization
- /// fiacso", whereby we cannot rely on the order of static initializations.
- /// The main problem is the root logger name - declared statically - which
- /// is referenced by various loggers. By deferring a reference to it until
- /// after the program starts executing - by which time the root name object
- /// will be initialized - we avoid this problem.
+ /// Returns the logger pointer. If not yet set, the implementation class is
+ /// initialized.
+ ///
+ /// The main reason for this is to allow loggers to be declared statically
+ /// before the underlying logging system is initialized. However, any
+ /// attempt to access a logging method on any logger before initialization -
+ /// regardless of whether is is statically or automatically declared - will
+ /// cause a "LoggingNotInitialized" exception to be thrown.
///
/// \return Returns pointer to implementation
LoggerImpl* getLoggerPtr() {
@@ -242,7 +258,6 @@ private:
LoggerImpl* loggerptr_; ///< Pointer to the underlying logger
std::string name_; ///< Copy of the logger name
- bool infunc_; ///< Copy of the infunc argument
};
} // namespace log
diff --git a/src/lib/log/logger_impl.cc b/src/lib/log/logger_impl.cc
index 41153e9..a6b42b6 100644
--- a/src/lib/log/logger_impl.cc
+++ b/src/lib/log/logger_impl.cc
@@ -13,43 +13,47 @@
// PERFORMANCE OF THIS SOFTWARE
#include <iostream>
+#include <iomanip>
#include <algorithm>
#include <stdarg.h>
#include <stdio.h>
#include <boost/lexical_cast.hpp>
+#include <boost/static_assert.hpp>
+
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#include <log4cplus/configurator.h>
-#include <log/debug_levels.h>
-#include <log/root_logger_name.h>
#include <log/logger.h>
#include <log/logger_impl.h>
+#include <log/logger_level.h>
+#include <log/logger_level_impl.h>
+#include <log/logger_name.h>
#include <log/message_dictionary.h>
#include <log/message_types.h>
-#include <log/root_logger_name.h>
#include <util/strutil.h>
+// Note: as log4cplus and the BIND 10 logger have many concepts in common, and
+// thus many similar names, to disambiguate types we don't "use" the log4cplus
+// namespace: instead, all log4cplus types are explicitly qualified.
+
using namespace std;
namespace isc {
namespace log {
-// Static initializations
-
-LoggerImpl::LoggerInfoMap LoggerImpl::logger_info_;
-LoggerImpl::LoggerInfo LoggerImpl::root_logger_info_(isc::log::INFO, 0);
-
-// Constructor
-LoggerImpl::LoggerImpl(const std::string& name, bool)
+// Constructor. The setting of logger_ must be done when the variable is
+// constructed (instead of being left to the body of the function); at least
+// one compiler requires that all member variables be constructed before the
+// constructor is run, but log4cplus::Logger (the type of logger_) has no
+// default constructor.
+LoggerImpl::LoggerImpl(const string& name) : name_(expandLoggerName(name)),
+ logger_(log4cplus::Logger::getInstance(name_))
{
- // Are we the root logger?
- if (name == getRootLoggerName()) {
- is_root_ = true;
- name_ = name;
- } else {
- is_root_ = false;
- name_ = getRootLoggerName() + "." + name;
- }
}
// Destructor. (Here because of virtual declaration.)
@@ -58,164 +62,72 @@ LoggerImpl::~LoggerImpl() {
}
// Set the severity for logging.
-
void
LoggerImpl::setSeverity(isc::log::Severity severity, int dbglevel) {
-
- // Silently coerce the debug level into the valid range of 0 to 99
-
- int debug_level = max(MIN_DEBUG_LEVEL, min(MAX_DEBUG_LEVEL, dbglevel));
- if (is_root_) {
-
- // Can only set severity for the root logger, you can't disable it.
- // Any attempt to do so is silently ignored.
- if (severity != isc::log::DEFAULT) {
- root_logger_info_ = LoggerInfo(severity, debug_level);
- }
-
- } else if (severity == isc::log::DEFAULT) {
-
- // Want to set to default; this means removing the information
- // about this logger from the logger_info_ if it is set.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
- logger_info_.erase(i);
- }
-
- } else {
-
- // Want to set this information
- logger_info_[name_] = LoggerInfo(severity, debug_level);
- }
+ Level level(severity, dbglevel);
+ logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level));
}
// Return severity level
-
isc::log::Severity
LoggerImpl::getSeverity() {
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
+ return level.severity;
+}
- if (is_root_) {
- return (root_logger_info_.severity);
- }
- else {
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
- return ((i->second).severity);
- }
- else {
- return (isc::log::DEFAULT);
- }
- }
+// Return current debug level (only valid if current severity level is DEBUG).
+int
+LoggerImpl::getDebugLevel() {
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
+ return level.dbglevel;
}
// Get effective severity. Either the current severity or, if not set, the
// severity of the root level.
-
isc::log::Severity
LoggerImpl::getEffectiveSeverity() {
-
- if (!is_root_ && !logger_info_.empty()) {
-
- // Not root logger and there is at least one item in the info map for a
- // logger.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
-
- // Found, so return the severity.
- return ((i->second).severity);
- }
- }
-
- // Must be the root logger, or this logger is defaulting to the root logger
- // settings.
- return (root_logger_info_.severity);
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+ return level.severity;
}
-// Get the debug level. This returns 0 unless the severity is DEBUG.
-
+// Return effective debug level (only valid if current effective severity level
+// is DEBUG).
int
-LoggerImpl::getDebugLevel() {
-
- if (!is_root_ && !logger_info_.empty()) {
-
- // Not root logger and there is something in the map, check if there
- // is a setting for this one.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
-
- // Found, so return the debug level.
- if ((i->second).severity == isc::log::DEBUG) {
- return ((i->second).dbglevel);
- } else {
- return (0);
- }
- }
- }
-
- // Must be the root logger, or this logger is defaulting to the root logger
- // settings.
- if (root_logger_info_.severity == isc::log::DEBUG) {
- return (root_logger_info_.dbglevel);
- } else {
- return (0);
- }
+LoggerImpl::getEffectiveDebugLevel() {
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+ return level.dbglevel;
}
-// The code for isXxxEnabled is quite simple and is in the header. The only
-// exception is isDebugEnabled() where we have the complication of the debug
-// levels.
-
-bool
-LoggerImpl::isDebugEnabled(int dbglevel) {
-
- if (!is_root_ && !logger_info_.empty()) {
-
- // Not root logger and there is something in the map, check if there
- // is a setting for this one.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
-
- // Found, so return the debug level.
- if ((i->second).severity <= isc::log::DEBUG) {
- return ((i->second).dbglevel >= dbglevel);
- } else {
- return (false); // Nothing lower than debug
- }
- }
- }
-
- // Must be the root logger, or this logger is defaulting to the root logger
- // settings.
- if (root_logger_info_.severity <= isc::log::DEBUG) {
- return (root_logger_info_.dbglevel >= dbglevel);
- } else {
- return (false);
- }
-}
// Output a general message
+string*
+LoggerImpl::lookupMessage(const MessageID& ident) {
+ return (new string(string(ident) + " " +
+ MessageDictionary::globalDictionary().getText(ident)));
+}
void
-LoggerImpl::output(const char* sev_text, const MessageID& ident,
- va_list ap)
-{
- char message[512]; // Should be large enough for any message
-
- // Obtain text of the message and substitute arguments.
- const string format = MessageDictionary::globalDictionary().getText(ident);
- vsnprintf(message, sizeof(message), format.c_str(), ap);
-
- // Get the time in a struct tm format, and convert to text
- time_t t_time;
- time(&t_time);
- struct tm* tm_time = localtime(&t_time);
-
- char chr_time[32];
- (void) strftime(chr_time, sizeof(chr_time), "%Y-%m-%d %H:%M:%S", tm_time);
-
- // Now output.
- std::cout << chr_time << " " << sev_text << " [" << getName() << "] " <<
- ident << ", " << message << "\n";
+LoggerImpl::outputRaw(const Severity& severity, const string& message) {
+ switch (severity) {
+ case DEBUG:
+ LOG4CPLUS_DEBUG(logger_, message);
+ break;
+
+ case INFO:
+ LOG4CPLUS_INFO(logger_, message);
+ break;
+
+ case WARN:
+ LOG4CPLUS_WARN(logger_, message);
+ break;
+
+ case ERROR:
+ LOG4CPLUS_ERROR(logger_, message);
+ break;
+
+ case FATAL:
+ LOG4CPLUS_FATAL(logger_, message);
+ }
}
} // namespace log
diff --git a/src/lib/log/logger_impl.h b/src/lib/log/logger_impl.h
index 9fc9cf9..90bd41a 100644
--- a/src/lib/log/logger_impl.h
+++ b/src/lib/log/logger_impl.h
@@ -18,15 +18,19 @@
#include <stdarg.h>
#include <time.h>
+#include <iostream>
#include <cstdlib>
#include <string>
#include <map>
#include <utility>
-#include <log/debug_levels.h>
-#include <log/logger.h>
+
+// log4cplus logger header file
+#include <log4cplus/logger.h>
+
+// BIND-10 logger files
+#include <log/logger_level_impl.h>
#include <log/message_types.h>
-#include <log/root_logger_name.h>
namespace isc {
namespace log {
@@ -35,46 +39,36 @@ namespace log {
///
/// The logger uses a "pimpl" idiom for implementation, where the base logger
/// class contains little more than a pointer to the implementation class, and
-/// all actions are carried out by the latter. This class is an implementation
-/// class that just outputs to stdout.
+/// all actions are carried out by the latter.
+///
+/// This particular implementation is based on log4cplus (from sourceforge:
+/// http://log4cplus.sourceforge.net). Particular items of note:
+///
+/// a) BIND 10 loggers have names of the form "program.sublogger". In other
+/// words, each of the loggers is a sub-logger of the main program logger.
+/// In log4cplus, there is a root logger (called "root" according to the
+/// documentation, but actually unnamed) and all loggers created are subloggers
+/// if it.
+///
+/// In this implementation, the log4cplus root logger is unused. Instead, the
+/// BIND 10 root logger is created as a child of the log4cplus root logger,
+/// and all other loggers used in the program are created as sub-loggers of
+/// that. In this way, the logging system can just include the name of the
+/// logger in each message without the need to specially consider if the
+/// message is the root logger or not.
+///
+/// b) The idea of debug levels is implemented. See logger_level.h and
+/// logger_level_impl.h for more details on this.
class LoggerImpl {
public:
- /// \brief Information About Logger
- ///
- /// Holds a information about a logger, namely its severity and its debug
- /// level. This could be a std::pair, except that it gets confusing when
- /// accessing the LoggerInfoMap: that returns a pair, so we to reference
- /// elements we would use constructs like ((i->first).second);
- struct LoggerInfo {
- isc::log::Severity severity;
- int dbglevel;
-
- LoggerInfo(isc::log::Severity sev = isc::log::INFO,
- int dbg = MIN_DEBUG_LEVEL) : severity(sev), dbglevel(dbg)
- {}
- };
-
-
- /// \brief Information About All Loggers
- ///
- /// Information about all loggers in the system - except the root logger -
- /// is held in a map, linking name of the logger (excluding the root
- /// name component) and its set severity and debug levels. The root
- /// logger information is held separately.
- typedef std::map<std::string, LoggerInfo> LoggerInfoMap;
-
-
/// \brief Constructor
///
/// Creates a logger of the specific name.
///
/// \param name Name of the logger.
- ///
- /// \param exit_delete This argument is present to get round a bug in
- /// the log4cxx implementation. It is unused here.
- LoggerImpl(const std::string& name, bool);
+ LoggerImpl(const std::string& name);
/// \brief Destructor
@@ -94,16 +88,16 @@ public:
///
/// \param severity Severity level to log
/// \param dbglevel If the severity is DEBUG, this is the debug level.
- /// This can be in the range 1 to 100 and controls the verbosity. A value
+ /// This can be in the range 0 to 99 and controls the verbosity. A value
/// outside these limits is silently coerced to the nearest boundary.
- virtual void setSeverity(isc::log::Severity severity, int dbglevel = 1);
+ virtual void setSeverity(Severity severity, int dbglevel = 1);
/// \brief Get Severity Level for Logger
///
/// \return The current logging level of this logger. In most cases though,
/// the effective logging level is what is required.
- virtual isc::log::Severity getSeverity();
+ virtual Severity getSeverity();
/// \brief Get Effective Severity Level for Logger
@@ -111,120 +105,67 @@ public:
/// \return The effective severity level of the logger. This is the same
/// as getSeverity() if the logger has a severity level set, but otherwise
/// is the severity of the parent.
- virtual isc::log::Severity getEffectiveSeverity();
+ virtual Severity getEffectiveSeverity();
- /// \brief Return DEBUG Level
+ /// \brief Return debug level
///
- /// \return Current setting of debug level. This is returned regardless of
- /// whether the
+ /// \return Current setting of debug level. This will be zero if the
+ /// the current severity level is not DEBUG.
virtual int getDebugLevel();
+ /// \brief Return effective debug level
+ ///
+ /// \return Current setting of effective debug level. This will be zero if
+ /// the current effective severity level is not DEBUG.
+ virtual int getEffectiveDebugLevel();
+
+
/// \brief Returns if Debug Message Should Be Output
///
/// \param dbglevel Level for which debugging is checked. Debugging is
/// enabled only if the logger has DEBUG enabled and if the dbglevel
/// checked is less than or equal to the debug level set for the logger.
- virtual bool
- isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL);
+ virtual bool isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL) {
+ Level level(DEBUG, dbglevel);
+ return logger_.isEnabledFor(LoggerLevelImpl::convertFromBindLevel(level));
+ }
/// \brief Is INFO Enabled?
virtual bool isInfoEnabled() {
- return (isEnabled(isc::log::INFO));
+ return (logger_.isEnabledFor(log4cplus::INFO_LOG_LEVEL));
}
/// \brief Is WARNING Enabled?
virtual bool isWarnEnabled() {
- return (isEnabled(isc::log::WARN));
+ return (logger_.isEnabledFor(log4cplus::WARN_LOG_LEVEL));
}
/// \brief Is ERROR Enabled?
virtual bool isErrorEnabled() {
- return (isEnabled(isc::log::ERROR));
+ return (logger_.isEnabledFor(log4cplus::ERROR_LOG_LEVEL));
}
/// \brief Is FATAL Enabled?
virtual bool isFatalEnabled() {
- return (isEnabled(isc::log::FATAL));
+ return (logger_.isEnabledFor(log4cplus::FATAL_LOG_LEVEL));
}
-
- /// \brief Common Severity check
- ///
- /// Implements the common severity check. As an optimisation, this checks
- /// to see if any logger-specific levels have been set (a quick check as it
- /// just involves seeing if the collection of logger information is empty).
- /// if not, it returns the information for the root level; if so, it has
- /// to take longer and look up the information in the map holding the
- /// logging details.
- virtual bool isEnabled(isc::log::Severity severity) {
- if (logger_info_.empty()) {
- return (root_logger_info_.severity <= severity);
- }
- else {
- return (getSeverity() <= severity);
- }
- }
-
-
- /// \brief Output General Message
+ /// \brief Raw output
///
- /// The message is formatted to include the date and time, the severity
- /// and the logger generating the message.
+ /// Writes the message with time into the log. Used by the Formatter
+ /// to produce output.
///
- /// \param sev_text Severity level as a text string
- /// \param ident Message identification
- /// \param ap Variable argument list holding message arguments
- void output(const char* sev_text, const MessageID& ident,
- va_list ap);
+ /// \param severity Severity of the message. (This controls the prefix
+ /// label output with the message text.)
+ /// \param message Text of the message.
+ void outputRaw(const Severity& severity, const std::string& message);
-
- /// \brief Output Debug Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- /// \param ap Variable argument list holding message arguments
- void debug(const MessageID& ident, va_list ap) {
- output("DEBUG", ident, ap);
- }
-
-
- /// \brief Output Informational Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- /// \param ap Variable argument list holding message arguments
- void info(const MessageID& ident, va_list ap) {
- output("INFO ", ident, ap);
- }
-
- /// \brief Output Warning Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- /// \param ap Variable argument list holding message arguments
- void warn(const MessageID& ident, va_list ap) {
- output("WARN ", ident, ap);
- }
-
- /// \brief Output Error Message
+ /// \brief Look up message text in dictionary
///
- /// \param ident Message identification.
- /// \param text Text to log
- /// \param ap Variable argument list holding message arguments
- void error(const MessageID& ident, va_list ap) {
- output("ERROR", ident, ap);
- }
-
- /// \brief Output Fatal Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- /// \param ap Variable argument list holding message arguments
- void fatal(const MessageID& ident, va_list ap) {
- output("FATAL", ident, ap);
- }
+ /// This gets you the unformatted text of message for given ID.
+ std::string* lookupMessage(const MessageID& id);
/// \brief Equality
///
@@ -236,28 +177,9 @@ public:
return (name_ == other.name_);
}
-
- /// \brief Reset Global Data
- ///
- /// Only used for testing, this clears all the logger information and
- /// resets it back to default values.
- static void reset() {
- root_logger_info_ = LoggerInfo(isc::log::INFO, MIN_DEBUG_LEVEL);
- logger_info_.clear();
- }
-
-
private:
- bool is_root_; ///< true if a root logger
- std::string name_; ///< Name of this logger
-
- // Split the status of the root logger from this logger. If - is will
- // probably be the usual case - no per-logger setting is enabled, a
- // quick check of logger_info_.empty() will return true and we can quickly
- // return the root logger status without a length lookup in the map.
-
- static LoggerInfo root_logger_info_; ///< Status of root logger
- static LoggerInfoMap logger_info_; ///< Store of debug levels etc.
+ std::string name_; ///< Full name of this logger
+ log4cplus::Logger logger_; ///< Underlying log4cplus logger
};
} // namespace log
diff --git a/src/lib/log/logger_impl_log4cxx.cc b/src/lib/log/logger_impl_log4cxx.cc
deleted file mode 100644
index afe2d56..0000000
--- a/src/lib/log/logger_impl_log4cxx.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE
-
-#include <iostream>
-
-#include <stdarg.h>
-#include <stdio.h>
-
-#include <log4cxx/appender.h>
-#include <log4cxx/basicconfigurator.h>
-#include <log4cxx/patternlayout.h>
-#include <log4cxx/consoleappender.h>
-
-#include <log/root_logger_name.h>
-#include <log/logger.h>
-#include <log/logger_impl.h>
-#include <log/message_dictionary.h>
-#include <log/message_types.h>
-#include <log/xdebuglevel.h>
-
-#include <util/strutil.h>
-
-using namespace std;
-
-namespace isc {
-namespace log {
-
-// Static initializations
-
-bool LoggerImpl::init_ = false;
-
-// Destructor. Delete log4cxx stuff if "don't delete" is clear.
-
-LoggerImpl::~LoggerImpl() {
- if (exit_delete_) {
- delete loggerptr_;
- }
-}
-
-// Initialize logger - create a logger as a child of the root logger. With
-// log4cxx this is assured by naming the logger <parent>.<child>.
-
-void
-LoggerImpl::initLogger() {
-
- // Initialize basic logging if not already done. This is a one-off for
- // all loggers.
- if (!init_) {
-
- // TEMPORARY
- // Add a suitable console logger to the log4cxx root logger. (This
- // is the logger at the root of the log4cxx tree, not the BIND-10 root
- // logger, which is one level down.) The chosen format is:
- //
- // YYYY-MM-DD hh:mm:ss.sss [logger] SEVERITY: text
- //
- // As noted, this is a temporary hack: it is done here to ensure that
- // a suitable output and output pattern is set. Future versions of the
- // software will set this based on configuration data.
-
- log4cxx::LayoutPtr layout(
- new log4cxx::PatternLayout(
- "%d{yyyy-MM-DD HH:mm:ss.SSS} %-5p [%c] %m\n"));
- log4cxx::AppenderPtr console(
- new log4cxx::ConsoleAppender(layout));
- log4cxx::LoggerPtr sys_root_logger = log4cxx::Logger::getRootLogger();
- sys_root_logger->addAppender(console);
-
- // Set the default logging to INFO
- sys_root_logger->setLevel(log4cxx::Level::getInfo());
-
- // All static stuff initialized
- init_ = true;
- }
-
- // Initialize this logger. Name this as to whether the BIND-10 root logger
- // name has been set. (If not, this mucks up the hierarchy :-( ).
- string root_name = RootLoggerName::getName();
- if (root_name.empty() || (name_ == root_name)) {
- loggerptr_ = new log4cxx::LoggerPtr(log4cxx::Logger::getLogger(name_));
- }
- else {
- loggerptr_ = new log4cxx::LoggerPtr(
- log4cxx::Logger::getLogger(root_name + "." + name_)
- );
- }
-}
-
-
-// Set the severity for logging. There is a 1:1 mapping between the logging
-// severity and the log4cxx logging levels, apart from DEBUG.
-//
-// In log4cxx, each of the logging levels (DEBUG, INFO, WARN etc.) has a numeric
-// value. The level is set to one of these and any numeric level equal to or
-// above it that is reported. For example INFO has a value of 20000 and ERROR
-// a value of 40000. So if a message of WARN severity (= 30000) is logged, it is
-// not logged when the logger's severity level is ERROR (as 30000 !>= 40000).
-// It is reported if the logger's severity level is set to WARN (as 30000 >=
-/// 30000) or INFO (30000 >= 20000).
-//
-// This gives a simple system for handling different debug levels. The debug
-// level is a number between 0 and 99, with 0 being least verbose and 99 the
-// most. To implement this seamlessly, when DEBUG is set, the numeric value
-// of the logging level is actually set to (DEBUG - debug-level). Similarly
-// messages of level "n" are logged at a logging level of (DEBUG - n). Thus if
-// the logging level is set to DEBUG and the debug level set to 25, the actual
-// level set is 10000 - 25 = 99975.
-//
-// Attempting to log a debug message of level 26 is an attempt to log a message
-// of level 10000 - 26 = 9974. As 9974 !>= 9975, it is not logged. A
-// message of level 25 is, because 9975 >= 9975.
-//
-// The extended set of logging levels is implemented by the XDebugLevel class.
-
-void
-LoggerImpl::setSeverity(isc::log::Severity severity, int dbglevel) {
- switch (severity) {
- case NONE:
- getLogger()->setLevel(log4cxx::Level::getOff());
- break;
-
- case FATAL:
- getLogger()->setLevel(log4cxx::Level::getFatal());
- break;
-
- case ERROR:
- getLogger()->setLevel(log4cxx::Level::getError());
- break;
-
- case WARN:
- getLogger()->setLevel(log4cxx::Level::getWarn());
- break;
-
- case INFO:
- getLogger()->setLevel(log4cxx::Level::getInfo());
- break;
-
- case DEBUG:
- getLogger()->setLevel(
- log4cxx::XDebugLevel::getExtendedDebug(dbglevel));
- break;
-
- // Will get here for DEFAULT or any other value. This disables the
- // logger's own severity and it defaults to the severity of the parent
- // logger.
- default:
- getLogger()->setLevel(0);
- }
-}
-
-// Convert between numeric log4cxx logging level and BIND-10 logging severity.
-
-isc::log::Severity
-LoggerImpl::convertLevel(int value) {
-
- // The order is optimised. This is only likely to be called when testing
- // for writing debug messages, so the check for DEBUG_INT is first.
- if (value <= log4cxx::Level::DEBUG_INT) {
- return (DEBUG);
- } else if (value <= log4cxx::Level::INFO_INT) {
- return (INFO);
- } else if (value <= log4cxx::Level::WARN_INT) {
- return (WARN);
- } else if (value <= log4cxx::Level::ERROR_INT) {
- return (ERROR);
- } else if (value <= log4cxx::Level::FATAL_INT) {
- return (FATAL);
- } else {
- return (NONE);
- }
-}
-
-
-// Return the logging severity associated with this logger.
-
-isc::log::Severity
-LoggerImpl::getSeverityCommon(const log4cxx::LoggerPtr& ptrlogger,
- bool check_parent) {
-
- log4cxx::LevelPtr level = ptrlogger->getLevel();
- if (level == log4cxx::LevelPtr()) {
-
- // Null level returned, logging should be that of the parent.
-
- if (check_parent) {
- log4cxx::LoggerPtr parent = ptrlogger->getParent();
- if (parent == log4cxx::LoggerPtr()) {
-
- // No parent, so reached the end of the chain. Return INFO
- // severity.
- return (INFO);
- }
- else {
- return (getSeverityCommon(parent, check_parent));
- }
- }
- else {
- return (DEFAULT);
- }
- } else {
- return (convertLevel(level->toInt()));
- }
-}
-
-
-// Get the debug level. This returns 0 unless the severity is DEBUG.
-
-int
-LoggerImpl::getDebugLevel() {
-
- log4cxx::LevelPtr level = getLogger()->getLevel();
- if (level == log4cxx::LevelPtr()) {
-
- // Null pointer returned, logging should be that of the parent.
- return (0);
-
- } else {
- int severity = level->toInt();
- if (severity <= log4cxx::Level::DEBUG_INT) {
- return (log4cxx::Level::DEBUG_INT - severity);
- }
- else {
- return (0);
- }
- }
-}
-
-
-
-} // namespace log
-} // namespace isc
diff --git a/src/lib/log/logger_impl_log4cxx.h b/src/lib/log/logger_impl_log4cxx.h
deleted file mode 100644
index 3101347..0000000
--- a/src/lib/log/logger_impl_log4cxx.h
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __LOGGER_IMPL_LOG4CXX_H
-#define __LOGGER_IMPL_LOG4CXX_H
-
-#include <cstdlib>
-#include <string>
-#include <boost/lexical_cast.hpp>
-#include <log4cxx/logger.h>
-#include <log4cxx/logger.h>
-
-#include <log/debug_levels.h>
-#include <log/logger.h>
-#include <log/message_types.h>
-
-namespace isc {
-namespace log {
-
-/// \brief Log4cxx Logger Implementation
-///
-/// The logger uses a "pimpl" idiom for implementation, where the base logger
-/// class contains little more than a pointer to the implementation class, and
-/// all actions are carried out by the latter. This class is an implementation
-/// class interfacing to the log4cxx logging system.
-
-class LoggerImpl {
-public:
-
- /// \brief Constructor
- ///
- /// Creates/attaches to a logger of a specific name.
- ///
- /// \param name Name of the logger. If the name is that of the root name,
- /// this creates an instance of the root logger; otherwise it creates a
- /// child of the root logger.
- ///
- /// \param exit_delete This argument is present to get round a bug in
- /// log4cxx. If a log4cxx logger is declared outside an execution unit, it
- /// is not deleted until the program runs down. At that point all such
- /// objects - including internal log4cxx objects - are deleted. However,
- /// there seems to be a bug in log4cxx where the way that such objects are
- /// destroyed causes a MutexException to be thrown (this is described in
- /// https://issues.apache.org/jira/browse/LOGCXX-322). As this only occurs
- /// during program rundown, the issue is not serious - it just looks bad to
- /// have the program crash instead of shut down cleanly.\n
- /// \n
- /// The original implementation of the isc::log::Logger had as a member a
- /// log4cxx logger (actually a LoggerPtr). If the isc:: Logger was declared
- /// statically, when it was destroyed at the end of the program the internal
- /// LoggerPtr was destroyed, which triggered the problem. The problem did
- /// not occur if the isc::log::Logger was created on the stack. To get
- /// round this, the internal LoggerPtr is now created dynamically. The
- /// exit_delete argument controls its destruction: if true, it is destroyed
- /// in the ISC Logger destructor. If false, it is not.\n
- /// \n
- /// When creating an isc::log::Logger on the stack, the argument should be
- /// false (the default); when the Logger is destroyed, all the internal
- /// log4cxx objects are destroyed. As only the logger (and not the internal
- /// log4cxx data structures are being destroyed), all is well. However,
- /// when creating the logger statically, the argument should be false. This
- /// means that the log4cxx objects are not destroyed at program rundown;
- /// instead memory is reclaimed and files are closed when the process is
- /// destroyed, something that does not trigger the bug.
- LoggerImpl(const std::string& name, bool exit_delete = false) :
- loggerptr_(NULL), name_(name), exit_delete_(exit_delete)
- {}
-
-
- /// \brief Destructor
- virtual ~LoggerImpl();
-
-
- /// \brief Get the full name of the logger (including the root name)
- virtual std::string getName() {
- return (getLogger()->getName());
- }
-
-
- /// \brief Set Severity Level for Logger
- ///
- /// Sets the level at which this logger will log messages. If none is set,
- /// the level is inherited from the parent.
- ///
- /// \param severity Severity level to log
- /// \param dbglevel If the severity is DEBUG, this is the debug level.
- /// This can be in the range 1 to 100 and controls the verbosity. A value
- /// outside these limits is silently coerced to the nearest boundary.
- virtual void setSeverity(isc::log::Severity severity, int dbglevel = 1);
-
-
- /// \brief Get Severity Level for Logger
- ///
- /// \return The current logging level of this logger. In most cases though,
- /// the effective logging level is what is required.
- virtual isc::log::Severity getSeverity() {
- return (getSeverityCommon(getLogger(), false));
- }
-
-
- /// \brief Get Effective Severity Level for Logger
- ///
- /// \return The effective severity level of the logger. This is the same
- /// as getSeverity() if the logger has a severity level set, but otherwise
- /// is the severity of the parent.
- virtual isc::log::Severity getEffectiveSeverity() {
- return (getSeverityCommon(getLogger(), true));
- }
-
-
- /// \brief Return DEBUG Level
- ///
- /// \return Current setting of debug level. This is returned regardless of
- /// whether the
- virtual int getDebugLevel();
-
-
- /// \brief Returns if Debug Message Should Be Output
- ///
- /// \param dbglevel Level for which debugging is checked. Debugging is
- /// enabled only if the logger has DEBUG enabled and if the dbglevel
- /// checked is less than or equal to the debug level set for the logger.
- virtual bool
- isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL) {
- return (getLogger()->getEffectiveLevel()->toInt() <=
- (log4cxx::Level::DEBUG_INT - dbglevel));
- }
-
-
- /// \brief Is INFO Enabled?
- virtual bool isInfoEnabled() {
- return (getLogger()->isInfoEnabled());
- }
-
-
- /// \brief Is WARNING Enabled?
- virtual bool isWarnEnabled() {
- return (getLogger()->isWarnEnabled());
- }
-
-
- /// \brief Is ERROR Enabled?
- virtual bool isErrorEnabled() {
- return (getLogger()->isErrorEnabled());
- }
-
-
- /// \brief Is FATAL Enabled?
- virtual bool isFatalEnabled() {
- return (getLogger()->isFatalEnabled());
- }
-
-
- /// \brief Output Debug Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- void debug(const MessageID& ident, const char* text) {
- LOG4CXX_DEBUG(getLogger(), ident << ", " << text);
- }
-
-
- /// \brief Output Informational Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- void info(const MessageID& ident, const char* text) {
- LOG4CXX_INFO(getLogger(), ident << ", " << text);
- }
-
-
- /// \brief Output Warning Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- void warn(const MessageID& ident, const char* text) {
- LOG4CXX_WARN(getLogger(), ident << ", " << text);
- }
-
-
- /// \brief Output Error Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- void error(const MessageID& ident, const char* text) {
- LOG4CXX_ERROR(getLogger(), ident << ", " << text);
- }
-
-
- /// \brief Output Fatal Message
- ///
- /// \param ident Message identification.
- /// \param text Text to log
- void fatal(const MessageID& ident, const char* text) {
- LOG4CXX_FATAL(getLogger(), ident << ", " << text);
- }
-
- //@{
- /// \brief Testing Methods
- ///
- /// The next set of methods are used in testing. As they are accessed from
- /// the main logger class, they must be public.
-
- /// \brief Equality
- ///
- /// Check if two instances of this logger refer to the same stream.
- /// (This method is principally for testing.)
- ///
- /// \return true if the logger objects are instances of the same logger.
- bool operator==(LoggerImpl& other) {
- return (*loggerptr_ == *other.loggerptr_);
- }
-
-
- /// \brief Logger Initialized
- ///
- /// Check that the logger has been properly initialized. (This method
- /// is principally for testing.)
- ///
- /// \return true if this logger object has been initialized.
- bool isInitialized() {
- return (loggerptr_ != NULL);
- }
-
- /// \brief Reset Global Data
- ///
- /// Only used for testing, this clears all the logger information and
- /// resets it back to default values. This is a no-op for log4cxx.
- static void reset() {
- }
-
- //@}
-
-protected:
-
- /// \brief Convert Between BIND-10 and log4cxx Logging Levels
- ///
- /// This method is marked protected to allow for unit testing.
- ///
- /// \param value log4cxx numeric logging level
- ///
- /// \return BIND-10 logging severity
- isc::log::Severity convertLevel(int value);
-
-private:
-
- /// \brief Get Severity Level for Logger
- ///
- /// This is common code for getSeverity() and getEffectiveSeverity() -
- /// it returns the severity of the logger; if not set (and the check_parent)
- /// flag is set, it searches up the parent-child tree until a severity
- /// level is found and uses that.
- ///
- /// \param ptrlogger Pointer to the log4cxx logger to check.
- /// \param check_parent true to search up the tree, false to return the
- /// current level.
- ///
- /// \return The effective severity level of the logger. This is the same
- /// as getSeverity() if the logger has a severity level set, but otherwise
- /// is the severity of the parent.
- isc::log::Severity getSeverityCommon(const log4cxx::LoggerPtr& ptrlogger,
- bool check_parent);
-
-
-
- /// \brief Initialize log4cxx Logger
- ///
- /// Creates the log4cxx logger used internally. A function is provided for
- /// this so that the creation does not take place when this Logger object
- /// is created but when it is used. As the latter occurs in executable
- /// code but the former can occur during initialization, this order
- /// guarantees that anything that is statically initialized has completed
- /// its initialization by the time the logger is used.
- void initLogger();
-
-
- /// \brief Return underlying log4cxx logger, initializing it if necessary
- ///
- /// \return Loggerptr object
- log4cxx::LoggerPtr& getLogger() {
- if (loggerptr_ == NULL) {
- initLogger();
- }
- return (*loggerptr_);
- }
-
- // Members. Note that loggerptr_ is a pointer to a LoggerPtr, which is
- // itself a pointer to the underlying log4cxx logger. This is due to the
- // problems with memory deletion on program exit, explained in the comments
- // for the "exit_delete" parameter in this class's constructor.
-
- log4cxx::LoggerPtr* loggerptr_; ///< Pointer to the underlying logger
- std::string name_; ///< Name of this logger]
- bool exit_delete_; ///< Delete loggerptr_ on exit?
-
- // NOTE - THIS IS A PLACE HOLDER
- static bool init_; ///< Set true when initialized
-};
-
-} // namespace log
-} // namespace isc
-
-
-#endif // __LOGGER_IMPL_LOG4CXX_H
diff --git a/src/lib/log/logger_level.cc b/src/lib/log/logger_level.cc
new file mode 100644
index 0000000..abac5be
--- /dev/null
+++ b/src/lib/log/logger_level.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE
+
+#include <log/logger_level.h>
+#include <log/macros.h>
+#include <log/log_messages.h>
+
+#include <boost/algorithm/string.hpp>
+
+
+namespace isc {
+namespace log {
+
+isc::log::Severity
+getSeverity(const std::string& sev_str) {
+ if (boost::iequals(sev_str, "DEBUG")) {
+ return isc::log::DEBUG;
+ } else if (boost::iequals(sev_str, "INFO")) {
+ return isc::log::INFO;
+ } else if (boost::iequals(sev_str, "WARN")) {
+ return isc::log::WARN;
+ } else if (boost::iequals(sev_str, "ERROR")) {
+ return isc::log::ERROR;
+ } else if (boost::iequals(sev_str, "FATAL")) {
+ return isc::log::FATAL;
+ } else if (boost::iequals(sev_str, "NONE")) {
+ return isc::log::NONE;
+ } else {
+ Logger logger("log");
+ LOG_ERROR(logger, LOG_BAD_SEVERITY).arg(sev_str);
+ return isc::log::INFO;
+ }
+}
+
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_level.h b/src/lib/log/logger_level.h
new file mode 100644
index 0000000..d84cb87
--- /dev/null
+++ b/src/lib/log/logger_level.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_LEVEL_H
+#define __LOGGER_LEVEL_H
+
+#include <string>
+
+#if defined(_WIN32) && defined(ERROR)
+#undef ERROR
+#endif
+
+namespace isc {
+namespace log {
+
+/// \brief Severity Levels
+///
+/// Defines the severity levels for logging. This is shared between the logger
+/// and the implementations classes.
+///
+/// N.B. The order of the levels - DEBUG less than INFO less that WARN etc. is
+/// implicitly assumed in several implementations. They must not be changed.
+
+typedef enum {
+ DEFAULT = 0, // Default to logging level of the parent
+ DEBUG = 1,
+ INFO = 2,
+ WARN = 3,
+ ERROR = 4,
+ FATAL = 5,
+ NONE = 6 // Disable logging
+} Severity;
+
+/// Minimum/maximum debug levels.
+
+const int MIN_DEBUG_LEVEL = 0;
+const int MAX_DEBUG_LEVEL = 99;
+
+/// \brief Log level structure
+///
+/// A simple pair structure that provides suitable names for the members. It
+/// holds a combination of logging severity and debug level.
+struct Level {
+ Severity severity; ///< Logging severity
+ int dbglevel; ///< Debug level
+
+ Level(Severity sev = DEFAULT, int dbg = MIN_DEBUG_LEVEL) :
+ severity(sev), dbglevel(dbg)
+ {}
+
+ // Default assignment and copy constructor is appropriate
+};
+
+/// \brief Returns the isc::log::Severity value represented by the given string
+///
+/// This must be one of the strings "DEBUG", "INFO", "WARN", "ERROR", "FATAL" or
+/// "NONE". (Case is not important, but the string most not contain leading or
+/// trailing spaces.)
+///
+/// \param sev_str The string representing severity value
+///
+/// \return The severity. If the string is not recognized, an error will be
+/// logged and the string will return isc::log::INFO.
+isc::log::Severity getSeverity(const std::string& sev_str);
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_LEVEL_H
diff --git a/src/lib/log/logger_level_impl.cc b/src/lib/log/logger_level_impl.cc
new file mode 100644
index 0000000..3bc6ff7
--- /dev/null
+++ b/src/lib/log/logger_level_impl.cc
@@ -0,0 +1,234 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <algorithm>
+#include <string.h>
+#include <iostream>
+#include <boost/lexical_cast.hpp>
+
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#include <log4cplus/logger.h>
+
+#ifdef _WIN32
+#ifdef ERROR
+#undef ERROR
+#endif
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
+#define strncasecmp _strnicmp
+#endif
+
+#include <log/logger_level.h>
+#include <log/logger_level_impl.h>
+#include <log/logimpl_messages.h>
+#include <log/macros.h>
+
+using namespace log4cplus;
+using namespace std;
+
+namespace {
+isc::log::Logger logger("log");
+}
+
+namespace isc {
+namespace log {
+
+// Convert BIND 10 level to a log4cplus logging level.
+log4cplus::LogLevel
+LoggerLevelImpl::convertFromBindLevel(const Level& level) {
+
+ // BIND 10 logging levels are small integers so we can do a table lookup
+ static const log4cplus::LogLevel log4cplus_levels[] = {
+ log4cplus::NOT_SET_LOG_LEVEL,
+ log4cplus::DEBUG_LOG_LEVEL,
+ log4cplus::INFO_LOG_LEVEL,
+ log4cplus::WARN_LOG_LEVEL,
+ log4cplus::ERROR_LOG_LEVEL,
+ log4cplus::FATAL_LOG_LEVEL,
+ log4cplus::OFF_LOG_LEVEL
+ };
+
+ // ... with compile-time checks to ensure that table indexes are correct.
+ BOOST_STATIC_ASSERT(static_cast<int>(DEFAULT) == 0);
+ BOOST_STATIC_ASSERT(static_cast<int>(DEBUG) == 1);
+ BOOST_STATIC_ASSERT(static_cast<int>(INFO) == 2);
+ BOOST_STATIC_ASSERT(static_cast<int>(WARN) == 3);
+ BOOST_STATIC_ASSERT(static_cast<int>(ERROR) == 4);
+ BOOST_STATIC_ASSERT(static_cast<int>(FATAL) == 5);
+ BOOST_STATIC_ASSERT(static_cast<int>(NONE) == 6);
+
+ // Do the conversion
+ if (level.severity == DEBUG) {
+
+ // Debug severity, so the log4cplus level returned depends on the
+ // debug level. Silently limit the debug level to the range
+ // MIN_DEBUG_LEVEL to MAX_DEBUG_LEVEL (avoids the hassle of throwing
+ // and catching exceptions and besides, this is for debug information).
+ int limited = std::max(MIN_DEBUG_LEVEL,
+ std::min(level.dbglevel, MAX_DEBUG_LEVEL));
+ LogLevel newlevel = static_cast<int>(DEBUG_LOG_LEVEL -
+ (limited - MIN_DEBUG_LEVEL));
+ return (static_cast<log4cplus::LogLevel>(newlevel));
+
+ } else {
+
+ // Can do a table lookup to speed things up. There is no need to check
+ // that the index is out of range. That the variable is of type
+ // isc::log::Severity ensures that it must be one of the Severity enum
+ // members - conversion of a numeric value to an enum is not permitted.
+ return (log4cplus_levels[level.severity]);
+ }
+}
+
+// Convert log4cplus logging level to BIND 10 debug level. It is up to the
+// caller to validate that the debug level is valid.
+Level
+LoggerLevelImpl::convertToBindLevel(const log4cplus::LogLevel loglevel) {
+
+ // Not easy to do a table lookup as the numerical values of log4cplus levels
+ // are quite high.
+ if (loglevel <= log4cplus::NOT_SET_LOG_LEVEL) {
+ return (Level(DEFAULT));
+
+ } else if (loglevel <= log4cplus::DEBUG_LOG_LEVEL) {
+
+ // Debug severity, so extract the debug level from the numeric value.
+ // If outside the limits, change the severity to the level above or
+ // below.
+ int dbglevel = MIN_DEBUG_LEVEL +
+ static_cast<int>(log4cplus::DEBUG_LOG_LEVEL) -
+ static_cast<int>(loglevel);
+ if (dbglevel > MAX_DEBUG_LEVEL) {
+ return (Level(DEFAULT));
+ } else if (dbglevel < MIN_DEBUG_LEVEL) {
+ return (Level(INFO));
+ }
+ return (Level(DEBUG, dbglevel));
+
+ } else if (loglevel <= log4cplus::INFO_LOG_LEVEL) {
+ return (Level(INFO));
+
+ } else if (loglevel <= log4cplus::WARN_LOG_LEVEL) {
+ return (Level(WARN));
+
+ } else if (loglevel <= log4cplus::ERROR_LOG_LEVEL) {
+ return (Level(ERROR));
+
+ } else if (loglevel <= log4cplus::FATAL_LOG_LEVEL) {
+ return (Level(FATAL));
+
+ }
+
+ return (Level(NONE));
+}
+
+
+// Convert string to appropriate logging level
+log4cplus::LogLevel
+LoggerLevelImpl::logLevelFromString(const log4cplus::tstring& level) {
+
+ std::string name = level; // Get to known type
+ size_t length = name.size(); // Length of the string
+
+ if (length < 5) {
+
+ // String can't possibly start DEBUG so we don't know what it is.
+ // As per documentation, return NOT_SET level.
+ return (NOT_SET_LOG_LEVEL);
+ }
+ else {
+ if (strncasecmp(name.c_str(), "DEBUG", 5) == 0) {
+
+ // String starts "DEBUG" (or "debug" or any case mixture). The
+ // rest of the string - if any - should be a number.
+ if (length == 5) {
+
+ // It is plain "DEBUG". Take this as level 0.
+ return (DEBUG_LOG_LEVEL);
+ }
+ else {
+
+ // Try converting the remainder to an integer. The "5" is
+ // the length of the string "DEBUG". Note that if the number
+ // is outside the range of debug levels, it is coerced to the
+ // nearest limit. Thus a level of DEBUG509 will end up as
+ // if DEBUG99 has been specified.
+ try {
+ int dbglevel = boost::lexical_cast<int>(name.substr(5));
+ if (dbglevel < MIN_DEBUG_LEVEL) {
+ LOG_WARN(logger, LOGIMPL_BELOW_MIN_DEBUG).arg(dbglevel)
+ .arg(MIN_DEBUG_LEVEL);
+ dbglevel = MIN_DEBUG_LEVEL;
+
+ } else if (dbglevel > MAX_DEBUG_LEVEL) {
+ LOG_WARN(logger, LOGIMPL_ABOVE_MAX_DEBUG).arg(dbglevel)
+ .arg(MAX_DEBUG_LEVEL);
+ dbglevel = MAX_DEBUG_LEVEL;
+
+ }
+ return convertFromBindLevel(Level(DEBUG, dbglevel));
+ }
+ catch (boost::bad_lexical_cast&) {
+ LOG_ERROR(logger, LOGIMPL_BAD_DEBUG_STRING).arg(name);
+ return (NOT_SET_LOG_LEVEL);
+ }
+ }
+ } else {
+
+ // Unknown string - return default. Log4cplus will call any other
+ // registered conversion functions to interpret it.
+ return (NOT_SET_LOG_LEVEL);
+ }
+ }
+}
+
+// Convert logging level to string. If the level is a valid debug level,
+// return the string DEBUG, else return the empty string.
+log4cplus::tstring
+LoggerLevelImpl::logLevelToString(log4cplus::LogLevel level) {
+ Level bindlevel = convertToBindLevel(level);
+ Severity& severity = bindlevel.severity;
+ int& dbglevel = bindlevel.dbglevel;
+
+ if ((severity == DEBUG) &&
+ ((dbglevel >= MIN_DEBUG_LEVEL) && (dbglevel <= MAX_DEBUG_LEVEL))) {
+ return (tstring("DEBUG"));
+ }
+
+ // Unknown, so return empty string for log4cplus to try other conversion
+ // functions.
+ return (tstring());
+}
+
+// Initialization. Register the conversion functions with the LogLevelManager.
+void
+LoggerLevelImpl::init() {
+
+ // Get the singleton log-level manager.
+ LogLevelManager& manager = getLogLevelManager();
+
+ // Register the conversion functions
+ manager.pushFromStringMethod(LoggerLevelImpl::logLevelFromString);
+ manager.pushToStringMethod(LoggerLevelImpl::logLevelToString);
+}
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_level_impl.h b/src/lib/log/logger_level_impl.h
new file mode 100644
index 0000000..9289a1d
--- /dev/null
+++ b/src/lib/log/logger_level_impl.h
@@ -0,0 +1,127 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_LEVEL_IMPL_H
+#define __LOGGER_LEVEL_IMPL_H
+
+#include <log4cplus/logger.h>
+#include <log/logger_level.h>
+
+namespace isc {
+namespace log {
+
+/// \brief Implementation aspects of logging levels
+///
+/// This extends the log4cplus level set to allow 100 debug levels.
+///
+/// First some terminology, as the use of the term "level" gets confusing. The
+/// code and comments here use the term "level" in two contexts:
+///
+/// Logging level: The category of messages to log. By default log4cplus
+/// defines the following logging levels: OFF_LOG_LEVEL, FATAL_LOG_LEVEL,
+/// ERROR_LOG_LEVEL, WARN_LOG_LEVEL, INFO_LOG_LEVEL, DEBUG_LOG_LEVEL,
+/// TRACE_LOG_LEVEL, ALL_LOG_LEVEL (which here will be abbreviated OFF, FATAL
+/// etc.). Within the context of BIND-10, OFF, TRACE and ALL are not used
+/// and the idea of DEBUG has been extended, as will be seen below. In
+/// BIND 10 terms, this is known as "severity"; the "logging level" usage will
+/// usually be used when talking about log4cplus aspects of the idea (as
+/// log4cplus uses that teminology).
+///
+/// Debug level: This is a number that ranges from 0 to 99 and is used by the
+/// application to control the detail of debug output. A value of 0 gives the
+/// highest-level debug output; a value of 99 gives the most verbose and most
+/// detailed. Debug messages (or whatever debug level) are only ever output
+/// when the logging level is set to DEBUG. (Note that the numbers 0 and 99
+/// are not hard-coded - they are the constants MIN_DEBUG_LEVEL and
+/// MAX_DEBUG_LEVEL.)
+///
+/// With log4cplus, the various logging levels have a numeric value associated
+/// with them, such that FATAL > ERROR > WARNING etc. This suggests that the
+/// idea of debug levels can be incorporated into the existing logging level
+/// scheme by assigning them appropriate numeric values, i.e.
+///
+/// WARNING > INFO > DEBUG > DEBUG - 1 > DEBUG - 2 > ... > DEBUG - 99
+///
+/// Setting a numeric level of DEBUG enables the basic messages; setting higher
+/// debug levels (corresponding to lower numeric logging levels) will enable
+/// progressively more messages. The lowest debug level (0) is chosen such that
+/// it corresponds to the default level of DEBUG.
+///
+/// This class comprises nothing more than static methods to aid the conversion
+/// of logging levels between log4cplus and BIND 10, and to register those
+/// levels with log4cplus.
+
+class LoggerLevelImpl {
+public:
+
+ /// \brief Convert BIND 10 level to log4cplus logging level
+ ///
+ /// Converts the BIND 10 severity level into a log4cplus logging level.
+ /// If the severity is DEBUG, the current BIND 10 debug level is taken
+ /// into account when doing the conversion.
+ ///
+ /// \param level BIND 10 severity and debug level
+ ///
+ /// \return Equivalent log4cplus logging level.
+ static
+ log4cplus::LogLevel convertFromBindLevel(const isc::log::Level& level);
+
+ /// \brief Convert log4cplus logging level to BIND 10 logging level
+ ///
+ /// Converts the log4cplus log level into a BIND 10 severity level.
+ /// The log4cplus log level may be non-standard in which case it is
+ /// encoding a BIND 10 debug level as well.
+ ///
+ /// \param level log4cplus log level
+ ///
+ /// \return Equivalent BIND 10 severity and debug level
+ static
+ isc::log::Level convertToBindLevel(const log4cplus::LogLevel loglevel);
+
+ /// \brief Convert string to log4cplus logging level
+ ///
+ /// BIND 10 extends the set of logging levels in log4cplus with a group
+ /// of debug levels. These are given names DEBUG0 through DEBUG99 (with
+ /// DEBUG0 being equivalent to DEBUG, the standard log level. If the name
+ /// is DEBUGn but n lies outside the range of debug levels, debug level
+ /// specifies is coerced to the nearest valid value. If the string is just
+ /// not recognised, a NOT_SET_LOG_LEVEL is returned.
+ ///
+ /// \param level String representing the logging level.
+ ///
+ /// \return Corresponding log4cplus log level
+ static
+ log4cplus::LogLevel logLevelFromString(const log4cplus::tstring& level);
+
+ /// \brief Convert log level to string
+ ///
+ /// If the log level is one of the extended debug levels, the string DEBUG
+ /// is returned, otherwise the empty string.
+ ///
+ /// \param level Extended logging level
+ ///
+ /// \return Equivalent string.
+ static log4cplus::tstring logLevelToString(log4cplus::LogLevel level);
+
+ /// \brief Initialize extended logging levels
+ ///
+ /// This must be called once, after log4cplus has been initialized. It
+ /// registers the level/string converter functions.
+ static void init();
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_LEVEL_IMPL_H
diff --git a/src/lib/log/logger_levels.h b/src/lib/log/logger_levels.h
deleted file mode 100644
index 48fa372..0000000
--- a/src/lib/log/logger_levels.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __LOGGER_LEVELS_H
-#define __LOGGER_LEVELS_H
-
-namespace isc {
-namespace log {
-
-/// \brief Severity Levels
-///
-/// Defines the severity levels for logging. This is shared between the logger
-/// and the implementations classes.
-///
-/// N.B. The order of the levels - DEBUG less than INFO less that WARN etc. is
-/// implicitly assumed in several implementations. They must not be changed.
-
-#if defined(_WIN32) && defined(ERROR)
-#undef ERROR
-#endif
-
-typedef enum {
- DEFAULT = 0, // Default to logging level of the parent
- DEBUG = 1,
- INFO = 2,
- WARN = 3,
- ERROR = 4,
- FATAL = 5,
- NONE = 6 // Disable logging
-} Severity;
-
-} // namespace log
-} // namespace isc
-
-#endif // __LOGGER_LEVELS_H
diff --git a/src/lib/log/logger_manager.cc b/src/lib/log/logger_manager.cc
new file mode 100644
index 0000000..70e0d6f
--- /dev/null
+++ b/src/lib/log/logger_manager.cc
@@ -0,0 +1,184 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <algorithm>
+#include <vector>
+
+#include <log/logger.h>
+#include <log/logger_manager.h>
+#include <log/logger_manager_impl.h>
+#include <log/logger_name.h>
+#include <log/logger_support.h>
+#include <log/log_messages.h>
+#include <log/macros.h>
+#include <log/message_dictionary.h>
+#include <log/message_exception.h>
+#include <log/message_initializer.h>
+#include <log/message_initializer.h>
+#include <log/message_reader.h>
+#include <log/message_types.h>
+
+using namespace std;
+
+namespace {
+
+// Logger used for logging messages within the logging code itself.
+isc::log::Logger logger("log");
+
+// Static stores for the initialization severity and debug level.
+// These are put in methods to avoid a "static initialization fiasco".
+
+isc::log::Severity& initSeverity() {
+ static isc::log::Severity severity = isc::log::INFO;
+ return (severity);
+}
+
+int& initDebugLevel() {
+ static int dbglevel = 0;
+ return (dbglevel);
+}
+
+std::string& initRootName() {
+ static std::string root("bind10");
+ return (root);
+}
+
+} // Anonymous namespace
+
+
+namespace isc {
+namespace log {
+
+// Constructor - create the implementation class.
+LoggerManager::LoggerManager() {
+ impl_ = new LoggerManagerImpl();
+}
+
+// Destructor - get rid of the implementation class
+LoggerManager::~LoggerManager() {
+ delete impl_;
+}
+
+// Initialize processing
+void
+LoggerManager::processInit() {
+ impl_->processInit();
+}
+
+// Process logging specification
+void
+LoggerManager::processSpecification(const LoggerSpecification& spec) {
+ impl_->processSpecification(spec);
+}
+
+// End Processing
+void
+LoggerManager::processEnd() {
+ impl_->processEnd();
+}
+
+
+/// Logging system initialization
+
+void
+LoggerManager::init(const std::string& root, isc::log::Severity severity,
+ int dbglevel, const char* file)
+{
+ // Save name, severity and debug level for later. No need to save the
+ // file name as once the local message file is read the messages will
+ // not be lost.
+ initRootName() = root;
+ initSeverity() = severity;
+ initDebugLevel() = dbglevel;
+
+ // Create the BIND 10 root logger and set the default severity and
+ // debug level. This is the logger that has the name of the application.
+ // All other loggers created in this application will be its children.
+ setRootLoggerName(root);
+
+ // Initialize the implementation logging. After this point, some basic
+ // logging has been set up and messages can be logged.
+ LoggerManagerImpl::init(severity, dbglevel);
+ setLoggingInitialized();
+
+ // Check if there were any duplicate message IDs in the default dictionary
+ // and if so, log them. Log using the logging facility logger.
+ vector<string>& duplicates = MessageInitializer::getDuplicates();
+ if (!duplicates.empty()) {
+
+ // There are duplicates present. This will be listed in alphabetic
+ // order of message ID, so they need to be sorted. This list itself may
+ // contain duplicates; if so, the message ID is listed as many times as
+ // there are duplicates.
+ sort(duplicates.begin(), duplicates.end());
+ for (vector<string>::iterator i = duplicates.begin();
+ i != duplicates.end(); ++i) {
+ LOG_WARN(logger, LOG_DUPLICATE_MESSAGE_ID).arg(*i);
+ }
+
+ }
+
+ // Replace any messages with local ones (if given)
+ if (file) {
+ readLocalMessageFile(file);
+ }
+}
+
+
+// Read local message file
+// TODO This should be done after the configuration has been read so that
+// the file can be placed in the local configuration
+void
+LoggerManager::readLocalMessageFile(const char* file) {
+
+ MessageDictionary& dictionary = MessageDictionary::globalDictionary();
+ MessageReader reader(&dictionary);
+ try {
+
+ logger.info(LOG_READING_LOCAL_FILE).arg(file);
+ reader.readFile(file, MessageReader::REPLACE);
+
+ // File successfully read. As each message in the file is supposed to
+ // replace one in the dictionary, any ID read that can't be located in
+ // the dictionary will not be used. To aid problem diagnosis, the
+ // unknown message IDs are listed.
+ MessageReader::MessageIDCollection unknown = reader.getNotAdded();
+ for (MessageReader::MessageIDCollection::const_iterator
+ i = unknown.begin(); i != unknown.end(); ++i) {
+ string message_id = boost::lexical_cast<string>(*i);
+ logger.warn(LOG_NO_SUCH_MESSAGE).arg(message_id);
+ }
+ }
+ catch (MessageException& e) {
+ MessageID ident = e.id();
+ vector<string> args = e.arguments();
+
+ // Log the variable number of arguments. The actual message will be
+ // logged when the error_message variable is destroyed.
+ Formatter<isc::log::Logger> error_message = logger.error(ident);
+ for (int i = 0; i < args.size(); ++i) {
+ error_message = error_message.arg(args[i]);
+ }
+ }
+}
+
+// Reset logging to settings passed to init()
+void
+LoggerManager::reset() {
+ setRootLoggerName(initRootName());
+ LoggerManagerImpl::reset(initSeverity(), initDebugLevel());
+}
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_manager.h b/src/lib/log/logger_manager.h
new file mode 100644
index 0000000..dece0c9
--- /dev/null
+++ b/src/lib/log/logger_manager.h
@@ -0,0 +1,141 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_MANAGER_H
+#define __LOGGER_MANAGER_H
+
+#include "exceptions/exceptions.h"
+#include <log/logger_specification.h>
+
+// Generated if, when updating the logging specification, an unknown
+// destination is encountered.
+class UnknownLoggingDestination : public isc::Exception {
+public:
+ UnknownLoggingDestination(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what)
+ {}
+};
+
+namespace isc {
+namespace log {
+
+class LoggerManagerImpl;
+
+/// \brief Logger Manager
+///
+/// The logger manager class exists to process the set of logger specifications
+/// and use them to set up the logging in the program appropriately.
+///
+/// To isolate the underlying implementation from basic processing, the
+/// LoggerManager is implemented using the "pimpl" idiom.
+
+class LoggerManager {
+public:
+ /// \brief Constructor
+ LoggerManager();
+
+ /// \brief Destructor
+ ~LoggerManager();
+
+ /// \brief Process Specifications
+ ///
+ /// Replaces the current logging configuration by the one given.
+ ///
+ /// \param start Iterator pointing to the start of the collection of
+ /// logging specifications.
+ /// \param finish Iterator pointing to the end of the collection of
+ /// logging specification.
+ template <typename T>
+ void process(T start, T finish) {
+ processInit();
+ for (T i = start; i != finish; ++i) {
+ processSpecification(*i);
+ }
+ processEnd();
+ }
+
+ /// \brief Process a single specification
+ ///
+ /// A convenience function for a single specification.
+ ///
+ /// \param spec Specification to process
+ void process(const LoggerSpecification& spec) {
+ processInit();
+ processSpecification(spec);
+ processEnd();
+ }
+
+ /// \brief Run-Time Initialization
+ ///
+ /// Performs run-time initialization of the logger system, in particular
+ /// supplying the root logger name and name of a replacement message file.
+ ///
+ /// This must be the first logging function called in the program. If
+ /// an attempt is made to log a message before this is function is called,
+ /// the results will be dependent on the underlying logging package.
+ ///
+ /// \param root Name of the root logger. This should be set to the name of
+ /// the program.
+ /// \param severity Severity at which to log
+ /// \param dbglevel Debug severity (ignored if "severity" is not "DEBUG")
+ /// \param file Name of the local message file. This must be NULL if there
+ /// is no local message file.
+ static void init(const std::string& root,
+ isc::log::Severity severity = isc::log::INFO,
+ int dbglevel = 0, const char* file = NULL);
+
+ /// \brief Reset logging
+ ///
+ /// Resets logging to whatever was set in the call to init().
+ static void reset();
+
+ /// \brief Read local message file
+ ///
+ /// Reads the local message file into the global dictionary, overwriting
+ /// existing messages. If the file contained any message IDs not in the
+ /// dictionary, they are listed in a warning message.
+ ///
+ /// \param file Name of the local message file
+ static void readLocalMessageFile(const char* file);
+
+private:
+ /// \brief Initialize Processing
+ ///
+ /// Initializes the processing of a list of specifications by resetting all
+ /// loggers to their defaults, which is to pass the message to their
+ /// parent logger. (Except for the root logger, where the default action is
+ /// to output the message.)
+ void processInit();
+
+ /// \brief Process Logging Specification
+ ///
+ /// Processes the given specification. It is assumed at this point that
+ /// either the logger does not exist or has been made inactive.
+ void processSpecification(const LoggerSpecification& spec);
+
+ /// \brief End Processing
+ ///
+ /// Place holder for finish processing.
+ /// TODO: Check that the root logger has something enabled
+ void processEnd();
+
+ // Members
+ LoggerManagerImpl* impl_; ///< Pointer to implementation
+};
+
+} // namespace log
+} // namespace isc
+
+
+#endif // __LOGGER_MANAGER_H
diff --git a/src/lib/log/logger_manager_impl.cc b/src/lib/log/logger_manager_impl.cc
new file mode 100644
index 0000000..4a9253a
--- /dev/null
+++ b/src/lib/log/logger_manager_impl.cc
@@ -0,0 +1,236 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <algorithm>
+#include <iostream>
+
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#include <log4cplus/logger.h>
+#include <log4cplus/configurator.h>
+#include <log4cplus/consoleappender.h>
+#include <log4cplus/fileappender.h>
+#include <log4cplus/syslogappender.h>
+
+#include <log/logger.h>
+#include <log/logger_level_impl.h>
+#include <log/logger_manager.h>
+#include <log/logger_manager_impl.h>
+#include <log/log_messages.h>
+#include <log/logger_name.h>
+#include <log/logger_specification.h>
+
+using namespace std;
+
+namespace isc {
+namespace log {
+
+// Reset hierarchy of loggers back to default settings. This removes all
+// appenders from loggers, sets their severity to NOT_SET (so that events are
+// passed back to the parent) and resets the root logger to logging
+// informational messages. (This last is not a log4cplus default, so we have to
+// explicitly reset the logging severity.)
+
+void
+LoggerManagerImpl::processInit() {
+ log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
+ initRootLogger();
+}
+
+// Process logging specification. Set up the common states then dispatch to
+// add output specifications.
+
+void
+LoggerManagerImpl::processSpecification(const LoggerSpecification& spec) {
+
+ log4cplus::Logger logger = log4cplus::Logger::getInstance(
+ expandLoggerName(spec.getName()));
+
+ // Set severity level according to specification entry.
+ logger.setLogLevel(LoggerLevelImpl::convertFromBindLevel(
+ Level(spec.getSeverity(), spec.getDbglevel())));
+
+ // Set the additive flag.
+ logger.setAdditivity(spec.getAdditive());
+
+ // Output options given?
+ if (spec.optionCount() > 0) {
+
+ // Yes, so replace all appenders for this logger.
+ logger.removeAllAppenders();
+
+ // Now process output specifications.
+ for (LoggerSpecification::const_iterator i = spec.begin();
+ i != spec.end(); ++i) {
+ switch (i->destination) {
+ case OutputOption::DEST_CONSOLE:
+ createConsoleAppender(logger, *i);
+ break;
+
+ case OutputOption::DEST_FILE:
+ createFileAppender(logger, *i);
+ break;
+
+#ifndef _WIN32
+ case OutputOption::DEST_SYSLOG:
+ createSyslogAppender(logger, *i);
+ break;
+#endif
+
+ default:
+ // Not a valid destination. As we are in the middle of updating
+ // logging destinations, we could be in the situation where
+ // there are no valid appenders. For this reason, throw an
+ // exception.
+ isc_throw(UnknownLoggingDestination,
+ "Unknown logging destination, code = " <<
+ i->destination);
+ }
+ }
+ }
+}
+
+// Console appender - log to either stdout or stderr.
+void
+LoggerManagerImpl::createConsoleAppender(log4cplus::Logger& logger,
+ const OutputOption& opt)
+{
+ log4cplus::SharedAppenderPtr console(
+ new log4cplus::ConsoleAppender(
+ (opt.stream == OutputOption::STR_STDERR), opt.flush));
+ setConsoleAppenderLayout(console);
+ logger.addAppender(console);
+}
+
+// File appender. Depending on whether a maximum size is given, either
+// a standard file appender or a rolling file appender will be created.
+void
+LoggerManagerImpl::createFileAppender(log4cplus::Logger& logger,
+ const OutputOption& opt)
+{
+ LOG4CPLUS_OPEN_MODE_TYPE mode =
+ LOG4CPLUS_FSTREAM_NAMESPACE::ios::app; // Append to existing file
+
+ log4cplus::SharedAppenderPtr fileapp;
+ if (opt.maxsize == 0) {
+ fileapp = log4cplus::SharedAppenderPtr(new log4cplus::FileAppender(
+ opt.filename, mode, opt.flush));
+ } else {
+ fileapp = log4cplus::SharedAppenderPtr(
+ new log4cplus::RollingFileAppender(opt.filename, opt.maxsize,
+ opt.maxver, opt.flush));
+ }
+
+ // use the same console layout for the files.
+ setConsoleAppenderLayout(fileapp);
+ logger.addAppender(fileapp);
+}
+
+// Syslog appender.
+void
+LoggerManagerImpl::createSyslogAppender(log4cplus::Logger& logger,
+ const OutputOption& opt)
+{
+#ifndef _WIN32
+ log4cplus::SharedAppenderPtr syslogapp(
+ new log4cplus::SysLogAppender(opt.facility));
+ setSyslogAppenderLayout(syslogapp);
+ logger.addAppender(syslogapp);
+#endif
+}
+
+
+// One-time initialization of the log4cplus system
+
+void
+LoggerManagerImpl::init(isc::log::Severity severity, int dbglevel) {
+
+ // Set up basic configurator. This attaches a ConsoleAppender to the
+ // root logger with suitable output. This is used until we we have
+ // actually read the logging configuration, in which case the output
+ // may well be changed.
+ log4cplus::BasicConfigurator config;
+ config.configure();
+
+ // Add the additional debug levels
+ LoggerLevelImpl::init();
+
+ reset(severity, dbglevel);
+}
+
+// Reset logging to default configuration. This closes all appenders
+// and resets the root logger to output INFO messages to the console.
+// It is principally used in testing.
+void
+LoggerManagerImpl::reset(isc::log::Severity severity, int dbglevel) {
+
+ // Initialize the root logger
+ initRootLogger(severity, dbglevel);
+}
+
+// Initialize the root logger
+void LoggerManagerImpl::initRootLogger(isc::log::Severity severity,
+ int dbglevel)
+{
+ log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
+
+ // Set the log4cplus root to not output anything - effectively we are
+ // ignoring it.
+ log4cplus::Logger::getRoot().setLogLevel(log4cplus::OFF_LOG_LEVEL);
+
+ // Set the level for the BIND 10 root logger to the given severity and
+ // debug level.
+ log4cplus::Logger b10root = log4cplus::Logger::getInstance(
+ getRootLoggerName());
+ b10root.setLogLevel(LoggerLevelImpl::convertFromBindLevel(
+ Level(severity, dbglevel)));
+
+ // Set the BIND 10 root to use a console logger.
+ OutputOption opt;
+ createConsoleAppender(b10root, opt);
+}
+
+// Set the the "console" layout for the given appenders. This layout includes
+// a date/time and the name of the logger.
+
+void LoggerManagerImpl::setConsoleAppenderLayout(
+ log4cplus::SharedAppenderPtr& appender)
+{
+ // Create the pattern we want for the output - local time.
+ string pattern = "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c] %m\n";
+
+ // Finally the text of the message
+ auto_ptr<log4cplus::Layout> layout(new log4cplus::PatternLayout(pattern));
+ appender->setLayout(layout);
+}
+
+// Set the the "syslog" layout for the given appenders. This is the same
+// as the console, but without the timestamp (which is expected to be
+// set by syslogd).
+
+void LoggerManagerImpl::setSyslogAppenderLayout(
+ log4cplus::SharedAppenderPtr& appender)
+{
+ // Create the pattern we want for the output - local time.
+ string pattern = "%-5p [%c] %m\n";
+
+ // Finally the text of the message
+ auto_ptr<log4cplus::Layout> layout(new log4cplus::PatternLayout(pattern));
+ appender->setLayout(layout);
+}
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_manager_impl.h b/src/lib/log/logger_manager_impl.h
new file mode 100644
index 0000000..fef47c9
--- /dev/null
+++ b/src/lib/log/logger_manager_impl.h
@@ -0,0 +1,171 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_MANAGER_IMPL_H
+#define __LOGGER_MANAGER_IMPL_H
+
+#include <string>
+
+#include <log4cplus/appender.h>
+#include <log/logger_level.h>
+
+// Forward declaration to avoid need to include log4cplus header file here.
+namespace log4cplus {
+class Logger;
+class Appender;
+}
+
+namespace isc {
+namespace log {
+
+// Forward declarations
+class LoggerSpecification;
+struct OutputOption;
+
+/// \brief Logger Manager Implementation
+///
+/// This is the implementation of the logger manager for the log4cplus
+/// underlying logger.
+///
+/// As noted in logger_manager.h, the logger manager class exists to set up the
+/// logging given a set of specifications. This class handles the processing
+/// of those specifications.
+///
+/// Note: the logging has been implemented using a "pimpl" idiom to conceal
+/// the underlying implementation (log4cplus) from the BIND 10 interface.
+/// This requires that there be an implementation class, even though in this
+/// case, all the implementation class methods can be declared static.
+
+class LoggerManagerImpl {
+public:
+
+ /// \brief Constructor
+ LoggerManagerImpl()
+ {}
+
+ /// \brief Initialize Processing
+ ///
+ /// This resets the hierachy of loggers back to their defaults. This means
+ /// that all non-root loggers (if they exist) are set to NOT_SET, and the
+ /// root logger reset to logging informational messages.
+ ///
+ /// \param root_name BIND 10 name of the root logger
+ static void processInit();
+
+ /// \brief Process Specification
+ ///
+ /// Processes the specification for a single logger.
+ ///
+ /// \param spec Logging specification for this logger
+ static void processSpecification(const LoggerSpecification& spec);
+
+ /// \brief End Processing
+ ///
+ /// Terminates the processing of the logging specifications.
+ static void processEnd()
+ {}
+
+ /// \brief Implementation-specific initialization
+ ///
+ /// Sets the basic configuration for logging (the root logger has INFO and
+ /// more severe messages routed to stdout). Unless this function (or
+ /// process() with a valid specification for all loggers that will log
+ /// messages) is called before a message is logged, log4cplus will output
+ /// a message to stderr noting that logging has not been initialized.
+ ///
+ /// It is assumed here that the name of the BIND 10 root logger can be
+ /// obtained from the global function getRootLoggerName().
+ ///
+ /// \param severity Severity to be associated with this logger
+ /// \param dbglevel Debug level associated with the root logger
+ static void init(isc::log::Severity severity = isc::log::INFO,
+ int dbglevel = 0);
+
+ /// \brief Reset logging
+ ///
+ /// Resets to default configuration (root logger logging to the console
+ /// with INFO severity).
+ ///
+ /// \param severity Severity to be associated with this logger
+ /// \param dbglevel Debug level associated with the root logger
+ static void reset(isc::log::Severity severity = isc::log::INFO,
+ int dbglevel = 0);
+
+private:
+ /// \brief Create console appender
+ ///
+ /// Creates an object that, when attached to a logger, will log to one
+ /// of the output streams (stdout or stderr).
+ ///
+ /// \param logger Log4cplus logger to which the appender must be attached.
+ /// \param opt Output options for this appender.
+ static void createConsoleAppender(log4cplus::Logger& logger,
+ const OutputOption& opt);
+
+ /// \brief Create file appender
+ ///
+ /// Creates an object that, when attached to a logger, will log to a
+ /// specified file. This also includes the ability to "roll" files when
+ /// they reach a specified size.
+ ///
+ /// \param logger Log4cplus logger to which the appender must be attached.
+ /// \param opt Output options for this appender.
+ static void createFileAppender(log4cplus::Logger& logger,
+ const OutputOption& opt);
+
+ /// \brief Create syslog appender
+ ///
+ /// Creates an object that, when attached to a logger, will log to the
+ /// syslog file.
+ ///
+ /// \param logger Log4cplus logger to which the appender must be attached.
+ /// \param opt Output options for this appender.
+ static void createSyslogAppender(log4cplus::Logger& logger,
+ const OutputOption& opt);
+
+ /// \brief Set default layout and severity for root logger
+ ///
+ /// Initializes the root logger to BIND 10 defaults - console output and
+ /// the passed severity/debug level.
+ ///
+ /// \param severity Severity of messages that the logger should output.
+ /// \param dbglevel Debug level if severity = DEBUG
+ static void initRootLogger(isc::log::Severity severity = isc::log::INFO,
+ int dbglevel = 0);
+
+ /// \brief Set layout for console appender
+ ///
+ /// Sets the layout of the specified appender to one suitable for file
+ /// or console output:
+ ///
+ /// YYYY-MM-DD HH:MM:SS.ssss SEVERITY [root.logger] message
+ ///
+ /// \param appender Appender for which this pattern is to be set.
+ static void setConsoleAppenderLayout(log4cplus::SharedAppenderPtr& appender);
+
+ /// \brief Set layout for syslog appender
+ ///
+ /// Sets the layout of the specified appender to one suitable for the
+ /// syslog file:
+ ///
+ /// SEVERITY [root.logger] message
+ ///
+ /// \param appender Appender for which this pattern is to be set.
+ static void setSyslogAppenderLayout(log4cplus::SharedAppenderPtr& appender);
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_MANAGER_IMPL_H
diff --git a/src/lib/log/logger_name.cc b/src/lib/log/logger_name.cc
new file mode 100644
index 0000000..abfcd5e
--- /dev/null
+++ b/src/lib/log/logger_name.cc
@@ -0,0 +1,59 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <string>
+#include "log/logger_name.h"
+
+namespace isc {
+namespace log {
+
+namespace {
+
+// Obtain the root logger name in a way that is safe for statically-initialized
+// objects.
+
+std::string&
+getRootLoggerNameInternal() {
+ static std::string root_name;
+ return (root_name);
+}
+
+} // Anonymous namespace
+
+void
+setRootLoggerName(const std::string& name) {
+ getRootLoggerNameInternal() = name;
+}
+
+const std::string& getRootLoggerName() {
+ return (getRootLoggerNameInternal());
+}
+
+std::string expandLoggerName(const std::string& name) {
+
+ // Are we the root logger, or does the logger name start with
+ // the string "<root_logger_name>.". If so, use a logger
+ // whose name is the one given.
+ if ((name == getRootLoggerName()) ||
+ (name.find(getRootLoggerName() + std::string(".")) == 0)) {
+ return (name);
+
+ }
+
+ // Anything else is assumed to be a sub-logger of the root logger.
+ return (getRootLoggerName() + "." + name);
+}
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_name.h b/src/lib/log/logger_name.h
new file mode 100644
index 0000000..82ea2ad
--- /dev/null
+++ b/src/lib/log/logger_name.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_NAME_H
+#define __LOGGER_NAME_H
+
+#include <string>
+
+/// \brief Define Name of Root Logger
+///
+/// In BIND-10, the name root logger of a program is the name of the program
+/// itself (in contrast to packages such as log4cplus where the root logger name
+// is something like "root"). These trivial functions allow the setting and
+// getting of that name by the logger classes.
+
+namespace isc {
+namespace log {
+
+/// \brief Set root logger name
+///
+/// This function should be called by the program's initialization code before
+/// any logging functions are called.
+///
+/// \param name Name of the root logger. This should be the program name.
+void setRootLoggerName(const std::string& name);
+
+/// \brief Get root logger name
+///
+/// \return Name of the root logger.
+const std::string& getRootLoggerName();
+
+/// \brief Expand logger name
+///
+/// Given a logger name, returns the fully-expanded logger name. If the name
+/// starts with the root logger name, it is returned as-is. Otherwise it is
+/// prefixed with the root logger name.
+///
+/// \param name Name to expand.
+///
+/// \return Fully-expanded logger name.
+std::string expandLoggerName(const std::string& name);
+
+}
+}
+
+#endif // __LOGGER_NAME_H
diff --git a/src/lib/log/logger_specification.h b/src/lib/log/logger_specification.h
new file mode 100644
index 0000000..75c48df
--- /dev/null
+++ b/src/lib/log/logger_specification.h
@@ -0,0 +1,156 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_SPECIFICATION_H
+#define __LOGGER_SPECIFICATION_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <log/logger_level.h>
+#include <log/output_option.h>
+
+/// \brief Logger Specification
+///
+/// The logging configuration options are a list of logger specifications, each
+/// of which represents a logger and the options for its appenders.
+///
+/// Unlike OutputOption (which is a struct), this contains a bit more
+/// structure and is concealed in a class.
+
+#include <vector>
+
+namespace isc {
+namespace log {
+
+class LoggerSpecification {
+public:
+ typedef std::vector<OutputOption>::iterator iterator;
+ typedef std::vector<OutputOption>::const_iterator const_iterator;
+
+ /// \brief Constructor
+ ///
+ /// \param name Name of the logger.
+ /// \param severity Severity at which this logger logs
+ /// \param dbglevel Debug level
+ /// \param additive true to cause message logged with this logger to be
+ /// passed to the parent for logging.
+ LoggerSpecification(const std::string& name = "",
+ isc::log::Severity severity = isc::log::INFO,
+ int dbglevel = 0, bool additive = false) :
+ name_(name), severity_(severity), dbglevel_(dbglevel),
+ additive_(additive)
+ {}
+
+ /// \brief Set the name of the logger.
+ ///
+ /// \param name Name of the logger.
+ void setName(const std::string& name) {
+ name_ = name;
+ }
+
+ /// \return Return logger name.
+ std::string getName() const {
+ return name_;
+ }
+
+ /// \brief Set the severity.
+ ///
+ /// \param severity New severity of the logger.
+ void setSeverity(isc::log::Severity severity) {
+ severity_ = severity;
+ }
+
+ /// \return Return logger severity.
+ isc::log::Severity getSeverity() const {
+ return severity_;
+ }
+
+ /// \brief Set the debug level.
+ ///
+ /// \param dbglevel New debug level of the logger.
+ void setDbglevel(int dbglevel) {
+ dbglevel_ = dbglevel;
+ }
+
+ /// \return Return logger debug level
+ int getDbglevel() const {
+ return dbglevel_;
+ }
+
+ /// \brief Set the additive flag.
+ ///
+ /// \param additive New value of the additive flag.
+ void setAdditive(bool additive) {
+ additive_ = additive;
+ }
+
+ /// \return Return additive flag.
+ bool getAdditive() const {
+ return additive_;
+ }
+
+ /// \brief Add output option.
+ ///
+ /// \param Option to add to the list.
+ void addOutputOption(const OutputOption& option) {
+ options_.push_back(option);
+ }
+
+ /// \return Iterator to start of output options.
+ iterator begin() {
+ return options_.begin();
+ }
+
+ /// \return Iterator to start of output options.
+ const_iterator begin() const {
+ return options_.begin();
+ }
+
+ /// \return Iterator to end of output options.
+ iterator end() {
+ return options_.end();
+ }
+
+ /// \return Iterator to end of output options.
+ const_iterator end() const {
+ return options_.end();
+ }
+
+ /// \return Number of output specification options.
+ size_t optionCount() const {
+ return options_.size();
+ }
+
+ /// \brief Reset back to defaults.
+ void reset() {
+ name_ = "";
+ severity_ = isc::log::INFO;
+ dbglevel_ = 0;
+ additive_ = false;
+ options_.clear();
+ }
+
+private:
+ std::string name_; ///< Logger name
+ isc::log::Severity severity_; ///< Severity for this logger
+ int dbglevel_; ///< Debug level
+ bool additive_; ///< Chaining output
+ std::vector<OutputOption> options_; ///< Logger options
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_SPEC_IFICATIONH
diff --git a/src/lib/log/logger_support.cc b/src/lib/log/logger_support.cc
index f8bf075..2097136 100644
--- a/src/lib/log/logger_support.cc
+++ b/src/lib/log/logger_support.cc
@@ -12,120 +12,42 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE
-/// \brief Temporary Logger Support
-///
-/// Performs run-time initialization of the logger system. In particular, it
-/// is passed information from the command line and:
-///
-/// a) Sets the severity of the messages being logged (and debug level if
-/// appropriate).
-/// b) Reads in the local message file is one has been supplied.
-///
-/// These functions will be replaced once the code has been written to obtain
-/// the logging parameters from the configuration database.
-
-#include <algorithm>
#include <string>
-#include <vector>
-#include <boost/lexical_cast.hpp>
-
-#include <log/logger.h>
#include <log/logger_support.h>
-#include <log/messagedef.h>
-#include <log/message_dictionary.h>
-#include <log/message_exception.h>
-#include <log/message_initializer.h>
-#include <log/message_reader.h>
-#include <log/message_types.h>
-#include <log/root_logger_name.h>
-
-namespace isc {
-namespace log {
+#include <log/logger_manager.h>
using namespace std;
-// Declare a logger for the logging subsystem. This is a sub-logger of the
-// root logger and is used in all functions in this file.
-Logger logger("log");
-
+namespace {
-/// \brief Reads Local Message File
-///
-/// Reads the local message file into the global dictionary, overwriting
-/// existing messages. If the file contained any message IDs not in the
-/// dictionary, they are listed in a warning message.
-///
-/// \param file Name of the local message file
-static void
-readLocalMessageFile(const char* file) {
+// Flag to hold logging initialization state.
+bool logging_init_state = false;
- MessageDictionary& dictionary = MessageDictionary::globalDictionary();
- MessageReader reader(&dictionary);
- try {
- logger.info(MSG_RDLOCMES, file);
- reader.readFile(file, MessageReader::REPLACE);
+} // Anonymous namespace
- // File successfully read, list the duplicates
- MessageReader::MessageIDCollection unknown = reader.getNotAdded();
- for (MessageReader::MessageIDCollection::const_iterator
- i = unknown.begin(); i != unknown.end(); ++i) {
- string message_id = boost::lexical_cast<string>(*i);
- logger.warn(MSG_IDNOTFND, message_id.c_str());
- }
- }
- catch (MessageException& e) {
- MessageID ident = e.id();
- vector<string> args = e.arguments();
- switch (args.size()) {
- case 0:
- logger.error(ident);
- break;
+namespace isc {
+namespace log {
- case 1:
- logger.error(ident, args[0].c_str());
- break;
+// Return initialization state.
+bool
+isLoggingInitialized() {
+ return (logging_init_state);
+}
- default: // 2 or more (2 should be the maximum)
- logger.error(ident, args[0].c_str(), args[1].c_str());
- }
- }
+// Set initialization state. (Note: as logging can be initialized via a direct
+// call to LoggerManager::init(), this function is called from there, not from
+// the initialization functions in this file.
+void
+setLoggingInitialized(bool state) {
+ logging_init_state = state;
}
-/// Logger Run-Time Initialization
+// Logger Run-Time Initialization.
void
initLogger(const string& root, isc::log::Severity severity, int dbglevel,
const char* file) {
-
- // Create the application root logger and set the default severity and
- // debug level. This is the logger that has the name of the application.
- // All other loggers created in this application will be its children.
- setRootLoggerName(root);
- Logger root_logger(isc::log::getRootLoggerName(), true);
-
- // Set the severity associated with it. If no other logger has a severity,
- // this will be the default.
- root_logger.setSeverity(severity, dbglevel);
-
- // Check if there were any duplicate message IDs in the default dictionary
- // and if so, log them. Log using the logging facility root logger.
- vector<string>& duplicates = MessageInitializer::getDuplicates();
- if (!duplicates.empty()) {
-
- // There are - sort and remove any duplicates.
- sort(duplicates.begin(), duplicates.end());
- vector<string>::iterator new_end =
- unique(duplicates.begin(), duplicates.end());
- for (vector<string>::iterator i = duplicates.begin(); i != new_end; ++i) {
- logger.warn(MSG_DUPMSGID, i->c_str());
- }
-
- }
-
- // Replace any messages with local ones (if given)
- if (file) {
- readLocalMessageFile(file);
- }
+ LoggerManager::init(root, severity, dbglevel, file);
}
} // namespace log
diff --git a/src/lib/log/logger_support.h b/src/lib/log/logger_support.h
index 6b5fdec..5805e6f 100644
--- a/src/lib/log/logger_support.h
+++ b/src/lib/log/logger_support.h
@@ -15,13 +15,40 @@
#ifndef __LOGGER_SUPPORT_H
#define __LOGGER_SUPPORT_H
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
#include <string>
#include <log/logger.h>
+#include <log/logger_unittest_support.h>
+
+/// \file
+/// \brief Logging initialization functions
+///
+/// Contains a set of functions relating to logging initialization that are
+/// used by the production code.
namespace isc {
namespace log {
-/// \brief Run-Time Initialization
+/// \brief Is logging initialized?
+///
+/// As some underlying logging implementations can behave unpredictably if they
+/// have not been initialized when a logging function is called, their
+/// initialization state is tracked. The logger functions will check this flag
+/// and throw an exception if logging is not initialized at that point.
+///
+/// \return true if logging has been initialized, false if not
+bool isLoggingInitialized();
+
+/// \brief Set state of "logging initialized" flag
+///
+/// \param state State to set the flag to. (This is expected to be "true" - the
+/// default - for all code apart from specific unit tests.)
+void setLoggingInitialized(bool state = true);
+
+/// \brief Run-time initialization
///
/// Performs run-time initialization of the logger in particular supplying:
///
@@ -36,11 +63,11 @@ namespace log {
/// \param severity Severity at which to log
/// \param dbglevel Debug severity (ignored if "severity" is not "DEBUG")
/// \param file Name of the local message file.
-void initLogger(const std::string& root, isc::log::Severity severity,
- int dbglevel, const char* file);
+void initLogger(const std::string& root,
+ isc::log::Severity severity = isc::log::INFO,
+ int dbglevel = 0, const char* file = NULL);
} // namespace log
} // namespace isc
-
#endif // __LOGGER_SUPPORT_H
diff --git a/src/lib/log/logger_unittest_support.cc b/src/lib/log/logger_unittest_support.cc
new file mode 100644
index 0000000..b7e6fbc
--- /dev/null
+++ b/src/lib/log/logger_unittest_support.cc
@@ -0,0 +1,179 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+
+#include <log/logger_level.h>
+#include <log/logger_name.h>
+#include <log/logger_manager.h>
+#include <log/logger_specification.h>
+#include <log/logger_unittest_support.h>
+#include <log/logger_support.h>
+#include <log/output_option.h>
+
+using namespace std;
+
+namespace isc {
+namespace log {
+
+// Get the logging severity. This is defined by the environment variable
+// B10_LOGGER_SEVERITY, and can be one of "DEBUG", "INFO", "WARN", "ERROR"
+// of "FATAL". (Note that the string must be in upper case with no leading
+// of trailing blanks.) If not present, the default severity passed to the
+// function is returned.
+isc::log::Severity
+b10LoggerSeverity(isc::log::Severity defseverity) {
+ const char* sev_char = getenv("B10_LOGGER_SEVERITY");
+ if (sev_char) {
+ return (isc::log::getSeverity(sev_char));
+ }
+ return (defseverity);
+}
+
+// Get the debug level. This is defined by the envornment variable
+// B10_LOGGER_DBGLEVEL. If not defined, a default value passed to the function
+// is returned.
+int
+b10LoggerDbglevel(int defdbglevel) {
+ const char* dbg_char = getenv("B10_LOGGER_DBGLEVEL");
+ if (dbg_char) {
+ int level = 0;
+ try {
+ level = boost::lexical_cast<int>(dbg_char);
+ if (level < MIN_DEBUG_LEVEL) {
+ std::cerr << "**ERROR** debug level of " << level
+ << " is invalid - a value of " << MIN_DEBUG_LEVEL
+ << " will be used\n";
+ level = MIN_DEBUG_LEVEL;
+ } else if (level > MAX_DEBUG_LEVEL) {
+ std::cerr << "**ERROR** debug level of " << level
+ << " is invalid - a value of " << MAX_DEBUG_LEVEL
+ << " will be used\n";
+ level = MAX_DEBUG_LEVEL;
+ }
+ } catch (...) {
+ // Error, but not fatal to the test
+ std::cerr << "**ERROR** Unable to translate "
+ "B10_LOGGER_DBGLEVEL - a value of 0 will be used\n";
+ }
+ return (level);
+ }
+
+ return (defdbglevel);
+}
+
+
+// Reset characteristics of the root logger to that set by the environment
+// variables B10_LOGGER_SEVERITY, B10_LOGGER_DBGLEVEL and B10_LOGGER_DESTINATION.
+
+void
+resetUnitTestRootLogger() {
+
+ using namespace isc::log;
+
+ // Constants: not declared static as this is function is expected to be
+ // called once only
+#ifdef _WIN32
+ const string DEVNULL = "NUL";
+#else
+ const string DEVNULL = "/dev/null";
+#endif
+ const string STDOUT = "stdout";
+ const string STDERR = "stderr";
+ const string SYSLOG = "syslog";
+ const string SYSLOG_COLON = "syslog:";
+
+ // Get the destination. If not specified, assume /dev/null. (The default
+ // severity for unit tests is DEBUG, which generates a lot of output.
+ // Routing the logging to /dev/null will suppress that, whilst still
+ // ensuring that the code paths are tested.)
+ const char* destination = getenv("B10_LOGGER_DESTINATION");
+ const string dest((destination == NULL) ? DEVNULL : destination);
+
+ // Prepare the objects to define the logging specification
+ LoggerSpecification spec(getRootLoggerName(),
+ b10LoggerSeverity(isc::log::DEBUG),
+ b10LoggerDbglevel(isc::log::MAX_DEBUG_LEVEL));
+ OutputOption option;
+
+ // Set up output option according to destination specification
+ if (dest == STDOUT) {
+ option.destination = OutputOption::DEST_CONSOLE;
+ option.stream = OutputOption::STR_STDOUT;
+
+ } else if (dest == STDERR) {
+ option.destination = OutputOption::DEST_CONSOLE;
+ option.stream = OutputOption::STR_STDERR;
+
+ } else if (dest == SYSLOG) {
+ option.destination = OutputOption::DEST_SYSLOG;
+ // Use default specified in OutputOption constructor for the
+ // syslog destination
+
+ } else if (dest.find(SYSLOG_COLON) == 0) {
+ option.destination = OutputOption::DEST_SYSLOG;
+ // Must take account of the string actually being "syslog:"
+ if (dest == SYSLOG_COLON) {
+ cerr << "**ERROR** value for B10_LOGGER_DESTINATION of " <<
+ SYSLOG_COLON << " is invalid, " << SYSLOG <<
+ " will be used instead\n";
+ // Use default for logging facility
+
+ } else {
+ // Everything else in the string is the facility name
+ option.facility = dest.substr(SYSLOG_COLON.size());
+ }
+
+ } else {
+ // Not a recognised destination, assume a file.
+ option.destination = OutputOption::DEST_FILE;
+ option.filename = dest;
+ }
+
+ // ... and set the destination
+ spec.addOutputOption(option);
+ LoggerManager manager;
+ manager.process(spec);
+}
+
+
+// Logger Run-Time Initialization via Environment Variables
+void initLogger(isc::log::Severity severity, int dbglevel) {
+
+ // Root logger name is defined by the environment variable B10_LOGGER_ROOT.
+ // If not present, the name is "bind10".
+ const char* DEFAULT_ROOT = "bind10";
+ const char* root = getenv("B10_LOGGER_ROOT");
+ if (! root) {
+ root = DEFAULT_ROOT;
+ }
+
+ // Set the local message file
+ const char* localfile = getenv("B10_LOGGER_LOCALMSG");
+
+ // Initialize logging
+ initLogger(root, isc::log::DEBUG, isc::log::MAX_DEBUG_LEVEL, localfile);
+
+ // Now set reset the output destination of the root logger, overriding
+ // the default severity, debug level and destination with those specified
+ // in the environment variables. (The two-step approach is used as the
+ // setUnitTestRootLoggerCharacteristics() function is used in several
+ // places in the BIND 10 tests, and it avoid duplicating code.)
+ resetUnitTestRootLogger();
+}
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_unittest_support.h b/src/lib/log/logger_unittest_support.h
new file mode 100644
index 0000000..ce9121b
--- /dev/null
+++ b/src/lib/log/logger_unittest_support.h
@@ -0,0 +1,126 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_UNITTEST_SUPPORT_H
+#define __LOGGER_UNITTEST_SUPPORT_H
+
+#include <string>
+#include <log/logger.h>
+
+/// \file
+/// \brief Miscellaneous logging functions used by the unit tests.
+///
+/// As the configuration database is unsually unavailable during unit tests,
+/// the functions defined here allow a limited amount of logging configuration
+/// through the use of environment variables
+
+namespace isc {
+namespace log {
+
+/// \brief Run-Time Initialization for Unit Tests from Environment
+///
+/// Performs run-time initialization of the logger via the setting of
+/// environment variables. These are:
+///
+/// - B10_LOGGER_ROOT\n
+/// Name of the root logger. If not given, the string "bind10" will be used.
+///
+/// - B10_LOGGER_SEVERITY\n
+/// Severity of messages that will be logged. This must be one of the strings
+/// "DEBUG", "INFO", "WARN", "ERROR", "FATAL" or "NONE". (Must be upper case
+/// and must not contain leading or trailing spaces.) If not specified (or if
+/// specified but incorrect), the default passed as argument to this function
+/// (currently DEBUG) will be used.
+///
+/// - B10_LOGGER_DBGLEVEL\n
+/// Ignored if the level is not DEBUG, this should be a number between 0 and
+/// 99 indicating the logging severity. The default is 0. If outside these
+/// limits or if not a number, The value passed to this function (default
+/// of MAX_DEBUG_LEVEL) is used.
+///
+/// - B10_LOGGER_LOCALMSG\n
+/// If defined, the path specification of a file that contains message
+/// definitions replacing ones in the default dictionary.
+///
+/// - B10_LOGGER_DESTINATION\n
+/// If defined, the destination of the logging output. This can be one of:
+/// - \c stdout Send output to stdout.
+/// - \c stderr Send output to stderr
+/// - \c syslog Send output to syslog using the facility local0.
+/// - \c syslog:xxx Send output to syslog, using the facility xxx. ("xxx"
+/// should be one of the syslog facilities such as "local0".) There must
+/// be a colon between "syslog" and "xxx
+/// - \c other Anything else is interpreted as the name of a file to which
+/// output is appended. If the file does not exist, it is created.
+///
+/// Any errors in the settings cause messages to be output to stderr.
+///
+/// This function is aimed at test programs, allowing the default settings to
+/// be overridden by the tester. It is not intended for use in production
+/// code.
+///
+/// TODO: Rename. This function overloads the initLogger() function that can
+/// be used to initialize production programs. This may lead to confusion.
+void initLogger(isc::log::Severity severity = isc::log::DEBUG,
+ int dbglevel = isc::log::MAX_DEBUG_LEVEL);
+
+
+/// \brief Obtains logging severity from B10_LOGGER_SEVERITY
+///
+/// Support function called by the unit test logging initialization code.
+/// It returns the logging severity defined by B10_LOGGER_SEVERITY. If
+/// not defined it returns the default passed to it.
+///
+/// \param defseverity Default severity used if B10_LOGGER_SEVERITY is not
+// defined.
+///
+/// \return Severity to use for the logging.
+isc::log::Severity b10LoggerSeverity(isc::log::Severity defseverity);
+
+
+/// \brief Obtains logging debug level from B10_LOGGER_DBGLEVEL
+///
+/// Support function called by the unit test logging initialization code.
+/// It returns the logging debug level defined by B10_LOGGER_DBGLEVEL. If
+/// not defined, it returns the default passed to it.
+///
+/// N.B. If there is an error, a message is written to stderr and a value
+/// related to the error is used. (This is because (a) logging is not yet
+/// initialized, hence only the error stream is known to exist, and (b) this
+/// function is only used in unit test logging initialization, so incorrect
+/// selection of a level is not really an issue.)
+///
+/// \param defdbglevel Default debug level to be used if B10_LOGGER_DBGLEVEL
+/// is not defined.
+///
+/// \return Debug level to use.
+int b10LoggerDbglevel(int defdbglevel);
+
+
+/// \brief Reset root logger characteristics
+///
+/// This is a simplified interface into the resetting of the characteristics
+/// of the root logger. It is aimed for use in unit tests and resets the
+/// characteristics of the root logger to use a severity, debug level and
+/// destination set by the environment variables B10_LOGGER_SEVERITY,
+/// B10_LOGGER_DBGLEVEL and B10_LOGGER_DESTINATION.
+void
+resetUnitTestRootLogger();
+
+} // namespace log
+} // namespace isc
+
+
+
+#endif // __LOGGER_UNITTEST_SUPPORT_H
diff --git a/src/lib/log/logimpl_messages.cc b/src/lib/log/logimpl_messages.cc
new file mode 100644
index 0000000..ca8552e
--- /dev/null
+++ b/src/lib/log/logimpl_messages.cc
@@ -0,0 +1,29 @@
+// File created from logimpl_messages.mes on Wed Jun 22 10:57:02 2011
+
+#include <cstddef>
+#include <log/message_types.h>
+#include <log/message_initializer.h>
+
+namespace isc {
+namespace log {
+
+extern const isc::log::MessageID LOGIMPL_ABOVE_MAX_DEBUG = "LOGIMPL_ABOVE_MAX_DEBUG";
+extern const isc::log::MessageID LOGIMPL_BAD_DEBUG_STRING = "LOGIMPL_BAD_DEBUG_STRING";
+extern const isc::log::MessageID LOGIMPL_BELOW_MIN_DEBUG = "LOGIMPL_BELOW_MIN_DEBUG";
+
+} // namespace log
+} // namespace isc
+
+namespace {
+
+const char* values[] = {
+ "LOGIMPL_ABOVE_MAX_DEBUG", "debug level of %1 is too high and will be set to the maximum of %2",
+ "LOGIMPL_BAD_DEBUG_STRING", "debug string '%1' has invalid format",
+ "LOGIMPL_BELOW_MIN_DEBUG", "debug level of %1 is too low and will be set to the minimum of %2",
+ NULL
+};
+
+const isc::log::MessageInitializer initializer(values);
+
+} // Anonymous namespace
+
diff --git a/src/lib/log/logimpl_messages.h b/src/lib/log/logimpl_messages.h
new file mode 100644
index 0000000..1b94838
--- /dev/null
+++ b/src/lib/log/logimpl_messages.h
@@ -0,0 +1,18 @@
+// File created from logimpl_messages.mes on Wed Jun 22 10:57:02 2011
+
+#ifndef __LOGIMPL_MESSAGES_H
+#define __LOGIMPL_MESSAGES_H
+
+#include <log/message_types.h>
+
+namespace isc {
+namespace log {
+
+extern const isc::log::MessageID LOGIMPL_ABOVE_MAX_DEBUG;
+extern const isc::log::MessageID LOGIMPL_BAD_DEBUG_STRING;
+extern const isc::log::MessageID LOGIMPL_BELOW_MIN_DEBUG;
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGIMPL_MESSAGES_H
diff --git a/src/lib/log/logimpl_messages.mes b/src/lib/log/logimpl_messages.mes
new file mode 100644
index 0000000..c40f80c
--- /dev/null
+++ b/src/lib/log/logimpl_messages.mes
@@ -0,0 +1,43 @@
+# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# \brief Logger Implementation Messages
+#
+# This holds messages generated by the underlying logger implementation. They
+# are likely to be specific to that implementation, and may well change if the
+# underlying implementation is changed. For that reason, they have been put
+# in a separate file.
+
+$NAMESPACE isc::log
+
+% LOGIMPL_ABOVE_MAX_DEBUG debug level of %1 is too high and will be set to the maximum of %2
+A message from the interface to the underlying logger implementation reporting
+that the debug level (as set by an internally-created string DEBUGn, where n
+is an integer, e.g. DEBUG22) is above the maximum allowed value and has
+been reduced to that value. The appearance of this message may indicate
+a programming error - please submit a bug report.
+
+% LOGIMPL_BAD_DEBUG_STRING debug string '%1' has invalid format
+A message from the interface to the underlying logger implementation
+reporting that an internally-created string used to set the debug level
+is not of the correct format (it should be of the form DEBUGn, where n
+is an integer, e.g. DEBUG22). The appearance of this message indicates
+a programming error - please submit a bug report.
+
+% LOGIMPL_BELOW_MIN_DEBUG debug level of %1 is too low and will be set to the minimum of %2
+A message from the interface to the underlying logger implementation reporting
+that the debug level (as set by an internally-created string DEBUGn, where n
+is an integer, e.g. DEBUG22) is below the minimum allowed value and has
+been increased to that value. The appearance of this message may indicate
+a programming error - please submit a bug report.
diff --git a/src/lib/log/macros.h b/src/lib/log/macros.h
new file mode 100644
index 0000000..3128131
--- /dev/null
+++ b/src/lib/log/macros.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOG_MACROS_H
+#define __LOG_MACROS_H
+
+#include <log/logger.h>
+
+/// \brief Macro to conveniently test debug output and log it
+#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE) \
+ if (!(LOGGER).isDebugEnabled((LEVEL))) { \
+ } else \
+ (LOGGER).debug((LEVEL), (MESSAGE))
+
+/// \brief Macro to conveniently test info output and log it
+#define LOG_INFO(LOGGER, MESSAGE) \
+ if (!(LOGGER).isInfoEnabled()) { \
+ } else \
+ (LOGGER).info((MESSAGE))
+
+/// \brief Macro to conveniently test warn output and log it
+#define LOG_WARN(LOGGER, MESSAGE) \
+ if (!(LOGGER).isWarnEnabled()) { \
+ } else \
+ (LOGGER).warn((MESSAGE))
+
+/// \brief Macro to conveniently test error output and log it
+#define LOG_ERROR(LOGGER, MESSAGE) \
+ if (!(LOGGER).isErrorEnabled()) { \
+ } else \
+ (LOGGER).error((MESSAGE))
+
+/// \brief Macro to conveniently test fatal output and log it
+#define LOG_FATAL(LOGGER, MESSAGE) \
+ if (!(LOGGER).isFatalEnabled()) { \
+ } else \
+ (LOGGER).fatal((MESSAGE))
+
+#endif
diff --git a/src/lib/log/message_exception.cc b/src/lib/log/message_exception.cc
deleted file mode 100644
index 1a69ca5..0000000
--- a/src/lib/log/message_exception.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-/// \brief Body of Virtual Destructor
-
-#include <log/message_exception.h>
-
-namespace isc {
-namespace log {
-
-MessageException::~MessageException() throw() {
-}
-
-} // namespace log
-} // namespace isc
diff --git a/src/lib/log/message_exception.h b/src/lib/log/message_exception.h
index 30c6618..eebee89 100644
--- a/src/lib/log/message_exception.h
+++ b/src/lib/log/message_exception.h
@@ -19,6 +19,7 @@
#include <string>
#include <vector>
+#include <boost/lexical_cast.hpp>
#include <log/message_types.h>
namespace isc {
@@ -35,33 +36,47 @@ public:
/// \brief Constructor
///
- /// \param id Message identification
- MessageException(MessageID id) : id_(id)
- {}
+ /// \param id Message identification.
+ /// \param lineno Line number on which error occurred (if > 0).
+ MessageException(MessageID id, int lineno = 0) : id_(id)
+ {
+ if (lineno > 0) {
+ args_.push_back(boost::lexical_cast<std::string>(lineno));
+ }
+ }
/// \brief Constructor
///
- /// \param id Message identification
- /// \param arg1 First message argument
- MessageException(MessageID id, const std::string& arg1) : id_(id)
+ /// \param id Message identification.
+ /// \param arg1 First message argument.
+ /// \param lineno Line number on which error occurred (if > 0).
+ MessageException(MessageID id, const std::string& arg1, int lineno = 0)
+ : id_(id)
{
+ if (lineno > 0) {
+ args_.push_back(boost::lexical_cast<std::string>(lineno));
+ }
args_.push_back(arg1);
}
/// \brief Constructor
///
- /// \param id Message identification
- /// \param arg1 First message argument
- /// \param arg2 Second message argument
+ /// \param id Message identification.
+ /// \param arg1 First message argument.
+ /// \param arg2 Second message argument.
+ /// \param lineno Line number on which error occurred (if > 0).
MessageException(MessageID id, const std::string& arg1,
- const std::string& arg2) : id_(id)
+ const std::string& arg2, int lineno = 0) : id_(id)
{
+ if (lineno > 0) {
+ args_.push_back(boost::lexical_cast<std::string>(lineno));
+ }
args_.push_back(arg1);
args_.push_back(arg2);
}
/// \brief Destructor
- virtual ~MessageException() throw();
+ ~MessageException() throw() {}
/// \brief Return Message ID
///
diff --git a/src/lib/log/message_reader.cc b/src/lib/log/message_reader.cc
index 7281346..2710ab8 100644
--- a/src/lib/log/message_reader.cc
+++ b/src/lib/log/message_reader.cc
@@ -12,58 +12,65 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <cassert>
#include <errno.h>
#include <string.h>
+#include <iostream>
#include <iostream>
#include <fstream>
+#include <log/log_messages.h>
#include <log/message_exception.h>
-#include <log/messagedef.h>
#include <log/message_reader.h>
#include <util/strutil.h>
using namespace std;
-namespace isc {
-namespace log {
-
-// Virtual destructor.
-MessageReader::~MessageReader() {
+namespace {
+const char DIRECTIVE_FLAG = '$'; // Starts each directive
+const char MESSAGE_FLAG = '%'; // Starts each message
}
+namespace isc {
+namespace log {
+
// Read the file.
void
MessageReader::readFile(const string& file, MessageReader::Mode mode) {
- // Ensure the non-added collection is empty: this object might be
- // being reused.
+ // Ensure the non-added collection is empty: we could be re-using this
+ // object.
not_added_.clear();
- // Open the file
+ // Open the file.
ifstream infile(file.c_str());
if (infile.fail()) {
- throw MessageException(MSG_OPNMSGIN, file, strerror(errno));
+ throw MessageException(LOG_INPUT_OPEN_FAIL, file, strerror(errno));
}
- // Loop round reading it.
+ // Loop round reading it. As we process the file one line at a time,
+ // keep a track of line number of aid diagnosis of problems.
string line;
getline(infile, line);
+ lineno_ = 0;
+
while (infile.good()) {
+ ++lineno_;
processLine(line, mode);
getline(infile, line);
}
// Why did the loop terminate?
if (!infile.eof()) {
- throw MessageException(MSG_MSGRDERR, file, strerror(errno));
+ throw MessageException(LOG_READ_ERROR, file, strerror(errno));
}
infile.close();
}
-// Parse a line of the file
+// Parse a line of the file.
void
MessageReader::processLine(const string& line, MessageReader::Mode mode) {
@@ -74,15 +81,16 @@ MessageReader::processLine(const string& line, MessageReader::Mode mode) {
if (text.empty()) {
; // Ignore blank lines
- } else if ((text[0] == '#') || (text[0] == '+')) {
- ; // Ignore comments or descriptions
-
- } else if (text[0] == '$') {
+ } else if (text[0] == DIRECTIVE_FLAG) {
parseDirective(text); // Process directives
- } else {
- parseMessage(text, mode); // Process other lines
+ } else if (text[0] == MESSAGE_FLAG) {
+ parseMessage(text, mode); // Process message definition line
+
+ } else {
+ ; // Other lines are extended message
+ // description so are ignored
}
}
@@ -99,130 +107,162 @@ MessageReader::parseDirective(const std::string& text) {
isc::util::str::uppercase(tokens[0]);
if (tokens[0] == string("$PREFIX")) {
parsePrefix(tokens);
+
} else if (tokens[0] == string("$NAMESPACE")) {
parseNamespace(tokens);
+
} else {
- throw MessageException(MSG_UNRECDIR, tokens[0]);
+
+ // Unrecognised directive
+ throw MessageException(LOG_UNRECOGNISED_DIRECTIVE, tokens[0], lineno_);
}
}
// Process $PREFIX
-
void
MessageReader::parsePrefix(const vector<string>& tokens) {
- // Check argument count
-
- static string valid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
- if (tokens.size() < 2) {
- throw MessageException(MSG_PRFNOARG);
- } else if (tokens.size() > 2) {
- throw MessageException(MSG_PRFEXTRARG);
-
- }
+ // Should not get here unless there is something in the tokens array.
+ assert(tokens.size() > 0);
- // As a style, we are going to have the symbols in uppercase
- string prefix = tokens[1];
- isc::util::str::uppercase(prefix);
+ // Process $PREFIX. With no arguments, the prefix is set to the empty
+ // string. One argument sets the prefix to the to its value and more than
+ // one argument is invalid.
+ if (tokens.size() == 1) {
+ prefix_ = "";
- // Token is potentially valid providing it only contains alphabetic
- // and numeric characters (and underscores) and does not start with a
- // digit.
- if ((prefix.find_first_not_of(valid) != string::npos) ||
- (std::isdigit(prefix[0]))) {
+ } else if (tokens.size() == 2) {
+ prefix_ = tokens[1];
- // Invalid character in string or it starts with a digit.
- throw MessageException(MSG_PRFINVARG, tokens[1]);
- }
+ // Token is potentially valid providing it only contains alphabetic
+ // and numeric characters (and underscores) and does not start with a
+ // digit.
+ if (invalidSymbol(prefix_)) {
+ throw MessageException(LOG_PREFIX_INVALID_ARG, prefix_, lineno_);
+ }
- // All OK - unless the prefix has already been set.
+ } else {
- if (prefix_.size() != 0) {
- throw MessageException(MSG_DUPLPRFX);
+ // Too many arguments
+ throw MessageException(LOG_PREFIX_EXTRA_ARGS, lineno_);
}
+}
- // Prefix has not been set, so set it and return success.
-
- prefix_ = prefix;
+// Check if string is an invalid C++ symbol. It is valid if comprises only
+// alphanumeric characters and underscores, and does not start with a digit.
+// (Owing to the logic of the rest of the code, we check for its invalidity,
+// not its validity.)
+bool
+MessageReader::invalidSymbol(const string& symbol) {
+ static const string valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789_";
+ return ( symbol.empty() ||
+ (symbol.find_first_not_of(valid_chars) != string::npos) ||
+ (std::isdigit(symbol[0])));
}
// Process $NAMESPACE. A lot of the processing is similar to that of $PREFIX,
// except that only limited checks will be done on the namespace (to avoid a
-// lot of parsing and separating out of the namespace components.)
+// lot of parsing and separating out of the namespace components.) Also, unlike
+// $PREFIX, there can only be one $NAMESPACE in a file.
void
MessageReader::parseNamespace(const vector<string>& tokens) {
// Check argument count
-
- static string valid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:"
- "abcdefghijklmnopqrstuvwxyz";
-
if (tokens.size() < 2) {
- throw MessageException(MSG_NSNOARG);
+ throw MessageException(LOG_NAMESPACE_NO_ARGS, lineno_);
} else if (tokens.size() > 2) {
- throw MessageException(MSG_NSEXTRARG);
+ throw MessageException(LOG_NAMESPACE_EXTRA_ARGS, lineno_);
}
// Token is potentially valid providing it only contains alphabetic
- // and numeric characters (and underscores and colons).
- if (tokens[1].find_first_not_of(valid) != string::npos) {
-
- // Invalid character in string or it starts with a digit.
- throw MessageException(MSG_NSINVARG, tokens[1]);
+ // and numeric characters (and underscores and colons). As noted above,
+ // we won't be exhaustive - after all, and code containing the resultant
+ // namespace will have to be compiled, and the compiler will catch errors.
+ static const string valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789_:";
+ if (tokens[1].find_first_not_of(valid_chars) != string::npos) {
+ throw MessageException(LOG_NAMESPACE_INVALID_ARG, tokens[1], lineno_);
}
// All OK - unless the namespace has already been set.
if (ns_.size() != 0) {
- throw MessageException(MSG_DUPLNS);
+ throw MessageException(LOG_DUPLICATE_NAMESPACE, lineno_);
}
// Prefix has not been set, so set it and return success.
-
ns_ = tokens[1];
}
// Process message. By the time this method is called, the line has been
-// stripped of leading and trailing spaces, and we believe that it is a line
-// defining a message. The first token on the line is converted to uppercase
-// and becomes the message ID; the rest of the line is the message text.
+// stripped of leading and trailing spaces. The first character of the string
+// is the message introducer, so we can get rid of that. The remainder is
+// a line defining a message.
+//
+// The first token on the line, when concatenated to the prefix and converted to
+// upper-case, is the message ID. The first of the line from the next token
+// on is the message text.
void
MessageReader::parseMessage(const std::string& text, MessageReader::Mode mode) {
static string delimiters("\t\n "); // Delimiters
+ // The line passed should be at least one character long and start with the
+ // message introducer (else we should not have got here).
+ assert((text.size() >= 1) && (text[0] == MESSAGE_FLAG));
+
+ // A line comprising just the message introducer is not valid.
+ if (text.size() == 1) {
+ throw MessageException(LOG_NO_MESSAGE_ID, text, lineno_);
+ }
+
+ // Strip off the introducer and any leading space after that.
+ string message_line = isc::util::str::trim(text.substr(1));
+
// Look for the first delimiter.
- size_t first_delim = text.find_first_of(delimiters);
+ size_t first_delim = message_line.find_first_of(delimiters);
if (first_delim == string::npos) {
// Just a single token in the line - this is not valid
- throw MessageException(MSG_NOMSGTXT, text);
+ throw MessageException(LOG_NO_MESSAGE_TEXT, message_line, lineno_);
}
- // Extract the first token into the message ID
- string ident = text.substr(0, first_delim);
+ // Extract the first token into the message ID, preceding it with the
+ // current prefix, then convert to upper-case. If the prefix is not set,
+ // perform the valid character check now - the string will become a C++
+ // symbol so we may as well identify problems early.
+ string ident = prefix_ + message_line.substr(0, first_delim);
+ if (prefix_.empty()) {
+ if (invalidSymbol(ident)) {
+ throw MessageException(LOG_INVALID_MESSAGE_ID, ident, lineno_);
+ }
+ }
+ isc::util::str::uppercase(ident);
// Locate the start of the message text
- size_t first_text = text.find_first_not_of(delimiters, first_delim);
+ size_t first_text = message_line.find_first_not_of(delimiters, first_delim);
if (first_text == string::npos) {
// ?? This happens if there are trailing delimiters, which should not
// occur as we have stripped trailing spaces off the line. Just treat
// this as a single-token error for simplicity's sake.
- throw MessageException(MSG_NOMSGTXT, text);
+ throw MessageException(LOG_NO_MESSAGE_TEXT, message_line, lineno_);
}
// Add the result to the dictionary and to the non-added list if the add to
// the dictionary fails.
bool added;
if (mode == ADD) {
- added = dictionary_->add(ident, text.substr(first_text));
+ added = dictionary_->add(ident, message_line.substr(first_text));
}
else {
- added = dictionary_->replace(ident, text.substr(first_text));
+ added = dictionary_->replace(ident, message_line.substr(first_text));
}
if (!added) {
not_added_.push_back(ident);
diff --git a/src/lib/log/message_reader.h b/src/lib/log/message_reader.h
index d07c7f2..eded9c6 100644
--- a/src/lib/log/message_reader.h
+++ b/src/lib/log/message_reader.h
@@ -64,10 +64,9 @@ public:
dictionary_(dictionary)
{}
-
/// \brief Virtual Destructor
- virtual ~MessageReader();
-
+ virtual ~MessageReader()
+ {}
/// \brief Get Dictionary
///
@@ -188,10 +187,24 @@ private:
/// \param tokens $NAMESPACE line split into tokens
void parseNamespace(const std::vector<std::string>& tokens);
+ /// \brief Check for invalid C++ symbol name
+ ///
+ /// The message ID (or concatenation of prefix and message ID) will be used
+ /// as the name of a symbol in C++ code. This function checks if the name
+ /// is invalid (contains anything other than alphanumeric characters or
+ /// underscores, or starts with a digit).
+ ///
+ /// \param symbol name to check to see if it is an invalid C++ symbol.
+ ///
+ /// \return true if the name is invalid, false if it is valid.
+ bool invalidSymbol(const std::string& symbol);
+
+
/// Attributes
MessageDictionary* dictionary_; ///< Dictionary to add messages to
MessageIDCollection not_added_; ///< List of IDs not added
+ int lineno_; ///< Number of last line read
std::string prefix_; ///< Argument of $PREFIX statement
std::string ns_; ///< Argument of $NAMESPACE statement
};
diff --git a/src/lib/log/messagedef.cc b/src/lib/log/messagedef.cc
deleted file mode 100644
index f680a74..0000000
--- a/src/lib/log/messagedef.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// File created from messagedef.mes on Mon Feb 14 11:07:45 2011
-
-#include <cstddef>
-#include <log/message_types.h>
-#include <log/message_initializer.h>
-
-namespace isc {
-namespace log {
-
-extern const isc::log::MessageID MSG_DUPLNS = "DUPLNS";
-extern const isc::log::MessageID MSG_DUPLPRFX = "DUPLPRFX";
-extern const isc::log::MessageID MSG_DUPMSGID = "DUPMSGID";
-extern const isc::log::MessageID MSG_IDNOTFND = "IDNOTFND";
-extern const isc::log::MessageID MSG_MSGRDERR = "MSGRDERR";
-extern const isc::log::MessageID MSG_MSGWRTERR = "MSGWRTERR";
-extern const isc::log::MessageID MSG_NOMSGTXT = "NOMSGTXT";
-extern const isc::log::MessageID MSG_NSEXTRARG = "NSEXTRARG";
-extern const isc::log::MessageID MSG_NSINVARG = "NSINVARG";
-extern const isc::log::MessageID MSG_NSNOARG = "NSNOARG";
-extern const isc::log::MessageID MSG_OPNMSGIN = "OPNMSGIN";
-extern const isc::log::MessageID MSG_OPNMSGOUT = "OPNMSGOUT";
-extern const isc::log::MessageID MSG_PRFEXTRARG = "PRFEXTRARG";
-extern const isc::log::MessageID MSG_PRFINVARG = "PRFINVARG";
-extern const isc::log::MessageID MSG_PRFNOARG = "PRFNOARG";
-extern const isc::log::MessageID MSG_RDLOCMES = "RDLOCMES";
-extern const isc::log::MessageID MSG_UNRECDIR = "UNRECDIR";
-
-} // namespace log
-} // namespace isc
-
-namespace {
-
-const char* values[] = {
- "DUPLNS", "duplicate $NAMESPACE directive found",
- "DUPLPRFX", "duplicate $PREFIX directive found",
- "DUPMSGID", "duplicate message ID (%s) in compiled code",
- "IDNOTFND", "could not replace message for '%s': no such message identification",
- "MSGRDERR", "error reading from message file %s: %s",
- "MSGWRTERR", "error writing to %s: %s",
- "NOMSGTXT", "a line containing a message ID ('%s') and nothing else was found",
- "NSEXTRARG", "$NAMESPACE directive has too many arguments",
- "NSINVARG", "$NAMESPACE directive has an invalid argument ('%s')",
- "NSNOARG", "no arguments were given to the $NAMESPACE directive",
- "OPNMSGIN", "unable to open message file %s for input: %s",
- "OPNMSGOUT", "unable to open %s for output: %s",
- "PRFEXTRARG", "$PREFIX directive has too many arguments",
- "PRFINVARG", "$PREFIX directive has an invalid argument ('%s')",
- "PRFNOARG", "no arguments were given to the $PREFIX directive",
- "RDLOCMES", "reading local message file %s",
- "UNRECDIR", "unrecognised directive '%s'",
- NULL
-};
-
-const isc::log::MessageInitializer initializer(values);
-
-} // Anonymous namespace
-
diff --git a/src/lib/log/messagedef.h b/src/lib/log/messagedef.h
deleted file mode 100644
index eb8f4ea..0000000
--- a/src/lib/log/messagedef.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// File created from messagedef.mes on Mon Feb 14 11:07:45 2011
-
-#ifndef __MESSAGEDEF_H
-#define __MESSAGEDEF_H
-
-#include <log/message_types.h>
-
-namespace isc {
-namespace log {
-
-extern const isc::log::MessageID MSG_DUPLNS;
-extern const isc::log::MessageID MSG_DUPLPRFX;
-extern const isc::log::MessageID MSG_DUPMSGID;
-extern const isc::log::MessageID MSG_IDNOTFND;
-extern const isc::log::MessageID MSG_MSGRDERR;
-extern const isc::log::MessageID MSG_MSGWRTERR;
-extern const isc::log::MessageID MSG_NOMSGTXT;
-extern const isc::log::MessageID MSG_NSEXTRARG;
-extern const isc::log::MessageID MSG_NSINVARG;
-extern const isc::log::MessageID MSG_NSNOARG;
-extern const isc::log::MessageID MSG_OPNMSGIN;
-extern const isc::log::MessageID MSG_OPNMSGOUT;
-extern const isc::log::MessageID MSG_PRFEXTRARG;
-extern const isc::log::MessageID MSG_PRFINVARG;
-extern const isc::log::MessageID MSG_PRFNOARG;
-extern const isc::log::MessageID MSG_RDLOCMES;
-extern const isc::log::MessageID MSG_UNRECDIR;
-
-} // namespace log
-} // namespace isc
-
-#endif // __MESSAGEDEF_H
diff --git a/src/lib/log/messagedef.mes b/src/lib/log/messagedef.mes
deleted file mode 100644
index 3599388..0000000
--- a/src/lib/log/messagedef.mes
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-$PREFIX MSG_
-$NAMESPACE isc::log
-
-# \brief Message Utility Message File
-#
-# This is the source of the set of messages generated by the message and logging
-# components. The associated .h and .cc files are created by hand from this
-# file though and are not built during the build process; this is to avoid the
-# chicken-and-egg situation where we need the files to build the message
-# compiler, yet we need the compiler to build the files.
-
-DUPMSGID duplicate message ID (%s) in compiled code
-+ Indicative of a programming error, when it started up, BIND10 detected that
-+ the given message ID had been registered by one or more modules. (All message
-+ IDs should be unique throughout BIND10.) This has no impact on the operation
-+ of the server other that erroneous messages may be logged. (When BIND10 loads
-+ the message IDs (and their associated text), if a duplicate ID is found it is
-+ discarded. However, when the module that supplied the duplicate ID logs that
-+ particular message, the text supplied by the module that added the original
-+ ID will be output - something that may bear no relation to the condition being
-+ logged.
-
-DUPLNS duplicate $NAMESPACE directive found
-+ When reading a message file, more than one $NAMESPACE directive was found. In
-+ this version of the code, such a condition is regarded as an error and the
-+ read will be abandoned.
-
-DUPLPRFX duplicate $PREFIX directive found
-+ When reading a message file, more than one $PREFIX directive was found. In
-+ this version of the code, such a condition is regarded as an error and the
-+ read will be abandoned.
-
-IDNOTFND could not replace message for '%s': no such message identification
-+ During start-up a local message file was read. A line with the listed
-+ message identification was found in the file, but the identification is not
-+ one contained in the compiled-in message dictionary. Either the message
-+ identification has been mis-spelled in the file, or the local file was used
-+ for an earlier version of the software and the message with that
-+ identification has been removed.
-+
-+ This message may appear a number of times in the file, once for every such
-+ unknown message identification.
-
-MSGRDERR error reading from message file %s: %s
-+ The specified error was encountered reading from the named message file.
-
-MSGWRTERR error writing to %s: %s
-+ The specified error was encountered by the message compiler when writing to
-+ the named output file.
-
-NSEXTRARG $NAMESPACE directive has too many arguments
-+ The $NAMESPACE directive takes a single argument, a namespace in which all the
-+ generated symbol names are placed. This error is generated when the
-+ compiler finds a $NAMESPACE directive with more than one argument.
-
-NSINVARG $NAMESPACE directive has an invalid argument ('%s')
-+ The $NAMESPACE argument should be a valid C++ namespace. The reader does a
-+ cursory check on its validity, checking that the characters in the namespace
-+ are correct. The error is generated when the reader finds an invalid
-+ character. (Valid are alphanumeric characters, underscores and colons.)
-
-NOMSGTXT a line containing a message ID ('%s') and nothing else was found
-+ Message definitions comprise lines starting with a message identification (a
-+ symbolic name for the message) and followed by the text of the message. This
-+ error is generated when a line is found in the message file that contains just
-+ the message identification and no text.
-
-NSNOARG no arguments were given to the $NAMESPACE directive
-+ The $NAMESPACE directive takes a single argument, a namespace in which all the
-+ generated symbol names are placed. This error is generated when the
-+ compiler finds a $NAMESPACE directive with no arguments.
-
-OPNMSGIN unable to open message file %s for input: %s
-+ The program was not able to open the specified input message file for the
-+ reason given.
-
-OPNMSGOUT unable to open %s for output: %s
-+ The program was not able to open the specified output file for the reason
-+ given.
-
-PRFEXTRARG $PREFIX directive has too many arguments
-+ The $PREFIX directive takes a single argument, a prefix to be added to the
-+ symbol names when a C++ .h file is created. This error is generated when the
-+ compiler finds a $PREFIX directive with more than one argument.
-
-PRFINVARG $PREFIX directive has an invalid argument ('%s')
-+ The $PREFIX argument is used in a symbol name in a C++ header file. As such,
-+ it must adhere to restrictions on C++ symbol names (e.g. may only contain
-+ alphanumeric characters or underscores, and may nor start with a digit). A
-+ $PREFIX directive was found with an argument (given in the message) that
-+ violates those restictions.
-
-PRFNOARG no arguments were given to the $PREFIX directive
-+ The $PREFIX directive takes a single argument, a prefix to be added to the
-+ symbol names when a C++ .h file is created. This error is generated when the
-+ compiler finds a $PREFIX directive with no arguments.
-
-RDLOCMES reading local message file %s
-+ This is an informational message output by BIND10 when it starts to read a
-+ local message file. (A local message file may replace the text of one of more
-+ messages; the ID of the message will not be changed though.)
-
-UNRECDIR unrecognised directive '%s'
-+ A line starting with a dollar symbol was found, but the first word on the line
-+ (shown in the message) was not a recognised message compiler directive.
diff --git a/src/lib/log/output_option.cc b/src/lib/log/output_option.cc
new file mode 100644
index 0000000..f56efb9
--- /dev/null
+++ b/src/lib/log/output_option.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <string>
+
+#include <boost/algorithm/string.hpp>
+
+#include <log/log_messages.h>
+#include <log/macros.h>
+#include <log/output_option.h>
+
+namespace isc {
+namespace log {
+
+OutputOption::Destination
+getDestination(const std::string& dest_str) {
+ if (boost::iequals(dest_str, "console")) {
+ return OutputOption::DEST_CONSOLE;
+ } else if (boost::iequals(dest_str, "file")) {
+ return OutputOption::DEST_FILE;
+ } else if (boost::iequals(dest_str, "syslog")) {
+ return OutputOption::DEST_SYSLOG;
+ } else {
+ Logger logger("log");
+ LOG_ERROR(logger, LOG_BAD_DESTINATION).arg(dest_str);
+ return OutputOption::DEST_CONSOLE;
+ }
+}
+
+OutputOption::Stream
+getStream(const std::string& stream_str) {
+ if (boost::iequals(stream_str, "stderr")) {
+ return OutputOption::STR_STDERR;
+ } else if (boost::iequals(stream_str, "stdout")) {
+ return OutputOption::STR_STDOUT;
+ } else {
+ Logger logger("log");
+ LOG_ERROR(logger, LOG_BAD_STREAM).arg(stream_str);
+ return OutputOption::STR_STDOUT;
+ }
+}
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/output_option.h b/src/lib/log/output_option.h
new file mode 100644
index 0000000..cbb7e95
--- /dev/null
+++ b/src/lib/log/output_option.h
@@ -0,0 +1,85 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __OUTPUT_OPTION_H
+#define __OUTPUT_OPTION_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string>
+
+/// \brief Logger Output Option
+///
+/// The logging configuration options are a list of logger specifications, each
+/// with one or more output options. This class represents an output option;
+/// one or more of these are attached to a LoggerSpecification object which is
+/// then passed to the LoggerManager to configure the logger.
+///
+/// Although there are three distinct output types (console, file, syslog) and
+/// the options for each do not really overlap. Although it is tempting to
+/// define a base OutputOption class and derive a class for each type
+/// (ConsoleOutputOptions etc.), it would be messy to use in practice. At
+/// some point the exact class would have to be known to get the class-specific
+/// options and the (pointer to) the base class cast to the appropriate type.
+/// Instead, this "struct" contains the union of all output options; it is up
+/// to the caller to cherry-pick the members it needs.
+///
+/// One final note: this object holds data and does no computation. For this
+/// reason, it is a "struct" and members are accessed directly instead of
+/// through methods.
+
+namespace isc {
+namespace log {
+
+struct OutputOption {
+
+ /// Destinations. Prefixed "DEST_" to avoid problems with the C stdio.h
+ /// FILE type.
+ typedef enum {
+ DEST_CONSOLE = 0,
+ DEST_FILE = 1,
+ DEST_SYSLOG = 2
+ } Destination;
+
+ /// If console, stream on which messages are output
+ typedef enum {
+ STR_STDOUT = 1,
+ STR_STDERR = 2
+ } Stream;
+
+ /// \brief Constructor
+ OutputOption() : destination(DEST_CONSOLE), stream(STR_STDERR),
+ flush(false), facility("LOCAL0"), filename(""),
+ maxsize(0), maxver(0)
+ {}
+
+ /// Members.
+
+ Destination destination; ///< Where the output should go
+ Stream stream; ///< stdout/stderr if console output
+ bool flush; ///< true to flush after each message
+ std::string facility; ///< syslog facility
+ std::string filename; ///< Filename if file output
+ size_t maxsize; ///< 0 if no maximum size
+ unsigned int maxver; ///< Maximum versions (none if <= 0)
+};
+
+OutputOption::Destination getDestination(const std::string& dest_str);
+OutputOption::Stream getStream(const std::string& stream_str);
+
+
+} // namespace log
+} // namespace isc
+
+#endif // __OUTPUT_OPTION_H
diff --git a/src/lib/log/root_logger_name.cc b/src/lib/log/root_logger_name.cc
deleted file mode 100644
index 58d9407..0000000
--- a/src/lib/log/root_logger_name.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <string>
-#include <root_logger_name.h>
-
-namespace isc {
-namespace log {
-
-namespace {
-
-// Obtain the root logger name in a way that is safe for statically-initialized
-// objects.
-
-std::string&
-getRootLoggerNameInternal() {
- static std::string root_name;
- return (root_name);
-}
-
-} // Anonymous namespace
-
-void
-setRootLoggerName(const std::string& name) {
- getRootLoggerNameInternal() = name;
-}
-
-const std::string& getRootLoggerName() {
- return (getRootLoggerNameInternal());
-}
-
-} // namespace log
-} // namespace isc
diff --git a/src/lib/log/root_logger_name.h b/src/lib/log/root_logger_name.h
deleted file mode 100644
index 9d50332..0000000
--- a/src/lib/log/root_logger_name.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __ROOT_LOGGER_NAME_H
-#define __ROOT_LOGGER_NAME_H
-
-#include <string>
-
-/// \brief Define Name of Root Logger
-///
-/// In BIND-10, the name root logger of a program is the name of the program
-/// itself (in contrast to packages such as log4cxx where the root logger name
-// is something like "."). These trivial functions allow the setting and
-// getting of that name by the logger classes.
-
-namespace isc {
-namespace log {
-
-/// \brief Set Root Logger Name
-///
-/// This function should be called by the program's initialization code before
-/// any logging functions are called.
-///
-/// \param name Name of the root logger. This should be the program name.
-void setRootLoggerName(const std::string& name);
-
-/// \brief Get Root Logger Name
-///
-/// \return Name of the root logger.
-const std::string& getRootLoggerName();
-
-}
-}
-
-#endif // __ROOT_LOGGER_NAME_H
diff --git a/src/lib/log/xdebuglevel.cc b/src/lib/log/xdebuglevel.cc
deleted file mode 100644
index c17a515..0000000
--- a/src/lib/log/xdebuglevel.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <cassert>
-#include <algorithm>
-#include <syslog.h>
-#include <string.h>
-#include <boost/lexical_cast.hpp>
-
-#include <xdebuglevel.h>
-#include <debug_levels.h>
-#include <log4cxx/helpers/stringhelper.h>
-
-using namespace log4cxx;
-using namespace log4cxx::helpers;
-
-// Storage for the logging level objects corresponding to each debug level
-
-bool XDebugLevel::dbglevels_unset_ = true;
-LevelPtr XDebugLevel::dbglevels_[NUM_DEBUG_LEVEL];
-
-// Register the class
-
-IMPLEMENT_LOG4CXX_LEVEL(XDebugLevel)
-
-
-// Create Extended Debug Level Objects
-
-LevelPtr
-XDebugLevel::getExtendedDebug(int level) {
-
- // Initialize the logging levels corresponding to the possible range of
- // debug if we have not already done so
- if (dbglevels_unset_) {
-
- // Asserting that the minimum debug level is zero - so corresponds
- // to DEBUG_INT - means that the lowest level is set to main DEBUG
- // level. This means that the existing logging level object can be
- // used.
- assert(MIN_DEBUG_LEVEL == 0);
- dbglevels_[0] = Level::getDebug();
-
- // Create the logging level objects for the rest of the debug levels.
- // They are given names of the form DEBUG<debug level> (e.g. DEBUG42).
- // They will all correspond to a syslog level of DEBUG.
- for (int i = 1; i < NUM_DEBUG_LEVEL; ++i) {
- std::string name = std::string("DEBUG") +
- boost::lexical_cast<std::string>(i);
- dbglevels_[i] = new XDebugLevel(
- (XDebugLevel::XDEBUG_MIN_LEVEL_INT - i),
- LOG4CXX_STR(name.c_str()), LOG_DEBUG);
- }
- dbglevels_unset_ = false;
- }
-
- // Now get the logging level object asked for. Coerce the debug level to
- // lie in the acceptable range.
- int actual = std::max(MIN_DEBUG_LEVEL, std::min(MAX_DEBUG_LEVEL, level));
-
- // ... and return a pointer to the appropriate logging level object
- return (dbglevels_[actual - MIN_DEBUG_LEVEL]);
-}
-
-// Convert an integer (an absolute logging level number, not a debug level) to a
-// logging level object. If it lies outside the valid range, an object
-// corresponding to the minimum debug value is returned.
-
-LevelPtr
-XDebugLevel::toLevel(int val) {
- return (toLevel(val, getExtendedDebug(MIN_DEBUG_LEVEL)));
-}
-
-LevelPtr
-XDebugLevel::toLevel(int val, const LevelPtr& defaultLevel) {
-
- // Note the reversal of the notion of MIN and MAX - see the header file for
- // details.
- if ((val >= XDEBUG_MAX_LEVEL_INT) && (val <= XDEBUG_MIN_LEVEL_INT)) {
- return (getExtendedDebug(XDEBUG_MIN_LEVEL_INT - val));
- }
- else {
- return (defaultLevel);
- }
-}
-
-// Convert string passed to a logging level or return default level.
-
-LevelPtr
-XDebugLevel::toLevelLS(const LogString& sArg) {
- return (toLevelLS(sArg, getExtendedDebug(0)));
-}
-
-LevelPtr
-XDebugLevel::toLevelLS(const LogString& sArg, const LevelPtr& defaultLevel) {
- std::string name = sArg; // Get to known type
- size_t length = name.size(); // Length of the string
-
- if (length < 5) {
-
- // String can't possibly start DEBUG so we don't know what it is.
- return (defaultLevel);
- }
- else {
- if (strncasecmp(name.c_str(), "DEBUG", 5) == 0) {
-
- // String starts "DEBUG" (or "debug" or any case mixture). The
- // rest of the string -if any - should be a number.
- if (length == 5) {
-
- // It is plain "DEBUG". Take this as level 0.
- return (getExtendedDebug(0));
- }
- else {
-
- // Try converting the remainder to an integer. The "5" is
- // the length of the string "DEBUG". Note that if the number
- // is outside the rangeof debug levels, it is coerced to the
- // nearest limit. Thus a level of DEBUG509 will end up as
- // if DEBUG99 has been specified.
- try {
- int level = boost::lexical_cast<int>(name.substr(5));
- return (getExtendedDebug(level));
- }
- catch ((boost::bad_lexical_cast&) ){
- return (defaultLevel);
- }
- }
- }
- else {
-
- // Unknown string - return default.
- return (defaultLevel);
- }
- }
-}
diff --git a/src/lib/log/xdebuglevel.h b/src/lib/log/xdebuglevel.h
deleted file mode 100644
index e580b77..0000000
--- a/src/lib/log/xdebuglevel.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __XDEBUGLEVEL_H
-#define __XDEBUGLEVEL_H
-
-#include <syslog.h>
-#include <log4cxx/level.h>
-
-#include <debug_levels.h>
-
-namespace log4cxx {
-
-/// \brief Debug Extension to Level Class
-///
-/// Based on the example given in the log4cxx distribution, this extends the
-/// log4cxx Level class to allow 100 debug levels.
-///
-/// First some terminology, as the use of the term "level" gets confusing. The
-/// code and comments here use the term "level" in two contexts:
-///
-/// Logging level: The category of messages to log. By default log4cxx defines
-/// the following logging levels: OFF, FATAL, ERROR, WARNING, INFO, DEBUG,
-/// TRACE, ALL. Within the context of BIND-10, OFF, TRACE and ALL are not used
-/// and the idea of DEBUG has been extended, as will be seen below.
-///
-/// Debug level: This is a number that ranges from 0 to 99 and is used by the
-/// application to control the detail of debug output. A value of 0 gives the
-/// highest-level debug output; a value of 99 gives the most verbose and most
-/// detailed. Debug messages (or whatever debug level) are only ever output
-/// when the logging level is set to DEBUG.
-///
-///
-/// With log4cxx, the various logging levels have a numeric value associated
-/// with them, such that FATAL > ERROR > WARNING etc. This suggests that the
-/// idea of debug levels can be incorporated into the existing logging level
-/// scheme by assigning them appropriate numeric values, i.e.
-///
-/// WARNING > INFO > DEBUG(0) > DEBUG(2) > ... > DEBUG(99)
-///
-/// Setting a numeric level of DEBUG enables the basic messages; setting lower
-/// numeric levels will enable progressively more messages. The lowest debug
-/// level (0) is chosen such that setting the general DEBUG logging level will
-/// automatically select that debug level.
-///
-/// This sub-class is needed because the log4cxx::Level class does not allow
-/// the setting of the numeric value of the current level to something other
-/// than the values enumerated in the class. It creates a set of log4cxx
-/// logging levels to correspond to the various debug levels. These levels have
-/// names in the range DEBUG1 to DEBUG99 (the existing Level DEBUG is used for
-/// a debug level of 0), although they are not used in BIND-10: instead the
-/// BIND-10 Logger class treats the logging levels and debug levels separately
-/// and combines them to choose the underlying log4cxx logging level.
-
-
-/// \brief Debug-Extended Level
-
-class XDebugLevel : public Level {
- DECLARE_LOG4CXX_LEVEL(XDebugLevel)
-
- /// Array of pointers to logging level objects, one for each debug level.
- /// The pointer corresponding to a debug level of 0 points to the DEBUG
- /// logging level object.
- static LevelPtr dbglevels_[NUM_DEBUG_LEVEL];
- static bool dbglevels_unset_;
-
-public:
-
- // Minimum and maximum debug levels. Note that XDEBUG_MIN_LEVEL_INT is the
- // number corresponding to the minimum debug level - and is actually larger
- // that XDEBUG_MAX_LEVEL_INT, the number corresponding to the maximum debug
- // level.
- enum {
- XDEBUG_MIN_LEVEL_INT = Level::DEBUG_INT - MIN_DEBUG_LEVEL,
- XDEBUG_MAX_LEVEL_INT = Level::DEBUG_INT - MAX_DEBUG_LEVEL
- };
-
- /// \brief Constructor
- ///
- /// \param level Numeric value of the logging level.
- /// \param name Name given to this logging level.
- /// \param syslogEquivalent The category to be used by syslog when it logs
- /// an event associated with the specified logging level.
- XDebugLevel(int level, const LogString& name, int syslogEquivalent) :
- Level(level, name, syslogEquivalent)
- {}
-
- /// \brief Create Logging Level Object
- ///
- /// Creates a logging level object corresponding to one of the debug levels.
- ///
- /// \param dbglevel The debug level, which ranges from MIN_DEBUG_LEVEL to
- /// MAX_DEBUG_LEVEL. It is coerced to that range if it lies outside it.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr getExtendedDebug(int dbglevel);
-
- /// \brief Convert Integer to a Logging Level
- ///
- /// Returns a logging level object corresponding to the given value (which
- /// is an absolute value of a logging level - it is not a debug level).
- /// If the number is invalid, an object of logging level DEBUG (the
- /// minimum debug logging level) is returned.
- ///
- /// \param val Number to convert to a logging level. This is an absolute
- /// logging level number, not a debug level.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevel(int val);
-
- /// \brief Convert Integer to a Level
- ///
- /// Returns a logging level object corresponding to the given value (which
- /// is an absolute value of a logging level - it is not a debug level).
- /// If the number is invalid, the given default is returned.
- ///
- /// \param val Number to convert to a logging level. This is an absolute
- /// logging level number, not a debug level.
- /// \param defaultLevel Logging level to return if value is not recognised.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevel(int val, const LevelPtr& defaultLevel);
-
- /// \brief Convert String to Logging Level
- ///
- /// Returns a logging level object corresponding to the given name. If the
- /// name is invalid, an object of logging level DEBUG (the minimum debug
- /// logging level) is returned.
- ///
- /// \param sArg Name of the logging level.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevelLS(const LogString& sArg);
-
- /// \brief Convert String to Logging Level
- ///
- /// Returns a logging level object corresponding to the given name. If the
- /// name is invalid, the given default is returned.
- ///
- /// \param sArg name of the level.
- /// \param defaultLevel Logging level to return if name doesn't exist.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevelLS(const LogString& sArg,
- const LevelPtr& defaultLevel);
-};
-
-} // namespace log4cxx
-
-
-#endif // __XDEBUGLEVEL_H
diff --git a/win32build/VS2010/libasiodns/libasiodns.vcxproj b/win32build/VS2010/libasiodns/libasiodns.vcxproj
index 9cdc0bf..2ce223a 100755
--- a/win32build/VS2010/libasiodns/libasiodns.vcxproj
+++ b/win32build/VS2010/libasiodns/libasiodns.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -67,7 +67,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\asiodns;..\..\..\ext\asio;..\..\..\ext\coroutine;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\asiodns;..\..\..\ext\asio;..\..\..\ext\coroutine;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -83,7 +83,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\asiodns;..\..\..\ext\asio;..\..\..\ext\coroutine;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\asiodns;..\..\..\ext\asio;..\..\..\ext\coroutine;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libasiodns_tests/libasiodns_tests.vcxproj b/win32build/VS2010/libasiodns_tests/libasiodns_tests.vcxproj
index 7766258..181a224 100755
--- a/win32build/VS2010/libasiodns_tests/libasiodns_tests.vcxproj
+++ b/win32build/VS2010/libasiodns_tests/libasiodns_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="testdata";_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -61,7 +61,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;liblog.lib;libasiolink.lib;libasiodns.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
- <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\liblog\Debug;..\libasiolink\Debug;..\libasiodns\Debug;..\..\..\..\gtest\md10\Debug;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\liblog\Debug;..\libasiolink\Debug;..\libasiodns\Debug;..\..\..\..\gtest\md10\Debug;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="testdata";NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -82,7 +82,7 @@
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;liblog.lib;libasiolink.lib;libasiodns.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\liblog\Release;..\libasiolink\Release;..\libasiodns\Release;..\..\..\..\gtest\md10\Release;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\liblog\Release;..\libasiolink\Release;..\libasiodns\Release;..\..\..\..\gtest\md10\Release;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/win32build/VS2010/libasiolink/libasiolink.vcxproj b/win32build/VS2010/libasiolink/libasiolink.vcxproj
index c15f24b..bda3408 100755
--- a/win32build/VS2010/libasiolink/libasiolink.vcxproj
+++ b/win32build/VS2010/libasiolink/libasiolink.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -73,7 +73,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -89,7 +89,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libasiolink_tests/libasiolink_tests.vcxproj b/win32build/VS2010/libasiolink_tests/libasiolink_tests.vcxproj
index 8cc1aa2..a6289a7 100755
--- a/win32build/VS2010/libasiolink_tests/libasiolink_tests.vcxproj
+++ b/win32build/VS2010/libasiolink_tests/libasiolink_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="testdata";_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -61,7 +61,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libdns++.lib;liblog.lib;libasiolink.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libdns++\Debug;..\liblog\Debug;..\libasiolink\Debug;..\..\..\..\gtest\md10\Debug;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libdns++\Debug;..\liblog\Debug;..\libasiolink\Debug;..\..\..\..\gtest\md10\Debug;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="testdata";NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -82,7 +82,7 @@
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libdns++.lib;liblog.lib;libasiolink.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Release;..\libdns++\Release;..\liblog\Release;..\libasiolink\Release;..\..\..\..\gtest\md10\Release;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Release;..\libdns++\Release;..\liblog\Release;..\libasiolink\Release;..\..\..\..\gtest\md10\Release;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/win32build/VS2010/libbench/libbench.vcxproj b/win32build/VS2010/libbench/libbench.vcxproj
index 5ec75d7..39b2930 100755
--- a/win32build/VS2010/libbench/libbench.vcxproj
+++ b/win32build/VS2010/libbench/libbench.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -56,7 +56,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libbench_tests/libbench_tests.vcxproj b/win32build/VS2010/libbench_tests/libbench_tests.vcxproj
index 8dfd308..5c7de19 100755
--- a/win32build/VS2010/libbench_tests/libbench_tests.vcxproj
+++ b/win32build/VS2010/libbench_tests/libbench_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/bench/tests/testdata";_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/bench/tests/testdata";NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libcache/libcache.vcxproj b/win32build/VS2010/libcache/libcache.vcxproj
index 0135c27..f640c85 100755
--- a/win32build/VS2010/libcache/libcache.vcxproj
+++ b/win32build/VS2010/libcache/libcache.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -71,7 +71,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\src\lib\cache;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\src\lib\cache;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -87,7 +87,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\src\lib\cache;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\src\lib\cache;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libcache_tests/libcache_tests.vcxproj b/win32build/VS2010/libcache_tests/libcache_tests.vcxproj
index 8a7afbf..3c09ee6 100755
--- a/win32build/VS2010/libcache_tests/libcache_tests.vcxproj
+++ b/win32build/VS2010/libcache_tests/libcache_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -54,7 +54,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;TEST_DATA_SRCDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/cache/tests/testdata";TEST_DATA_BUILDDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/cache/tests/testdata";_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsCpp</CompileAs>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cache;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cache;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -73,7 +73,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;TEST_DATA_SRCDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/cache/tests/testdata";TEST_DATA_BUILDDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/cache/tests/testdata";NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsCpp</CompileAs>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cache;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cache;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
diff --git a/win32build/VS2010/libcc/libcc.vcxproj b/win32build/VS2010/libcc/libcc.vcxproj
index 4d8a817..48d77b1 100755
--- a/win32build/VS2010/libcc/libcc.vcxproj
+++ b/win32build/VS2010/libcc/libcc.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -58,7 +58,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -79,7 +79,7 @@ copy session_config.h.win32 session_config.h
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libcc_tests/libcc_tests.vcxproj b/win32build/VS2010/libcc_tests/libcc_tests.vcxproj
index 27c513e..5d316d2 100755
--- a/win32build/VS2010/libcc_tests/libcc_tests.vcxproj
+++ b/win32build/VS2010/libcc_tests/libcc_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cc\tests;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cc\tests;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -61,7 +61,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libcc.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libcc\Debug;..\..\..\..\gtest\md10\Debug;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libcc\Debug;..\..\..\..\gtest\md10\Debug;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>cd ..\..\..\src\lib\cc\tests
@@ -77,7 +77,7 @@ copy session_unittests_config.h.win32 session_unittests_config.h
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cc\tests;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\cc\tests;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -87,7 +87,7 @@ copy session_unittests_config.h.win32 session_unittests_config.h
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libcc.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Release;..\libcc\Release;..\..\..\..\gtest\md10\Release;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Release;..\libcc\Release;..\..\..\..\gtest\md10\Release;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>cd ..\..\..\src\lib\cc\tests
diff --git a/win32build/VS2010/libcfgclient/libcfgclient.vcxproj b/win32build/VS2010/libcfgclient/libcfgclient.vcxproj
index 14293f1..c63ca0c 100755
--- a/win32build/VS2010/libcfgclient/libcfgclient.vcxproj
+++ b/win32build/VS2010/libcfgclient/libcfgclient.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -59,7 +59,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cc;..\..\..\src\lib\config;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cc;..\..\..\src\lib\config;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -75,7 +75,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cc;..\..\..\src\lib\config;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cc;..\..\..\src\lib\config;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libcfgclient_tests/libcfgclient_tests.vcxproj b/win32build/VS2010/libcfgclient_tests/libcfgclient_tests.vcxproj
index a102a32..94f57d2 100755
--- a/win32build/VS2010/libcfgclient_tests/libcfgclient_tests.vcxproj
+++ b/win32build/VS2010/libcfgclient_tests/libcfgclient_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;TEST_DATA_PATH="c:/cygwin/home/fdupont/bind10.trac826/src/lib/config/tests/testdata";_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -77,7 +77,7 @@ copy data_def_unittests_config.h.win32 data_def_unittests_config.h
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;TEST_DATA_PATH="c:/cygwin/home/fdupont/bind10.trac826/src/lib/config/tests/testdata";NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libcryptolink/libcryptolink.vcxproj b/win32build/VS2010/libcryptolink/libcryptolink.vcxproj
index 7b63a6c..19a6445 100755
--- a/win32build/VS2010/libcryptolink/libcryptolink.vcxproj
+++ b/win32build/VS2010/libcryptolink/libcryptolink.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -57,7 +57,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cryptolink;..\..\..\..\botan\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cryptolink;..\..\..\..\botan\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -73,7 +73,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cryptolink;..\..\..\..\botan\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\cryptolink;..\..\..\..\botan\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libcryptolink_tests/libcryptolink_tests.vcxproj b/win32build/VS2010/libcryptolink_tests/libcryptolink_tests.vcxproj
index f8f5e35..ad41746 100755
--- a/win32build/VS2010/libcryptolink_tests/libcryptolink_tests.vcxproj
+++ b/win32build/VS2010/libcryptolink_tests/libcryptolink_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libdatasrc/libdatasrc.vcxproj b/win32build/VS2010/libdatasrc/libdatasrc.vcxproj
index 5c6ff6a..c648fba 100755
--- a/win32build/VS2010/libdatasrc/libdatasrc.vcxproj
+++ b/win32build/VS2010/libdatasrc/libdatasrc.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -71,7 +71,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsCpp</CompileAs>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;C:\Program Files\boost\boost_1_44;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;%BOOST%;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -87,7 +87,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsCpp</CompileAs>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;C:\Program Files\boost\boost_1_44;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;%BOOST%;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
diff --git a/win32build/VS2010/libdatasrc_tests/libdatasrc_tests.vcxproj b/win32build/VS2010/libdatasrc_tests/libdatasrc_tests.vcxproj
index 7291484..63dfe2a 100755
--- a/win32build/VS2010/libdatasrc_tests/libdatasrc_tests.vcxproj
+++ b/win32build/VS2010/libdatasrc_tests/libdatasrc_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/datasrc/tests/testdata";_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\..\gtest\include;%BOOST%;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;TEST_DATA_DIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/datasrc/tests/testdata";NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\..\gtest\include;%BOOST%;C:\sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libdns++/libdns++.vcxproj b/win32build/VS2010/libdns++/libdns++.vcxproj
index 1724b71..f41ebb3 100755
--- a/win32build/VS2010/libdns++/libdns++.vcxproj
+++ b/win32build/VS2010/libdns++/libdns++.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -97,7 +97,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\util;..\..\..\src\lib\dns;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\util;..\..\..\src\lib\dns;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -119,7 +119,7 @@ python gen-rdatacode.py
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\util;..\..\..\src\lib\dns;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\util;..\..\..\src\lib\dns;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libdns++_benchmarks/libdns++_benchmarks.vcxproj b/win32build/VS2010/libdns++_benchmarks/libdns++_benchmarks.vcxproj
index e89c584..a2f6ff1 100755
--- a/win32build/VS2010/libdns++_benchmarks/libdns++_benchmarks.vcxproj
+++ b/win32build/VS2010/libdns++_benchmarks/libdns++_benchmarks.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libdns++_python/libdns++_python.vcxproj b/win32build/VS2010/libdns++_python/libdns++_python.vcxproj
index b7bee5d..20ad39e 100755
--- a/win32build/VS2010/libdns++_python/libdns++_python.vcxproj
+++ b/win32build/VS2010/libdns++_python/libdns++_python.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -55,7 +55,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBDNS_PYTHON_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns\python;C:\Program Files\boost\boost_1_44;C:\Python32\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns\python;%BOOST%;C:\Python32\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -79,7 +79,7 @@ copy bind10_config.py.win32 bind10_config.py
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBDNS_PYTHON_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns\python;C:\Program Files\boost\boost_1_44;C:\Python32\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns\python;%BOOST%;C:\Python32\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libdns++_tests/libdns++_tests.vcxproj b/win32build/VS2010/libdns++_tests/libdns++_tests.vcxproj
index f6240f2..8c94b6b 100755
--- a/win32build/VS2010/libdns++_tests/libdns++_tests.vcxproj
+++ b/win32build/VS2010/libdns++_tests/libdns++_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;TEST_DATA_SRCDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/dns/tests/testdata";TEST_DATA_BUILDDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/dns/tests/testdata";_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\util;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\util;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -139,7 +139,7 @@ python gen-wiredata.py -o rdata_txt_fromWire5.wire rdata_txt_fromWire5.spec
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;TEST_DATA_SRCDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/dns/tests/testdata";TEST_DATA_BUILDDIR="c:/cygwin/home/fdupont/bind10.trac826/src/lib/dns/tests/testdata";NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\util;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\util;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/liblog/liblog.vcxproj b/win32build/VS2010/liblog/liblog.vcxproj
index c9b0c18..eba50f8 100755
--- a/win32build/VS2010/liblog/liblog.vcxproj
+++ b/win32build/VS2010/liblog/liblog.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -11,31 +11,46 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\..\..\src\lib\log\debug_levels.h" />
<ClInclude Include="..\..\..\src\lib\log\dummylog.h" />
+ <ClInclude Include="..\..\..\src\lib\log\log_formatter.h" />
<ClInclude Include="..\..\..\src\lib\log\logger.h" />
<ClInclude Include="..\..\..\src\lib\log\logger_impl.h" />
- <ClInclude Include="..\..\..\src\lib\log\logger_levels.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logger_level.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logger_level_impl.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logger_manager.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logger_manager_impl.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logger_name.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logger_specification.h" />
<ClInclude Include="..\..\..\src\lib\log\logger_support.h" />
- <ClInclude Include="..\..\..\src\lib\log\messagedef.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logger_unittest_support.h" />
+ <ClInclude Include="..\..\..\src\lib\log\logimpl_messages.h" />
+ <ClInclude Include="..\..\..\src\lib\log\log_messages.h" />
+ <ClInclude Include="..\..\..\src\lib\log\macros.h" />
<ClInclude Include="..\..\..\src\lib\log\message_dictionary.h" />
<ClInclude Include="..\..\..\src\lib\log\message_exception.h" />
<ClInclude Include="..\..\..\src\lib\log\message_initializer.h" />
<ClInclude Include="..\..\..\src\lib\log\message_reader.h" />
<ClInclude Include="..\..\..\src\lib\log\message_types.h" />
- <ClInclude Include="..\..\..\src\lib\log\root_logger_name.h" />
+ <ClInclude Include="..\..\..\src\lib\log\output_option.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\lib\log\dummylog.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\log_formatter.cc" />
<ClCompile Include="..\..\..\src\lib\log\logger.cc" />
<ClCompile Include="..\..\..\src\lib\log\logger_impl.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\logger_level.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\logger_level_impl.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\logger_manager.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\logger_manager_impl.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\logger_name.cc" />
<ClCompile Include="..\..\..\src\lib\log\logger_support.cc" />
- <ClCompile Include="..\..\..\src\lib\log\messagedef.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\logger_unittest_support.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\logimpl_messages.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\log_messages.cc" />
<ClCompile Include="..\..\..\src\lib\log\message_dictionary.cc" />
- <ClCompile Include="..\..\..\src\lib\log\message_exception.cc" />
<ClCompile Include="..\..\..\src\lib\log\message_initializer.cc" />
<ClCompile Include="..\..\..\src\lib\log\message_reader.cc" />
- <ClCompile Include="..\..\..\src\lib\log\root_logger_name.cc" />
+ <ClCompile Include="..\..\..\src\lib\log\output_option.cc" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{AEF3DFFE-B566-4E6A-B299-B59B81022C06}</ProjectGuid>
@@ -76,7 +91,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;..\..\..\..\log4cplus\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -92,7 +107,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;..\..\..\..\log4cplus\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/liblog/liblog.vcxproj.filters b/win32build/VS2010/liblog/liblog.vcxproj.filters
index ca102f5..17a87ef 100755
--- a/win32build/VS2010/liblog/liblog.vcxproj.filters
+++ b/win32build/VS2010/liblog/liblog.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@@ -15,10 +15,10 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\..\..\src\lib\log\debug_levels.h">
+ <ClInclude Include="..\..\..\src\lib\log\dummylog.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\src\lib\log\dummylog.h">
+ <ClInclude Include="..\..\..\src\lib\log\log_formatter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\lib\log\logger.h">
@@ -27,12 +27,39 @@
<ClInclude Include="..\..\..\src\lib\log\logger_impl.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\src\lib\log\logger_levels.h">
+ <ClInclude Include="..\..\..\src\lib\log\logger_level.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\logger_level_impl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\logger_manager.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\logger_manager_impl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\logger_name.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\logger_specification.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\lib\log\logger_support.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\logger_unittest_support.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\logimpl_messages.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\log_messages.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\src\lib\log\macros.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\src\lib\log\message_dictionary.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -48,10 +75,7 @@
<ClInclude Include="..\..\..\src\lib\log\message_types.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\src\lib\log\messagedef.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\src\lib\log\root_logger_name.h">
+ <ClInclude Include="..\..\..\src\lib\log\output_option.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@@ -59,31 +83,52 @@
<ClCompile Include="..\..\..\src\lib\log\dummylog.cc">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\src\lib\log\log_formatter.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\src\lib\log\logger.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\lib\log\logger_impl.cc">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\src\lib\log\logger_level.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\log\logger_level_impl.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\log\logger_manager.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\log\logger_manager_impl.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\log\logger_name.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\src\lib\log\logger_support.cc">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\src\lib\log\message_dictionary.cc">
+ <ClCompile Include="..\..\..\src\lib\log\logger_unittest_support.cc">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\src\lib\log\message_exception.cc">
+ <ClCompile Include="..\..\..\src\lib\log\logimpl_messages.cc">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\src\lib\log\message_initializer.cc">
+ <ClCompile Include="..\..\..\src\lib\log\log_messages.cc">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\src\lib\log\message_reader.cc">
+ <ClCompile Include="..\..\..\src\lib\log\message_dictionary.cc">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\src\lib\log\messagedef.cc">
+ <ClCompile Include="..\..\..\src\lib\log\message_initializer.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\src\lib\log\message_reader.cc">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\src\lib\log\root_logger_name.cc">
+ <ClCompile Include="..\..\..\src\lib\log\output_option.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
diff --git a/win32build/VS2010/liblog_compiler/liblog_compiler.vcxproj b/win32build/VS2010/liblog_compiler/liblog_compiler.vcxproj
index 0f698ed..72f739b 100755
--- a/win32build/VS2010/liblog_compiler/liblog_compiler.vcxproj
+++ b/win32build/VS2010/liblog_compiler/liblog_compiler.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/liblog_tests/liblog_tests.vcxproj b/win32build/VS2010/liblog_tests/liblog_tests.vcxproj
index f8fe644..796af71 100755
--- a/win32build/VS2010/liblog_tests/liblog_tests.vcxproj
+++ b/win32build/VS2010/liblog_tests/liblog_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -66,7 +66,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -86,7 +86,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\log;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
diff --git a/win32build/VS2010/libnsas/libnsas.vcxproj b/win32build/VS2010/libnsas/libnsas.vcxproj
index 8c7873d..823da58 100755
--- a/win32build/VS2010/libnsas/libnsas.vcxproj
+++ b/win32build/VS2010/libnsas/libnsas.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -77,7 +77,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -93,7 +93,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libnsas_tests/libnsas_tests.vcxproj b/win32build/VS2010/libnsas_tests/libnsas_tests.vcxproj
index ce03999..48ff02f 100755
--- a/win32build/VS2010/libnsas_tests/libnsas_tests.vcxproj
+++ b/win32build/VS2010/libnsas_tests/libnsas_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -61,7 +61,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;libasiolink.lib;libnsas.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\libasiolink\Debug;..\libnsas\Debug;..\..\..\..\gtest\md10\Debug;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\libasiolink\Debug;..\libnsas\Debug;..\..\..\..\gtest\md10\Debug;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\src\lib\nsas;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -82,7 +82,7 @@
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;libasiolink.lib;libnsas.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\libasiolink\Release;..\libnsas\Release;..\..\..\..\gtest\md10\Release;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\libasiolink\Release;..\libnsas\Release;..\..\..\..\gtest\md10\Release;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/win32build/VS2010/libresolve/libresolve.vcxproj b/win32build/VS2010/libresolve/libresolve.vcxproj
index ebd6a33..770cf2d 100755
--- a/win32build/VS2010/libresolve/libresolve.vcxproj
+++ b/win32build/VS2010/libresolve/libresolve.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -63,7 +63,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsCpp</CompileAs>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -79,7 +79,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsCpp</CompileAs>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
diff --git a/win32build/VS2010/libresolve_tests/libresolve_tests.vcxproj b/win32build/VS2010/libresolve_tests/libresolve_tests.vcxproj
index 02265db..843827d 100755
--- a/win32build/VS2010/libresolve_tests/libresolve_tests.vcxproj
+++ b/win32build/VS2010/libresolve_tests/libresolve_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -61,7 +61,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;liblog.lib;libasiolink.lib;libasiodns.lib;libnsas.lib;libcache.lib;libresolve.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\liblog\Debug;..\libasiolink\Debug;..\libasiodns\Debug;..\libnsas\Debug;..\libcache\Debug;..\libresolve\Debug;..\..\..\..\gtest\md10\Debug;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\liblog\Debug;..\libasiolink\Debug;..\libasiodns\Debug;..\libnsas\Debug;..\libcache\Debug;..\libresolve\Debug;..\..\..\..\gtest\md10\Debug;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;..\..\..\ext\coroutine;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -82,7 +82,7 @@
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;liblog.lib;libasiolink.lib;libasiodns.lib;libnsas.lib;libcache.lib;libresolve.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\liblog\Release;..\libasiolink\Release;..\libasiodns\Release;..\libnsas\Release;..\libcache\Release;..\libresolve\Release;..\..\..\..\gtest\md10\Release;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\liblog\Release;..\libasiolink\Release;..\libasiodns\Release;..\libnsas\Release;..\libcache\Release;..\libresolve\Release;..\..\..\..\gtest\md10\Release;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/win32build/VS2010/libserver_common/libserver_common.vcxproj b/win32build/VS2010/libserver_common/libserver_common.vcxproj
index 7687a8d..3671afa 100755
--- a/win32build/VS2010/libserver_common/libserver_common.vcxproj
+++ b/win32build/VS2010/libserver_common/libserver_common.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -55,7 +55,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -71,7 +71,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libserver_common_tests/libserver_common_tests.vcxproj b/win32build/VS2010/libserver_common_tests/libserver_common_tests.vcxproj
index b981526..d9da977 100755
--- a/win32build/VS2010/libserver_common_tests/libserver_common_tests.vcxproj
+++ b/win32build/VS2010/libserver_common_tests/libserver_common_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\server_common;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\server_common;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -61,7 +61,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;libcc.lib;liblog.lib;libasiolink.lib;libasiodns.lib;libserver_common.lib;gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\libcc\Debug;..\liblog\Debug;..\libasiolink\Debug;..\libasiodns\Debug;..\libserver_common\Debug;..\..\..\..\gtest\md10\Debug;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Debug;..\libutil\Debug;..\libdns++\Debug;..\libcc\Debug;..\liblog\Debug;..\libasiolink\Debug;..\libasiodns\Debug;..\libserver_common\Debug;..\..\..\..\gtest\md10\Debug;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\server_common;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\server_common;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -82,7 +82,7 @@
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)run_unittests$(TargetExt)</OutputFile>
<AdditionalDependencies>libexceptions.lib;libutil.lib;libdns++.lib;libcc.lib;liblog.lib;libasiolink.lib;libasiodns.lib;libserver_common.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\libcc\Release;..\liblog\Release;..\libasiolink\Release;..\libasiodns\Release;..\libserver_common\Release;..\..\..\..\gtest\md10\Release;C:\Program Files\boost\boost_1_44\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>..\libexceptions\Release;..\libutil\Release;..\libdns++\Release;..\libcc\Release;..\liblog\Release;..\libasiolink\Release;..\libasiodns\Release;..\libserver_common\Release;..\..\..\..\gtest\md10\Release;%BOOST%\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/win32build/VS2010/libtestutils/libtestutils.vcxproj b/win32build/VS2010/libtestutils/libtestutils.vcxproj
index 964ed7a..dbfe691 100755
--- a/win32build/VS2010/libtestutils/libtestutils.vcxproj
+++ b/win32build/VS2010/libtestutils/libtestutils.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -59,7 +59,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -75,7 +75,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\ext\asio;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libutil/libutil.vcxproj b/win32build/VS2010/libutil/libutil.vcxproj
index ff17a83..5246763 100755
--- a/win32build/VS2010/libutil/libutil.vcxproj
+++ b/win32build/VS2010/libutil/libutil.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -76,7 +76,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\util;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\util;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -92,7 +92,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\util;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\util;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libutil_tests/libutil_tests.vcxproj b/win32build/VS2010/libutil_tests/libutil_tests.vcxproj
index f1b064c..640abfa 100755
--- a/win32build/VS2010/libutil_tests/libutil_tests.vcxproj
+++ b/win32build/VS2010/libutil_tests/libutil_tests.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -53,7 +53,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\utils;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\utils;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -72,7 +72,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\utils;..\..\..\..\gtest\include;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\exceptions;..\..\..\src\lib\utils;..\..\..\..\gtest\include;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
diff --git a/win32build/VS2010/libxfr/libxfr.vcxproj b/win32build/VS2010/libxfr/libxfr.vcxproj
index 7ea5517..f09776f 100755
--- a/win32build/VS2010/libxfr/libxfr.vcxproj
+++ b/win32build/VS2010/libxfr/libxfr.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -55,7 +55,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
@@ -71,7 +71,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;C:\Program Files\boost\boost_1_44;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\..;..\..\..\src\lib;..\..\..\src\lib\dns;..\..\..\ext\asio;%BOOST%;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
More information about the bind10-changes
mailing list