Boost logo

Boost-Commit :

From: john.groups_at_[hidden]
Date: 2007-10-28 08:48:50


Author: jtorjo
Date: 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
New Revision: 40523
URL: http://svn.boost.org/trac/boost/changeset/40523

Log:
[logging]
v0.9.0, 28 oct 2007
- use_format_write has 4 params now, I've added 2 new params: thread_safety and gather
  - if you want to leave something unchanged, use "default_" as argument
- added more complex example: Line Counter application
- Breaking change:
  - filters are declared with BOOST_DECLARE_LOG_FILTER, and defined with BOOST_DEFINE_LOG_FILTER
  - filters are now used with operator->, instead of "."
  - Example:
                BOOST_DEFINE_LOG_LEVEL(g_log_level, level::holder )
                ...
                g_log_level->set_enabled(level::error);
  - rationale: filters, same as levels, could be used before main

Added:
   sandbox/logging/boost/logging/detail/format_msg_type.hpp (contents, props changed)
   sandbox/logging/boost/logging/format_fwd.hpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/
   sandbox/logging/lib/logging/samples/basic_usage/ReadMe.txt (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/basic_usage.sln (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/basic_usage.vcproj (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/dir_spec.cpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/dir_spec.h (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/extensions.h (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/file_statistics.cpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/file_statistics.h (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/log.cpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/log.h (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/main.cpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/parse_file.cpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/parse_file.h (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/stdafx.cpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/stdafx.h (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/util.cpp (contents, props changed)
   sandbox/logging/lib/logging/samples/basic_usage/util.h (contents, props changed)
Text files modified:
   sandbox/logging/boost/logging/detail/manipulator.hpp | 95 +++++++++++++++++---------
   sandbox/logging/boost/logging/detail/raw_doc/Doxyfile.txt | 4
   sandbox/logging/boost/logging/detail/raw_doc/Doxyfile_web.txt | 4
   sandbox/logging/boost/logging/detail/raw_doc/common_usage_steps_fd.hpp | 15 ++-
   sandbox/logging/boost/logging/detail/raw_doc/customize_manipulator.hpp | 6 +
   sandbox/logging/boost/logging/detail/raw_doc/scenarios.hpp | 5 +
   sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp | 5 +
   sandbox/logging/boost/logging/detail/use_format_write.hpp | 43 +++++++++---
   sandbox/logging/boost/logging/detail/util.hpp | 18 ----
   sandbox/logging/boost/logging/filter.hpp | 4 -
   sandbox/logging/boost/logging/format.hpp | 10 ++
   sandbox/logging/boost/logging/format/destination/file.hpp | 2
   sandbox/logging/boost/logging/format/formatter/convert_format.hpp | 12 +-
   sandbox/logging/boost/logging/logging.hpp | 15 ++++
   sandbox/logging/boost/logging/macros.hpp | 142 ++++++++++++++++++++++++++++++++++++---
   sandbox/logging/boost/logging/process_msg.hpp | 33 ++++++--
   sandbox/logging/boost/logging/process_msg/ostream_like.hpp | 9 ++
   sandbox/logging/lib/logging/samples/scenarios/custom_fmt_dest.cpp | 40 +++++-----
   sandbox/logging/lib/logging/samples/scenarios/fastest_no_ostr_like.cpp | 12 +-
   sandbox/logging/lib/logging/samples/scenarios/fastest_use_ostr_like.cpp | 12 +-
   sandbox/logging/lib/logging/samples/scenarios/mul_levels_mul_logers.cpp | 41 +++++------
   sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp | 32 +++-----
   sandbox/logging/lib/logging/samples/scenarios/mul_loggers_one_filter.cpp | 43 +++++------
   sandbox/logging/lib/logging/samples/scenarios/no_levels_with_route.cpp | 34 ++++-----
   sandbox/logging/lib/logging/samples/scenarios/one_loger_one_filter.cpp | 34 ++++-----
   sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj | 15 ++-
   sandbox/logging/lib/logging/src/changelog.txt | 14 +++
   27 files changed, 451 insertions(+), 248 deletions(-)

Added: sandbox/logging/boost/logging/detail/format_msg_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/format_msg_type.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,51 @@
+// format_msg_type.hpp
+
+// Boost Logging library
+//
+// Author: John Torjo, www.torjo.com
+//
+// Copyright (C) 2007 John Torjo (see www.torjo.com for email)
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+// See http://www.torjo.com/log2/ for more details
+
+
+#ifndef JT28092007_format_msg_type_HPP_DEFINED
+#define JT28092007_format_msg_type_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+
+
+namespace boost { namespace logging {
+
+namespace formatter {
+ /**
+ @brief what is the default type of your string, in formatter_base ? See BOOST_LOG_FORMAT_MSG
+ */
+ template<class T = override> struct msg_type {
+ typedef hold_string_type& type;
+ };
+}
+
+namespace destination {
+ /**
+ @brief what is the default type of your string, in formatter_base ? See BOOST_LOG_DESTINATION_MSG
+ */
+ template<class T = override> struct msg_type {
+ // by default - the default string
+ typedef const hold_string_type& type;
+ };
+}
+
+}}
+
+#endif
+

Modified: sandbox/logging/boost/logging/detail/manipulator.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/manipulator.hpp (original)
+++ sandbox/logging/boost/logging/detail/manipulator.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -27,6 +27,7 @@
 #endif
 
 #include <boost/logging/detail/fwd.hpp>
+#include <boost/logging/detail/format_msg_type.hpp>
 
 namespace boost { namespace logging {
 
@@ -232,33 +233,23 @@
 */
 namespace manipulator {
 
- namespace detail {
- struct default_type {};
- template<class type_> struct ptr_finder {
- template<class other_type> struct find { typedef other_type type ; };
- };
- template<> struct ptr_finder<default_type> {
- template<class other_type> struct find { typedef other_type* type ; };
- };
- }
 
 
 
 /**
- @brief What to use as base class, for your formatter and destination classes
+ @brief What to use as base class, for your manipulator classes
 
     When using formatters and destinations, formatters must share a %base class,
     and destinations must share a %base class - see manipulator namespace.
 */
 template<
         class arg_type,
- class ptr_type_ = detail::default_type >
+ class ptr_type_ = default_ >
     struct base : boost::logging::op_equal::same_type_op_equal_base {
 
     typedef base<arg_type, ptr_type_> self_type;
- typedef typename detail::ptr_finder<ptr_type_> type_finder;
- typedef typename type_finder::template find<self_type>::type ptr_type;
 
+ typedef typename use_default<ptr_type_, self_type*>::type ptr_type;
     typedef arg_type param;
 
     typedef typename boost::remove_const<param>::type non_const_param;
@@ -293,11 +284,9 @@
 }
 
 /**
- @brief Use this when implementing your own formatter or destination class
-
- x
+ @brief Use this when implementing your own formatter or destination class. Don't use this directly. Use formatter::class_ or destination::class_
 */
-template<class type, class base_type, implement_op_equal::type op_e> struct class_
+template<class type, implement_op_equal::type op_e, class base_type> struct class_
     : base_type,
       detail::op_equal_base<op_e>,
       boost::logging::op_equal::same_type_op_equal<type> {
@@ -397,8 +386,8 @@
     template<class generic_type, class manipulator_base> struct generic_holder
             : class_<
                     generic_holder<generic_type,manipulator_base>,
- manipulator_base,
- implement_op_equal::has_context> {
+ implement_op_equal::has_context,
+ manipulator_base > {
         typedef typename manipulator_base::param param;
 
         generic_type m_val;
@@ -438,23 +427,43 @@
 @sa manipulator::base, manipulator::base_no_opearator_call, manipulator::non_const_context
 */
 namespace formatter {
- using boost::logging::manipulator::base;
- using boost::logging::manipulator::non_const_context;
 
     /**
- @sa boost::logging::manipulator::class_
- */
- using boost::logging::manipulator::class_;
+ @brief What to use as base class, for your formatter classes
 
- /**
- @sa boost::logging::manipulator::is_generic
+ When using formatters and destinations, formatters must share a %base class,
+ and destinations must share a %base class - see manipulator namespace.
     */
- typedef boost::logging::manipulator::is_generic is_generic;
+ template<
+ class arg_type = typename msg_type<override>::type,
+ class ptr_type_ = default_ >
+ struct base : boost::logging::manipulator::base<arg_type, ptr_type_> {
+ };
 
     /**
         @sa boost::logging::manipulator::implement_op_equal
     */
     typedef boost::logging::manipulator::implement_op_equal implement_op_equal;
+
+ /**
+ @brief Use this when implementing your own formatter class
+
+ @param type Your own class name
+ @param op_e How will you @ref boost::logging::manipulator::implement_op_equal "implement operator=="
+
+ @param base_type (optional) The formatter base class. Unless you've specified your own formatter class, you'll be happy with the default
+ */
+ template<class type, implement_op_equal::type op_e, class base_type = base<> > struct class_
+ : boost::logging::manipulator::class_<type, op_e, base_type> {};
+
+
+ using boost::logging::manipulator::non_const_context;
+
+ /**
+ @sa boost::logging::manipulator::is_generic
+ */
+ typedef boost::logging::manipulator::is_generic is_generic;
+
 }
 
 /**
@@ -469,23 +478,41 @@
 
 */
 namespace destination {
- using boost::logging::manipulator::base;
+ /**
+ @brief What to use as base class, for your destination classes
+
+ When using formatters and destinations, formatters must share a %base class,
+ and destinations must share a %base class - see manipulator namespace.
+ */
+ template<
+ class arg_type = typename msg_type<override>::type,
+ class ptr_type_ = default_ >
+ struct base : boost::logging::manipulator::base<arg_type, ptr_type_> {
+ };
+
     using boost::logging::manipulator::non_const_context;
 
     /**
- @sa boost::logging::manipulator::class_
+ @sa boost::logging::manipulator::implement_op_equal
+ */
+ typedef boost::logging::manipulator::implement_op_equal implement_op_equal;
+
+ /**
+ @brief Use this when implementing your own destination class
+
+ @param type Your own class name
+ @param op_e How will you @ref boost::logging::manipulator::implement_op_equal "implement operator=="
+
+ @param base_type (optional) The destination base class. Unless you've specified your own destination class, you'll be happy with the default
     */
- using boost::logging::manipulator::class_;
+ template<class type, implement_op_equal::type op_e, class base_type = base<> > struct class_
+ : boost::logging::manipulator::class_<type, op_e, base_type> {};
 
     /**
         @sa boost::logging::manipulator::is_generic
     */
     typedef boost::logging::manipulator::is_generic is_generic;
 
- /**
- @sa boost::logging::manipulator::implement_op_equal
- */
- typedef boost::logging::manipulator::implement_op_equal implement_op_equal;
 }
 
 }}

Modified: sandbox/logging/boost/logging/detail/raw_doc/Doxyfile.txt
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/Doxyfile.txt (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/Doxyfile.txt 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -86,7 +86,7 @@
 # configuration options related to the input files
 #---------------------------------------------------------------------------
 INPUT = ../.. \
- ../../../../lib/logging/samples/scenarios
+ ../../../../lib/logging/samples
 INPUT_ENCODING = UTF-8
 FILE_PATTERNS = *.c \
                          *.cc \
@@ -120,7 +120,7 @@
 EXCLUDE_SYMLINKS = NO
 EXCLUDE_PATTERNS =
 EXCLUDE_SYMBOLS =
-EXAMPLE_PATH = ../../../../lib/logging/samples/scenarios
+EXAMPLE_PATH = ../../../../lib/logging/samples
 EXAMPLE_PATTERNS = *
 EXAMPLE_RECURSIVE = NO
 IMAGE_PATH =

Modified: sandbox/logging/boost/logging/detail/raw_doc/Doxyfile_web.txt
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/Doxyfile_web.txt (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/Doxyfile_web.txt 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -86,7 +86,7 @@
 # configuration options related to the input files
 #---------------------------------------------------------------------------
 INPUT = ../.. \
- ../../../../lib/logging/samples/scenarios
+ ../../../../lib/logging/samples
 INPUT_ENCODING = UTF-8
 FILE_PATTERNS = *.c \
                          *.cc \
@@ -120,7 +120,7 @@
 EXCLUDE_SYMLINKS = NO
 EXCLUDE_PATTERNS =
 EXCLUDE_SYMBOLS =
-EXAMPLE_PATH = ../../../../lib/logging/samples/scenarios
+EXAMPLE_PATH = ../../../../lib/logging/samples
 EXAMPLE_PATTERNS = *
 EXAMPLE_RECURSIVE = NO
 IMAGE_PATH =

Modified: sandbox/logging/boost/logging/detail/raw_doc/common_usage_steps_fd.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/common_usage_steps_fd.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/common_usage_steps_fd.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -4,13 +4,14 @@
 @page common_usage_steps_fd Common steps when using Formatters and destinations
 
 The usual steps when using the Boost Logging Lib are:
-- Step 1: Specify your @ref boost::logging::manipulator "formatter & destination base classes"
-- Step 2: Define your logger class(es)
-- Step 3: Define your filters (for instance, if you use levels, use a level::holder)
-- Step 4: Declare which loggers you'll use (in a header file)
-- Step 5: Define which loggers you'll use (in a source file). We need this separation
- (into Step 4 and 5, in order to make compilation times fast)
-- Step 6: Define the macros through which you'll log
+- Step 1: (optional) Specify your format and/or message class. By default, it's @c std::(w)string.
+ You'll use this when you want an @ref "optimize string class".
+- Step 2: (optional) Specify your @ref boost::logging::manipulator "formatter & destination base classes"
+- Step 3: Specify your logger class(es)
+- Step 4: Declare the loggers and the filters you'll use (in a header file)
+- Step 5: Define the macros through which you'll log
+- Step 6: Define the loggers and the filters you'll use (in a source file). We need this separation
+ (into declaring and defining the logs/filters), in order to make compilation times fast.
 - Step 7: Add @ref boost::logging::manipulator "formatters and destinations". That is, how the message is to be formatted...
 - Step 8: Use it
 - Step 9: Enjoy the results!

Modified: sandbox/logging/boost/logging/detail/raw_doc/customize_manipulator.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/customize_manipulator.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/customize_manipulator.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -1,7 +1,7 @@
 namespace boost { namespace logging {
 
 /**
-_at_page customize_manipulator Customizing manipulator arguments
+@page customize_manipulator Customizing manipulator arguments (Advanced)
 
 FIXME
 
@@ -11,6 +11,10 @@
 
 @section customize_optimize Optimizing manipulator arguments
 
+optimize::cache_string_on_str
+optimize::cache_string_several_str
+
+
 FIXME
 
 */

Modified: sandbox/logging/boost/logging/detail/raw_doc/scenarios.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/scenarios.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/scenarios.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -11,6 +11,11 @@
 - @ref common_scenarios_6
 - @ref common_scenarios_7
 - @ref common_scenarios_8
+- @ref scenario_multiple_files
+ - @ref scenario_multiple_files_program
+ - @ref scenario_multiple_files_log_h
+ - @ref scenario_multiple_files_log_cpp
+ - @ref scenario_multiple_files_main
 
 @copydoc common_usage_steps_fd
 

Modified: sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -15,6 +15,11 @@
     - @ref common_scenarios_6
     - @ref common_scenarios_7
     - @ref common_scenarios_8
+ - @ref scenario_multiple_files
+ - @ref scenario_multiple_files_program
+ - @ref scenario_multiple_files_log_h
+ - @ref scenario_multiple_files_log_cpp
+ - @ref scenario_multiple_files_main
 
 - @ref workflow
     - @ref workflow_introduction

Modified: sandbox/logging/boost/logging/detail/use_format_write.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/use_format_write.hpp (original)
+++ sandbox/logging/boost/logging/detail/use_format_write.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -24,6 +24,7 @@
 #include <boost/logging/detail/fwd.hpp>
 #include <boost/logging/format/optimize.hpp>
 #include <boost/logging/process_msg/ostream_like.hpp>
+#include <boost/logging/detail/manipulator.hpp>
 
 namespace boost { namespace logging {
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -78,10 +79,22 @@
 
 FIXME need to have more template params
 
-_at_param format_base your formatter base class
+@param format_base_type your formatter base class
 @param destination_base your destination base class
+@param thread_safety
+@param gather
 */
-template<class format_base, class destination_base> struct use_format_write {
+template<
+ class format_base_type = default_,
+ class destination_base_type = default_ ,
+ class thread_safety = default_ ,
+ class gather = default_
+ >
+ struct use_format_write {
+
+ typedef typename use_default<format_base_type, boost::logging::formatter::base<> > ::type format_base;
+ typedef typename use_default<destination_base_type, boost::logging::destination::base<> > ::type destination_base;
+
     typedef typename format_base::raw_param format_param;
     typedef typename detail::find_gather<format_param>::type gather_type;
 
@@ -89,23 +102,31 @@
     typedef typename detail::find_format_write_params<format_param, format_base, destination_base>::router_type router_type;
 };
 
-template<class format_base, class destination_base> struct logger< use_format_write<format_base, destination_base> >
+template<class format_base, class destination_base, class thread_safety, class gather> struct logger< use_format_write<format_base, destination_base, thread_safety, gather> >
     : logger_base<
         process_msg<
- typename use_format_write<format_base, destination_base>::gather_type,
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::gather_type,
             writer::format_write<
- format_base,
- destination_base,
- typename use_format_write<format_base, destination_base>::apply_format_and_write,
- typename use_format_write<format_base, destination_base>::router_type
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::format_base,
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::destination_base,
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::apply_format_and_write,
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::router_type
>
>
>
 {
- typedef typename logger_base<
+ typedef logger_base<
         process_msg<
- typename use_format_write<format_base, destination_base>::gather_type,
- writer::format_write<format_base,destination_base> > > logger_base_type;
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::gather_type,
+ writer::format_write<
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::format_base,
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::destination_base,
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::apply_format_and_write,
+ typename use_format_write<format_base, destination_base, thread_safety, gather>::router_type
+ >
+ >
+ >
+ logger_base_type;
 
     logger() {}
     BOOST_LOGGING_FORWARD_CONSTRUCTOR(logger, logger_base_type)

Modified: sandbox/logging/boost/logging/detail/util.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/util.hpp (original)
+++ sandbox/logging/boost/logging/detail/util.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -32,21 +32,9 @@
     template<class type> struct type_as_arg {};
 
 
- /*
- it makes sure this value gets created before it's used
-
- FIXME most likely I don't need this????
- */
- template<class type> struct ensure_created_before_used {
- // FIXME I need to figure out how to do this - probably by just holding char[sizeof(T) * 2] or so - align it and that's it and have an extra bool
- ensure_created_before_used(const type & val = type() ) : val(val) {}
- type & operator()() { return *this; }
- const type & operator()() const { return *this; }
- private:
- type val;
- };
-
-
+ struct default_ {};
+ template<class param, class default_type> struct use_default { typedef param type; };
+ template<class default_type> struct use_default<default_, default_type> { typedef default_type type; };
 
 
     struct ansi_unicode_char_holder {

Modified: sandbox/logging/boost/logging/filter.hpp
==============================================================================
--- sandbox/logging/boost/logging/filter.hpp (original)
+++ sandbox/logging/boost/logging/filter.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -197,10 +197,6 @@
         const process_msg_type* operator->() const { return &m_processor; }
         process_msg_type* operator->() { return &m_processor; }
 
- // in the future, this little class counts, since it'll expose a small virtual interface
- // to allow BOOST_DECLARE_LOG/BOOST_DEFINE_LOG
- //
- // it also counts since it's the same interface as log_keeper
     private:
         process_msg_type m_processor;
     };

Modified: sandbox/logging/boost/logging/format.hpp
==============================================================================
--- sandbox/logging/boost/logging/format.hpp (original)
+++ sandbox/logging/boost/logging/format.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -32,9 +32,19 @@
 #include <boost/type_traits/remove_const.hpp>
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/logging/detail/manipulator.hpp>
+#include <boost/logging/format_fwd.hpp>
 
 namespace boost { namespace logging {
 
+/**
+@file boost/logging/format.hpp
+
+Include this file when you're using @ref manipulator "formatters and destinations",
+and you want to define the logger classes, in a source file
+(using BOOST_DEFINE_LOG)
+
+*/
+
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Format and write
     //

Modified: sandbox/logging/boost/logging/format/destination/file.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/destination/file.hpp (original)
+++ sandbox/logging/boost/logging/format/destination/file.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -59,7 +59,7 @@
 };
 
 namespace detail {
- std::ios_base::open_mode open_flags(file_settings fs) {
+ inline std::ios_base::open_mode open_flags(file_settings fs) {
         std::ios_base::open_mode flags = std::ios_base::out | fs.extra_flags() ;
         if ( fs.do_append() )
             flags |= std::ios_base::app;

Modified: sandbox/logging/boost/logging/format/formatter/convert_format.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/formatter/convert_format.hpp (original)
+++ sandbox/logging/boost/logging/format/formatter/convert_format.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -50,12 +50,12 @@
     Example : write_time
     */
     namespace prepend {
- void write(const char_type * src, string_type & dest ) {
+ inline void write(const char_type * src, string_type & dest ) {
             const char_type * end = src;
             for ( ; *end; ++end);
             dest.insert( dest.begin(), src, end);
         }
- void write(const string_type & src, string_type & dest) {
+ inline void write(const string_type & src, string_type & dest) {
             dest.insert( dest.begin(), src.begin(), src.end() );
         }
         template<class string> void write(const string_type & src, boost::logging::optimize::cache_string_one_str<string> & dest) {
@@ -69,10 +69,10 @@
     /**
     */
     namespace append {
- void write(const char_type * src, string_type & dest ) {
+ inline void write(const char_type * src, string_type & dest ) {
             dest += src;
         }
- void write(const string_type & src, string_type & dest) {
+ inline void write(const string_type & src, string_type & dest) {
             dest += src;
         }
         template<class string> void write(const string_type & src, boost::logging::optimize::cache_string_one_str<string> & dest) {
@@ -86,10 +86,10 @@
     /**
     */
     namespace modify {
- void write(const char_type * src, string_type & dest ) {
+ inline void write(const char_type * src, string_type & dest ) {
             dest = src;
         }
- void write(const string_type & src, string_type & dest) {
+ inline void write(const string_type & src, string_type & dest) {
             dest = src;
         }
         template<class string> void write(const string_type & src, boost::logging::optimize::cache_string_one_str<string> & dest) {

Added: sandbox/logging/boost/logging/format_fwd.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/format_fwd.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,70 @@
+// format_fwd.hpp
+
+// Boost Logging library
+//
+// Author: John Torjo, www.torjo.com
+//
+// Copyright (C) 2007 John Torjo (see www.torjo.com for email)
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+// See http://www.torjo.com/log2/ for more details
+
+
+
+#ifndef JT28092007_format_fwd_HPP_DEFINED
+#define JT28092007_format_fwd_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/logging.hpp>
+#include <boost/logging/format/optimize.hpp>
+
+namespace boost { namespace logging {
+
+/**
+@file boost/logging/format_fwd.hpp
+
+Include this file when you're using @ref manipulator "formatters and destinations",
+and you want to declare the logger classes, in a header file
+(using BOOST_DECLARE_LOG)
+
+Example:
+
+@code
+#ifndef LOG_H_header
+#define LOG_H_header
+
+#include <boost/logging/logging.hpp>
+#include <boost/logging/format/optimize.hpp>
+
+BOOST_LOG_FORMAT_MSG( boost::logging::optimize::cache_string_one_str<> )
+
+#if defined(BOOST_LOG_DEFINE_LOGS)
+#include <boost/logging/format.hpp>
+
+typedef logger< use_format_write< > > log_type;
+#endif
+
+BOOST_DECLARE_LOG(g_l, log_type)
+BOOST_DECLARE_LOG_FILTER(g_l_filter, level::holder)
+
+#define LDBG_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_log_level, debug ) << "[dbg] "
+#define LERR_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_log_level, error ) << "[ERR] "
+#define LAPP_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_log_level, info ) << "[app] "
+
+void init_logs();
+
+#endif
+@endcode
+*/
+
+}}
+
+#endif
+

Modified: sandbox/logging/boost/logging/logging.hpp
==============================================================================
--- sandbox/logging/boost/logging/logging.hpp (original)
+++ sandbox/logging/boost/logging/logging.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -28,8 +28,23 @@
 #include <boost/logging/macros.hpp>
 #include <boost/logging/level.hpp>
 
+// just in case we might think of using formatters
+#include <boost/logging/detail/format_msg_type.hpp>
+
 namespace boost { namespace logging {
 
+/**
+@file boost/logging/logging.hpp
+
+Include this file when you're using the logging lib, but don't necessarily want to use @ref manipulator "formatters and destinations".
+If you want to use @ref manipulator "formatters and destinations", then you can include this one instead:
+
+@code
+#include <boost/logging/format_fwd.hpp>
+@endcode
+
+*/
+
 }}
 
 #endif

Modified: sandbox/logging/boost/logging/macros.hpp
==============================================================================
--- sandbox/logging/boost/logging/macros.hpp (original)
+++ sandbox/logging/boost/logging/macros.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -24,6 +24,7 @@
 #include <boost/logging/detail/fwd.hpp>
 #include <time.h>
 #include <stdlib.h>
+#include <stdio.h>
 
 namespace boost { namespace logging {
 
@@ -44,21 +45,24 @@
     Explain why the if ; else strategy: so that if withing if (x) LOG_ ... ; else blabla - still ok
         #define L_ if ( g_single_log) ; else g_single_log->read_msg().gather().msg()
 
-
+ don't want compile fast? then log.h will look easier; but - are you sure you don't want to turn compile fast off?
 
     Macros
- - BOOST_LOGGING_COMPILE_FAST_ON
- - BOOST_LOGGING_COMPILE_FAST_OFF
- - BOOST_LOGGING_COMPILE_FAST
+ - BOOST_LOG_COMPILE_FAST_ON
+ - BOOST_LOG_COMPILE_FAST_OFF
+ - BOOST_LOG_COMPILE_FAST
+ - BOOST_LOG_DEFINE_LOGS
+ - define it when you define/init your logs
+ - if compile fast is "off", this is defined by default
 */
 
-#ifdef BOOST_LOGGING_COMPILE_FAST_ON
-#define BOOST_LOGGING_COMPILE_FAST
-#elif defined(BOOST_LOGGING_COMPILE_FAST_OFF)
-#undef BOOST_LOGGING_COMPILE_FAST
+#ifdef BOOST_LOG_COMPILE_FAST_ON
+#define BOOST_LOG_COMPILE_FAST
+#elif defined(BOOST_LOG_COMPILE_FAST_OFF)
+#undef BOOST_LOG_COMPILE_FAST
 #else
 // by default, turned on
-#define BOOST_LOGGING_COMPILE_FAST
+#define BOOST_LOG_COMPILE_FAST
 #endif
 
 namespace detail {
@@ -86,39 +90,125 @@
             long long ignore = reinterpret_cast<long long>(&log);
             // we need to force the compiler to force creation of the log
             if ( time(0) < 0)
- if ( time(0) < ignore)
+ if ( time(0) < ignore) {
+ printf("LOGGING LIB internal error - should NEVER happen. Please report this to the author of the lib");
                     exit(0);
+ }
         }
     };
+
+
+ /*
+ Note that BOOST_DECLARE_LOG_FILTER & BOOST_DEFINE_LOG_FILTER define a function,
+ so that we don't run into the problem of using an object before it's initialized.
+
+ However, client code doesn't need to be aware of that.
+ So, for instance, clients will say:
+
+ BOOST_DEFINE_LOG_FILTER(g_level_holder, level::holder);
+
+ g_level_holder->set_enabled(level::debug);
+ */
+ template<class type, type& (*func)() > struct log_filter_keeper {
+
+ const type* operator->() const { return &(func()); }
+ type* operator->() { return &(func()); }
+ };
+
 }
 
-#ifdef BOOST_LOGGING_COMPILE_FAST
+#ifdef BOOST_LOG_COMPILE_FAST
+// ****** Fast compile ******
+
+#define BOOST_DECLARE_LOG_WITH_STRING(name,type,str_type) \
+ type& name ## _boost_log_impl_(); extern boost::logging::detail::log_keeper<type, name ## _boost_log_impl_ > name;
+
+// logger< process_msg<gather, do_writer<> > l;
 
 // FIXME need to reimplement them when using compile_fast
-#define BOOST_DECLARE_LOG(name,type) type& name ## _boost_log_impl_(); extern boost::logging::detail::log_keeper<type, name ## _boost_log_impl_ > name;
+#define BOOST_DECLARE_LOG(name,type) BOOST_DECLARE_LOG_WITH_STRING(name,type, ::boost::logging::msg_type<>::type )
+
 #define BOOST_DEFINE_LOG(name,type) type& name ## _boost_log_impl_() \
     { static type i; return i; } \
     namespace { boost::logging::detail::fake_using_log ensure_log_is_created_before_main ## name ( name ## _boost_log_impl_() ); } \
     boost::logging::detail::log_keeper<type, name ## _boost_log_impl_ > name;
 
+
+
 #else
+// don't compile fast
 
-// FIXME need to reimplement them when using compile_fast
 #define BOOST_DECLARE_LOG(name,type) type& name ## _boost_log_impl_(); extern boost::logging::detail::log_keeper<type, name ## _boost_log_impl_ > name;
 #define BOOST_DEFINE_LOG(name,type) type& name ## _boost_log_impl_() \
     { static type i; return i; } \
     namespace { boost::logging::detail::fake_using_log ensure_log_is_created_before_main ## name ( name ## _boost_log_impl_() ); } \
     boost::logging::detail::log_keeper<type, name ## _boost_log_impl_ > name;
 
+/**
+ Advanced
+*/
+#define BOOST_DECLARE_LOG_WITH_STRING(name,type,str_type) BOOST_DECLARE_LOG(name,type)
+
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Defining filter Macros
+
+/*
+ when compile fast is "off", we always need BOOST_LOG_DEFINE_LOGS, to get access to the logger class typedefs;
+*/
+#if !defined(BOOST_LOG_COMPILE_FAST)
+#if !defined(BOOST_LOG_DEFINE_LOGS)
+
+#define BOOST_LOG_DEFINE_LOGS
+
 #endif
+#endif
+
+
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Filter Macros
+
+#define BOOST_DECLARE_LOG_FILTER_NO_NAMESPACE_PREFIX(name,type) type& name ## _boost_log_filter_impl_(); extern boost::logging::detail::log_filter_keeper<type, name ## _boost_log_filter_impl_ > name;
+#define BOOST_DEFINE_LOG_FILTER_NO_NAMESPACE_PREFIX(name,type) type& name ## _boost_log_filter_impl_() \
+ { static type i; return i; } \
+ namespace { boost::logging::detail::fake_using_log ensure_log_is_created_before_main ## name ( name ## _boost_log_filter_impl_() ); } \
+ boost::logging::detail::log_filter_keeper<type, name ## _boost_log_filter_impl_ > name;
 
 
+/**
+@note
+ It is assumed that @c type is a filter class from the @c boost::logging namespace.
+ In case you're creating your own filter class, make sure to have it in the boost::logging namespace. \n
+ Or, you can use the BOOST_DECLARE_LOG_FILTER_NO_NAMESPACE_PREFIX macro instead
+*/
+#define BOOST_DECLARE_LOG_FILTER(name,type) BOOST_DECLARE_LOG_FILTER_NO_NAMESPACE_PREFIX(name, ::boost::logging:: type)
+
+/**
+@note
+ It is assumed that @c type is a filter class from the @c boost::logging namespace.
+ In case you're creating your own filter class, make sure to have it in the boost::logging namespace. \n
+ Or, you can use the BOOST_DEFINE_LOG_FILTER_NO_NAMESPACE_PREFIX macro instead.
+*/
+#define BOOST_DEFINE_LOG_FILTER(name,type) BOOST_DEFINE_LOG_FILTER_NO_NAMESPACE_PREFIX(name, ::boost::logging:: type)
+
+
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Log Macros
+
 
 
 #define BOOST_LOG_USE_LOG(l, do_func, is_log_enabled) if ( !(is_log_enabled) ) ; else l -> do_func
 
-#define BOOST_LOG_USE_LOG_IF_LEVEL(l, holder, the_level) BOOST_LOG_USE_LOG(l, read_msg().gather().out(), holder.is_enabled(::boost::logging::level:: the_level) )
+#define BOOST_LOG_USE_LOG_IF_LEVEL(l, holder, the_level) BOOST_LOG_USE_LOG(l, read_msg().gather().out(), holder->is_enabled(::boost::logging::level:: the_level) )
 
 #define BOOST_LOG_USE_LOG_IF_FILTER(l, the_filter) BOOST_LOG_USE_LOG(l, read_msg().gather().out(), the_filter)
 
@@ -128,10 +218,34 @@
 
 
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Format and Destination Macros
+
+/**
 
+@note
+ When using BOOST_LOG_FORMAT_MSG or BOOST_LOG_DESTINATION_MSG, you must not be within any namespace scope.
 
+ This is because when using this macro, as @c msg_class, you can specify any of your class, or
+ something residing in @c boost::logging namespace.
+*/
+#define BOOST_LOG_FORMAT_MSG(msg_class) \
+ namespace boost { namespace logging { \
+ template<> struct formatter::msg_type<override> { typedef msg_class & type; }; \
+ }}
+
+/**
 
+@note
+ When using BOOST_LOG_FORMAT_MSG or BOOST_LOG_DESTINATION_MSG, you must not be within any namespace scope.
 
+ This is because when using this macro, as @c msg_class, you can specify any of your class, or
+ something residing in @c boost::logging namespace.
+*/
+#define BOOST_LOG_DESTINATION_MSG(msg_class) \
+ namespace boost { namespace logging { \
+ template<> struct destination::msg_type<override> { typedef const msg_class & type; }; \
+ }}
 
 
 

Modified: sandbox/logging/boost/logging/process_msg.hpp
==============================================================================
--- sandbox/logging/boost/logging/process_msg.hpp (original)
+++ sandbox/logging/boost/logging/process_msg.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -104,8 +104,6 @@
     template<class gather_msg, class write_msg> struct process_msg {
         typedef process_msg<gather_msg, write_msg> self;
 
- // FIXME we should have a way to specify a template gather_msg - for example useful for cache_string
-
         process_msg() {}
         BOOST_LOGGING_FORWARD_CONSTRUCTOR(process_msg,m_writer)
 
@@ -128,14 +126,29 @@
         write_msg m_writer;
     };
 
- template<class arg_type = const char*> struct write_call_func {
- typedef void (*func)(arg_type) ;
- write_call_func(func f) : m_f(f) {}
- void operator()(arg_type a) { f(a); }
- private:
- func m_f;
- };
-
+ namespace detail {
+ template<class param> struct do_write_base {
+ virtual void operator()(param arg) = 0;
+ };
+
+ template<class gather_msg, class write_msg> struct do_write : do_write_base<typename gather_msg::param> {
+ typedef typename gather_msg::param param;
+
+ BOOST_LOGGING_FORWARD_CONSTRUCTOR(do_write,m_writer)
+
+ virtual void operator()(param arg) {
+ m_writer(arg);
+ }
+ write_msg m_writer;
+ };
+
+ template<class gather_msg> struct call_write {
+ typedef typename gather_msg::param param;
+ typedef typename do_write_base<param> writer_type;
+ writer_type * m_writer;
+ call_write(writer_type * writer) : m_writer(writer) {}
+ };
+ }
 
 }}
 

Modified: sandbox/logging/boost/logging/process_msg/ostream_like.hpp
==============================================================================
--- sandbox/logging/boost/logging/process_msg/ostream_like.hpp (original)
+++ sandbox/logging/boost/logging/process_msg/ostream_like.hpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -118,6 +118,9 @@
     In our case, 1. and 2. are the same
 */
 template<class stream_type = std::basic_ostringstream<char_type> > struct return_raw_stream {
+ // what does the gather_msg class return?
+ typedef stream_type& param;
+
     return_raw_stream() {}
     return_raw_stream(const return_raw_stream& other) : m_out( other.m_out.str() ) {}
 
@@ -162,6 +165,9 @@
 
 */
 template<class stream_type = std::basic_ostringstream<char_type> > struct return_str {
+ // what does the gather_msg class return?
+ typedef std::basic_string<char_type> & param;
+
     return_str() {}
     return_str(const return_str& other) : m_out(other.m_out.str()) {}
 
@@ -187,6 +193,9 @@
         int prepend_size = 10,
         int append_size = 10,
         class stream_type = std::basic_ostringstream<char_type> > struct return_cache_str {
+
+ // what does the gather_msg class return?
+ typedef cache_string & param;
     
     return_cache_str() {}
     return_cache_str(const return_cache_str& other) : m_out(other.m_out.str()) {}

Added: sandbox/logging/lib/logging/samples/basic_usage/ReadMe.txt
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/ReadMe.txt 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1 @@
+Example of using Boost Logging Lib v2

Added: sandbox/logging/lib/logging/samples/basic_usage/basic_usage.sln
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/basic_usage.sln 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_usage", "basic_usage.vcproj", "{011E74A4-F775-4EE3-B195-03B308F7D2F0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {011E74A4-F775-4EE3-B195-03B308F7D2F0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {011E74A4-F775-4EE3-B195-03B308F7D2F0}.Debug|Win32.Build.0 = Debug|Win32
+ {011E74A4-F775-4EE3-B195-03B308F7D2F0}.Release|Win32.ActiveCfg = Release|Win32
+ {011E74A4-F775-4EE3-B195-03B308F7D2F0}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal

Added: sandbox/logging/lib/logging/samples/basic_usage/basic_usage.vcproj
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/basic_usage.vcproj 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="basic_usage"
+ ProjectGUID="{011E74A4-F775-4EE3-B195-03B308F7D2F0}"
+ RootNamespace="basic_usage"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".,../../../.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_LOG_COMPILE_FAST_OFF;_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="D:\boosts\boost_1_33_1\bin\boost\libs\filesystem\build\libboost_filesystem.lib\vc-8_0\debug\threading-multi"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\dir_spec.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\file_statistics.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\log.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\main.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\parse_file.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\util.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\dir_spec.h"
+ >
+ </File>
+ <File
+ RelativePath=".\extensions.h"
+ >
+ </File>
+ <File
+ RelativePath=".\file_statistics.h"
+ >
+ </File>
+ <File
+ RelativePath=".\log.h"
+ >
+ </File>
+ <File
+ RelativePath=".\parse_file.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\util.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>

Added: sandbox/logging/lib/logging/samples/basic_usage/dir_spec.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/dir_spec.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,65 @@
+#include "dir_spec.h"
+
+// Wherever you use logs, include this ;)
+#include "log.h"
+
+#include "parse_file.h"
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/convenience.hpp>
+
+dir_spec::dir_spec(const std::string & path, const extensions & ext) : m_path(path), m_ext(ext), m_file_count(0) {
+ LAPP_ << "Parsing dir : " << fs::system_complete(path).string() << ", looking for " << ext;
+}
+
+
+dir_spec::~dir_spec(void)
+{
+}
+
+void dir_spec::iterate() {
+ iterate_dir( m_path);
+
+ LAPP_ << "\n\nAll Files :\n"
+ << "\n No of Files : " << m_file_count
+ << "\n"
+ << "\n Code : " << m_stats.code
+ << "\n Comments : " << m_stats.commented
+ << "\n Empty : " << m_stats.empty
+ << "\n Total : " << m_stats.total
+ << "\n"
+ << "\n Avg C/L : " << (int)((double)m_stats.non_space_chars / (double)(m_stats.code + m_stats.commented))
+ ;
+
+}
+
+void dir_spec::iterate_dir(const fs::path & dir) {
+ LDBG_ << "Parsing dir " << fs::system_complete(dir).string();
+
+ if ( !fs::exists( dir) ) {
+ LERR_ << "Dir " << dir.string() << " does not exist anymore!";
+ return ;
+ }
+
+ for ( fs::directory_iterator b(dir), e; b != e; ++b) {
+ if ( fs::is_directory(*b))
+ iterate_dir(*b);
+ else {
+ // file
+ bool matches_ext = false;
+ for ( extensions::array::const_iterator b_ext = m_ext.vals.begin(), e_ext = m_ext.vals.end(); b_ext != e_ext; ++b_ext)
+ if ( fs::extension(*b) == "." + *b_ext) {
+ matches_ext = true;
+ break;
+ }
+
+ if ( matches_ext) {
+ m_stats += parse_file(*b);
+ ++m_file_count;
+ }
+ else
+ LDBG_ << "Ignoring file " << b->string();
+ }
+ }
+
+}
+

Added: sandbox/logging/lib/logging/samples/basic_usage/dir_spec.h
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/dir_spec.h 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,33 @@
+#ifndef jt_DIR_SPEC_H
+#define jt_DIR_SPEC_H
+
+#include "extensions.h"
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
+
+#include "file_statistics.h"
+
+/**
+ Contains a directory specification
+ - what directories we're to search
+ - what type of files we're to seach
+*/
+struct dir_spec
+{
+ dir_spec(const std::string & path, const extensions & ext);
+ ~dir_spec(void);
+
+ void iterate();
+
+private:
+ void iterate_dir(const fs::path & dir);
+
+private:
+ std::string m_path;
+ extensions m_ext;
+
+ file_statistics m_stats;
+ int m_file_count;
+};
+
+#endif

Added: sandbox/logging/lib/logging/samples/basic_usage/extensions.h
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/extensions.h 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,35 @@
+#ifndef jt_EXTENSIONS_H_
+#define jt_EXTENSIONS_H_
+
+#include <vector>
+#include <string>
+#include <iostream>
+
+struct extensions
+{
+ typedef std::vector<std::string> array;
+ array vals;
+
+ extensions(const std::string & ext = "") {
+ if ( !ext.empty())
+ vals.push_back(ext);
+ }
+
+ extensions & add(const std::string & ext) {
+ vals.push_back(ext);
+ return *this;
+ }
+};
+
+inline std::ostream & operator<<(std::ostream & out, const extensions& exts) {
+ out << "[";
+ for ( extensions::array::const_iterator b = exts.vals.begin(), e = exts.vals.end(); b != e ; ++b) {
+ if ( b != exts.vals.begin())
+ out << "; ";
+ out << "." << (*b);
+ }
+ out << "]";
+ return out;
+}
+
+#endif

Added: sandbox/logging/lib/logging/samples/basic_usage/file_statistics.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/file_statistics.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,13 @@
+#include "file_statistics.h"
+
+file_statistics::file_statistics() : commented(0), empty(0), code(0), total(0), non_space_chars(0) {
+}
+
+void file_statistics::operator+=(const file_statistics& to_add) {
+ commented += to_add.commented;
+ empty += to_add.empty;
+ code += to_add.code;
+ total += to_add.total;
+ non_space_chars += to_add.non_space_chars;
+}
+

Added: sandbox/logging/lib/logging/samples/basic_usage/file_statistics.h
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/file_statistics.h 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,23 @@
+#ifndef jt_FILE_STATISTICS_h
+#define jt_FILE_STATISTICS_h
+
+/**
+ statics (lines of code) from a file
+*/
+struct file_statistics
+{
+ file_statistics();
+
+ int commented;
+ int empty;
+ int code;
+ int total;
+
+ // this contains the nubmer of chars, once each line is trimmed
+ unsigned long non_space_chars;
+
+ void operator+=(const file_statistics& to_add);
+};
+
+#endif
+

Added: sandbox/logging/lib/logging/samples/basic_usage/log.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/log.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,22 @@
+// so that we have access to the log_type typedef
+#define BOOST_LOG_DEFINE_LOGS
+#include "log.h"
+
+// Step 6: Define the filters and loggers you'll use
+BOOST_DEFINE_LOG(g_l, log_type)
+BOOST_DEFINE_LOG_FILTER(g_l_filter, level::holder)
+
+using namespace boost::logging;
+
+void init_logs() {
+ // Add formatters and destinations
+ // That is, how the message is to be formatted...
+ g_l->writer().add_formatter( formatter::idx() );
+ g_l->writer().add_formatter( formatter::time("$hh:$mm.$ss ") );
+ g_l->writer().add_formatter( formatter::append_enter() );
+
+ // ... and where should it be written to
+ g_l->writer().add_destination( destination::cout() );
+ g_l->writer().add_destination( destination::dbg_window() );
+ g_l->writer().add_destination( destination::file("out.txt") );
+}

Added: sandbox/logging/lib/logging/samples/basic_usage/log.h
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/log.h 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,27 @@
+#ifndef LOG_H_header
+#define LOG_H_header
+
+#include <boost/logging/format_fwd.hpp>
+
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
+
+#if defined(BOOST_LOG_DEFINE_LOGS)
+#include <boost/logging/format.hpp>
+
+// Step 3 : Specify your logging class(es)
+typedef boost::logging::logger< boost::logging::use_format_write< > > log_type;
+#endif
+
+// Step 4: declare which filters and loggers you'll use
+BOOST_DECLARE_LOG_FILTER(g_l_filter, level::holder)
+BOOST_DECLARE_LOG(g_l, log_type)
+
+// Step 5: define the macros through which you'll log
+#define LDBG_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_l_filter, debug ) << "[dbg] "
+#define LERR_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_l_filter, error ) << "[ERR] "
+#define LAPP_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_l_filter, info )
+
+void init_logs();
+
+#endif

Added: sandbox/logging/lib/logging/samples/basic_usage/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/main.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,133 @@
+// main.cpp : Where the main() action is
+
+/**
+@page scenario_multiple_files A more complex example - a Line counter application
+
+- @ref scenario_multiple_files_program
+- @ref scenario_multiple_files_log_h
+- @ref scenario_multiple_files_log_cpp
+- @ref scenario_multiple_files_main
+
+
+
+@section scenario_multiple_files_program What the program does
+
+This represents a @b very basic program to count lines of code from a directory and its subdirs.
+It's very basic on purpose, just to show you how to use the Boost Log library v2 in your own projects.
+
+It counts code lines, empty lines, and comment lines.
+Again, it's a very simple program, thus:
+- an empty line : contains only spaces
+- a comment line:
+ - C++ : starts with //
+ - C: the start of a C comment is when the line @b starts with "/ *";
+ the end of a C comment is when the line @b ends with "* /";
+ anything else is not considered a comment
+
+
+Command line arguments:
+- 1st: the dir to search (default : ".")
+- 2nd: the extensions to search (default: "cpp;c;h;hpp")
+- 3rd: verbosity: "d" : debug, "i" : info, "e" : error (default : "i")
+
+
+About logging:
+- You have multiple levels (in this example: debug < info < error)
+- Message is formatted like this: <tt>time [idx] message <enter> </tt>
+- You have <b>one log</b>, which writes to several log destinations:
+ the console, the debug output window, and the "out.txt" file
+- all the logs are @b declared in "log.h" file
+- all the logs are @b defined in "log.cpp" file
+
+The highlights of setting up the logging are :
+- @c log.h file - declaring the log/macros to use the log
+- @c log.cpp file - defining the log, and the @c init_logs function (initializing the log)
+- @c main.cpp file - reading the command line, and calls the @c init_logs function
+
+You can check out the whole example: <tt>libs/logging/samples/basic_usage</tt>.
+
+@section scenario_multiple_files_log_h The log.h file
+
+@include basic_usage/log.h
+
+@section scenario_multiple_files_log_cpp The log.cpp file
+
+@include basic_usage/log.cpp
+
+@section scenario_multiple_files_main The main.cpp file
+
+@include basic_usage/main.cpp
+
+*/
+
+#include "stdafx.h"
+
+// Wherever you use logs, include this ;)
+#include "log.h"
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+#include "dir_spec.h"
+#include "extensions.h"
+#include "util.h"
+#include <boost/filesystem/path.hpp>
+
+using namespace boost::logging;
+namespace fs = boost::filesystem;
+
+int main(int argc, char * argv[])
+{
+ fs::path::default_name_check( fs::no_check);
+
+ init_logs();
+
+ std::string dir = ".";
+ if ( argc > 1)
+ dir = argv[1];
+
+ extensions ext;
+ {
+ std::string ext_str = "cpp;c;h;hpp";
+ if ( argc > 2)
+ ext_str = argv[2];
+ str_replace(ext_str, ";", " ");
+ str_replace(ext_str, ",", " ");
+ str_replace(ext_str, ".", "");
+ std::istringstream in( ext_str);
+ std::string word;
+ while ( in >> word)
+ ext.add(word);
+ }
+
+ level::type lev = level::info;
+ std::string lev_str = "info";
+ if ( argc > 3) {
+ lev_str = argv[3];
+ if ( lev_str == "d") {
+ lev = level::debug;
+ lev_str = "debug";
+ }
+ else if ( lev_str == "i") {
+ lev = level::info;
+ lev_str = "info";
+ }
+ else if ( lev_str == "e") {
+ lev = level::error;
+ lev_str = "error";
+ }
+ else {
+ LERR_ << "invalid verbosity " << lev_str << "; available options: d, i, e";
+ lev_str = "info";
+ }
+ }
+ g_l_filter->set_enabled(lev);
+
+ LAPP_ << "Verbosity: " << lev_str;
+
+ dir_spec spec(dir, ext);
+ spec.iterate();
+ return 0;
+}
+

Added: sandbox/logging/lib/logging/samples/basic_usage/parse_file.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/parse_file.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,65 @@
+#include "parse_file.h"
+
+// Wherever you use logs, include this ;)
+#include "log.h"
+
+#include "util.h"
+#include <fstream>
+
+file_statistics parse_file(const fs::path& file) {
+ LDBG_ << "Parsing file " << file.string();
+
+ file_statistics stats;
+ std::ifstream in( file.string().c_str());
+ std::string line;
+ bool within_c_comment = false;
+ while ( std::getline(in, line) ) {
+ trim_str(line);
+
+ if ( line.empty() )
+ ++stats.empty;
+
+ bool within_comment = within_c_comment;
+ if ( line.size() >= 2)
+ if ( line.find("//") == 0)
+ within_comment = true;
+
+ if ( line.size() >= 2)
+ if ( line.find("/*") == 0) {
+ within_comment = true;
+ within_c_comment = true;
+ }
+
+
+ if ( within_comment)
+ ++stats.commented;
+ else {
+ if ( !line.empty())
+ ++stats.code;
+ }
+
+ ++stats.total;
+ stats.non_space_chars += (int)line.size();
+
+ // see if C comment has ended
+ if ( within_c_comment)
+ if ( line.size() >= 2)
+ if ( line.substr( line.size() - 2, 2) == "*/")
+ within_c_comment = false;
+ }
+
+ if ( stats.total < 1)
+ LERR_ << "Could not read from file " << file.string();
+
+ LAPP_ << "File " << file.string() << ":\n"
+ << "\n Code : " << stats.code
+ << "\n Comments : " << stats.commented
+ << "\n Empty : " << stats.empty
+ << "\n Total : " << stats.total
+ << "\n"
+ << "\n Avg C/L : " << (int)((double)stats.non_space_chars / (double)(stats.code + stats.commented))
+ ;
+
+ return stats;
+}
+

Added: sandbox/logging/lib/logging/samples/basic_usage/parse_file.h
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/parse_file.h 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,11 @@
+#ifndef jt_PARSE_FILE_h
+#define jt_PARSE_FILE_h
+
+#include "file_statistics.h"
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
+
+file_statistics parse_file(const fs::path& file);
+
+#endif
+

Added: sandbox/logging/lib/logging/samples/basic_usage/stdafx.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/stdafx.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// basic_usage.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file

Added: sandbox/logging/lib/logging/samples/basic_usage/stdafx.h
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/stdafx.h 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,17 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#include <stdio.h>
+#include <tchar.h>
+
+
+
+// TODO: reference additional headers your program requires here

Added: sandbox/logging/lib/logging/samples/basic_usage/util.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/util.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,34 @@
+#include "util.h"
+#include <algorithm>
+
+std::string lo_case( const std::string & str) {
+ std::string lo;
+ lo.resize( str.length());
+ std::transform( str.begin(), str.end(), lo.begin(), tolower);
+ return lo;
+}
+
+void trim_str(std::string & str) {
+ std::string::iterator begin = str.begin(), end = str.end();
+ while ( begin < end)
+ if ( isspace(*begin)) ++begin;
+ else break;
+
+ while ( begin < end)
+ if ( isspace(end[-1]) ) --end;
+ else break;
+
+ str = std::string(begin, end);
+}
+
+void str_replace( std::string & str, const std::string & find, const std::string & replace) {
+ size_t pos = 0;
+ while ( true) {
+ size_t next = str.find( find, pos);
+ if ( next == std::string::npos)
+ break;
+ str.erase( next, find.length() );
+ str.insert( next, replace);
+ pos = next + replace.size();
+ }
+}

Added: sandbox/logging/lib/logging/samples/basic_usage/util.h
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/basic_usage/util.h 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -0,0 +1,10 @@
+#ifndef jt_UTIL_h
+#define jt_UTIL_h
+
+#include <string>
+
+std::string lo_case( const std::string & str) ;
+void trim_str(std::string & str) ;
+void str_replace( std::string & str, const std::string & find, const std::string & replace) ;
+
+#endif

Modified: sandbox/logging/lib/logging/samples/scenarios/custom_fmt_dest.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/custom_fmt_dest.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/custom_fmt_dest.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -76,36 +76,34 @@
 
 
 #define BOOST_LOGGING_COMPILE_FAST_OFF
-#include <boost/logging/logging.hpp>
-#include <boost/logging/format.hpp>
+#include <boost/logging/format_fwd.hpp>
 
-using namespace boost::logging;
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
 
-// Optimize : use a cache string, to make formatting the message faster
-typedef optimize::cache_string_one_str<> cache_string;
+#include <boost/logging/format.hpp>
 
-// Step 1: specify your formatter & destination base classes
-typedef formatter::base< cache_string& > formatter_base;
-typedef destination::base< const std::string & > destination_base;
+// Step 3 : Specify your logging class(es)
+typedef boost::logging::logger< boost::logging::use_format_write< > > log_type;
 
-// Step 2 : Define your logging class(es)
-typedef logger< use_format_write<formatter_base,destination_base> > log_type;
 
-// Step 3 : Set up a filter
-filter::no_ts g_log_filter ;
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
+BOOST_DECLARE_LOG(g_l, log_type)
 
-// Step 4: declare which loggers you'll use
-BOOST_DECLARE_LOG(g_l, log_type) // normally these go into a header file ;)
+// Step 5: define the macros through which you'll log
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() )
 
-// Step 5: define which loggers you'll use
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
 BOOST_DEFINE_LOG(g_l, log_type)
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
 
-// Step 6: define the macros through which you'll log
-#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter.is_enabled() )
+
+using namespace boost::logging;
 
 // Example of custom formatter:
 // dump the no. of seconds since start of program
-struct secs_since_start : formatter::class_<secs_since_start, formatter_base, formatter::implement_op_equal::no_context> {
+struct secs_since_start : formatter::class_<secs_since_start, formatter::implement_op_equal::no_context> {
     ::time_t m_start;
     secs_since_start() : m_start( ::time(0) ) {}
     void operator()(param str) const {
@@ -119,7 +117,7 @@
 // Example of custom destination:
 // Dump each message as XML
 struct as_xml :
- destination::class_<as_xml, destination_base, formatter::implement_op_equal::has_context>,
+ destination::class_<as_xml, formatter::implement_op_equal::has_context>,
         formatter::non_const_context<std::ofstream> {
 
     std::string m_name;
@@ -152,11 +150,11 @@
     std::string hello = "hello", world = "world";
     L_ << hello << ", " << world;
 
- g_log_filter.set_enabled(false);
+ g_log_filter->set_enabled(false);
     L_ << "this will not be written to the log";
     L_ << "this won't be written to the log";
 
- g_log_filter.set_enabled(true);
+ g_log_filter->set_enabled(true);
     L_ << "good to be back ;) " << i++;
 
     // Step 9 : Enjoy!

Modified: sandbox/logging/lib/logging/samples/scenarios/fastest_no_ostr_like.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/fastest_no_ostr_like.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/fastest_no_ostr_like.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -59,20 +59,20 @@
 using namespace boost::logging;
 
 
-// Step 1 : Define your logging class(es)
+// Step 1 : Specify your logging class(es)
 typedef logger< destination::cout > app_log_type;
 typedef logger< destination::file > err_log_type;
 
 // Step 2 : Set up a filter
-filter::no_ts g_log_filter ;
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
 
 // Step 3: declare which loggers you'll use
 app_log_type g_log_app;
 err_log_type g_log_err("err.txt");
 
 // Step 4: define the macros through which you'll log
-#define LAPP_ BOOST_LOG_USE_SIMPLE_LOG_IF_FILTER(g_log_app, g_log_filter.is_enabled() )
-#define LERR_ BOOST_LOG_USE_SIMPLE_LOG_IF_FILTER(g_log_err, g_log_filter.is_enabled() )
+#define LAPP_ BOOST_LOG_USE_SIMPLE_LOG_IF_FILTER(g_log_app, g_log_filter->is_enabled() )
+#define LERR_ BOOST_LOG_USE_SIMPLE_LOG_IF_FILTER(g_log_err, g_log_filter->is_enabled() )
 
 void fastest_no_ostr_like_example() {
     // Step 5: use it...
@@ -82,12 +82,12 @@
     std::string hello = "hello", world = "world";
     LAPP_(hello + ", " + world + "\n");
 
- g_log_filter.set_enabled(false);
+ g_log_filter->set_enabled(false);
     LAPP_("this will not be written to the log");
     LAPP_("this won't be written to the log");
     LERR_("this error is not logged ");
 
- g_log_filter.set_enabled(true);
+ g_log_filter->set_enabled(true);
     LAPP_("good to be back ;) \n" );
     LERR_("second error \n" );
 

Modified: sandbox/logging/lib/logging/samples/scenarios/fastest_use_ostr_like.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/fastest_use_ostr_like.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/fastest_use_ostr_like.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -60,20 +60,20 @@
 using namespace boost::logging;
 
 
-// Step 1 : Define your logging class(es)
+// Step 1 : Specify your logging class(es)
 typedef logger< process_msg<gather::ostream_like::return_str<>, destination::cout> > app_log_type;
 typedef logger< process_msg<gather::ostream_like::return_str<>, destination::file> > err_log_type;
 
 // Step 2 : Set up a filter
-filter::no_ts g_log_filter ;
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
 
 // Step 3: declare which loggers you'll use
 app_log_type g_log_app;
 err_log_type g_log_err("err.txt");
 
 // Step 4: define the macros through which you'll log
-#define LAPP_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_app, g_log_filter.is_enabled() )
-#define LERR_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_err, g_log_filter.is_enabled() )
+#define LAPP_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_app, g_log_filter->is_enabled() )
+#define LERR_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_err, g_log_filter->is_enabled() )
 
 void fastest_use_ostr_like_example() {
     // Step 5: use it...
@@ -85,12 +85,12 @@
     std::string hello = "hello", world = "world";
     LAPP_ << hello << ", " << world << "\n";
 
- g_log_filter.set_enabled(false);
+ g_log_filter->set_enabled(false);
     LAPP_ << "this will not be written to the log";
     LAPP_ << "this won't be written to the log";
     LERR_ << "this error is not logged " << i++;
 
- g_log_filter.set_enabled(true);
+ g_log_filter->set_enabled(true);
     LAPP_ << "good to be back ;) " << i++ << "\n";
     LERR_ << "second error " << i++ << "\n";
 

Modified: sandbox/logging/lib/logging/samples/scenarios/mul_levels_mul_logers.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/mul_levels_mul_logers.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/mul_levels_mul_logers.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -78,38 +78,35 @@
 
 
 #define BOOST_LOGGING_COMPILE_FAST_OFF
-#include <boost/logging/logging.hpp>
-#include <boost/logging/format.hpp>
-
-using namespace boost::logging;
+#include <boost/logging/format_fwd.hpp>
 
-// Optimize : use a cache string, to make formatting the message faster
-typedef optimize::cache_string_one_str<> cache_string;
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
 
-// Step 1: specify your formatter & destination base classes
-typedef formatter::base< cache_string& > formatter_base;
-typedef destination::base< const std::string & > destination_base;
+#include <boost/logging/format.hpp>
 
-// Step 2 : Define your logging class(es)
-typedef logger< use_format_write<formatter_base,destination_base> > log_type;
+// Step 3 : Specify your logging class(es)
+typedef boost::logging::logger< boost::logging::use_format_write< > > log_type;
 
-// Step 3 : If you use levels, Set up a log level holder
-level::holder g_log_level; // holds the application log level
 
-// Step 4: declare which loggers you'll use
-BOOST_DECLARE_LOG(g_log_err, log_type) // normally these go into a header file ;)
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_level, level::holder ) // holds the application log level
+BOOST_DECLARE_LOG(g_log_err, log_type)
 BOOST_DECLARE_LOG(g_log_app, log_type)
 BOOST_DECLARE_LOG(g_log_dbg, log_type)
 
-// Step 5: define which loggers you'll use
+// Step 5: define the macros through which you'll log
+#define LDBG_ BOOST_LOG_USE_LOG_IF_LEVEL(g_log_dbg, g_log_level, debug ) << "[dbg] "
+#define LERR_ BOOST_LOG_USE_LOG_IF_LEVEL(g_log_err, g_log_level, error )
+#define LAPP_ BOOST_LOG_USE_LOG_IF_LEVEL(g_log_app, g_log_level, info ) << "[app] "
+
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG_FILTER(g_log_level, level::holder ) // holds the application log level
 BOOST_DEFINE_LOG(g_log_err, log_type)
 BOOST_DEFINE_LOG(g_log_app, log_type)
 BOOST_DEFINE_LOG(g_log_dbg, log_type)
 
-// Step 6: define the macros through which you'll log
-#define LDBG_ BOOST_LOG_USE_LOG_IF_LEVEL(g_log_dbg, g_log_level, debug ) << "[dbg] "
-#define LERR_ BOOST_LOG_USE_LOG_IF_LEVEL(g_log_err, g_log_level, error )
-#define LAPP_ BOOST_LOG_USE_LOG_IF_LEVEL(g_log_app, g_log_level, info ) << "[app] "
+using namespace boost::logging;
 
 void mul_levels_mul_logers_example() {
     // Step 7: add formatters and destinations
@@ -143,11 +140,11 @@
     std::string hello = "hello", world = "world";
     LAPP_ << hello << ", " << world;
 
- g_log_level.set_enabled(level::error);
+ g_log_level->set_enabled(level::error);
     LDBG_ << "this will not be written anywhere";
     LAPP_ << "this won't be written anywhere either";
 
- g_log_level.set_enabled(level::info);
+ g_log_level->set_enabled(level::info);
     LAPP_ << "good to be back ;) " << i++;
     LERR_ << "second error " << i++;
 

Modified: sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -47,32 +47,26 @@
 
 
 #define BOOST_LOGGING_COMPILE_FAST_OFF
-#include <boost/logging/logging.hpp>
 #include <boost/logging/format.hpp>
 
 using namespace boost::logging;
+// Step 3 : Specify your logging class(es)
+typedef logger< use_format_write< > > log_type;
 
-// Step 1: specify your formatter & destination base classes
-typedef formatter::base< std::string& > formatter_base;
-typedef destination::base< const std::string & > destination_base;
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_level, level::holder ) // holds the application log level
+BOOST_DECLARE_LOG(g_l, log_type)
 
-// Step 2 : define your logging class(es)
-typedef logger< use_format_write<formatter_base,destination_base> > log_type;
-
-// Step 3 : If you use levels, Set up a log level holder
-level::holder g_log_level; // holds the application log level
-
-// Step 4: declare which loggers you'll use
-BOOST_DECLARE_LOG(g_l, log_type) // normally this goes into a header file ;)
-
-// Step 5: define which loggers you'll use
-BOOST_DEFINE_LOG(g_l, log_type)
-
-// Step 6: define the macros through which you'll log
+// Step 5: define the macros through which you'll log
 #define LDBG_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_log_level, debug )
 #define LERR_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_log_level, error )
 #define LAPP_ BOOST_LOG_USE_LOG_IF_LEVEL(g_l, g_log_level, info )
 
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG_FILTER(g_log_level, level::holder ) // holds the application log level
+BOOST_DEFINE_LOG(g_l, log_type)
+
+
 void test_mul_levels_one_logger() {
     // Step 7: add formatters and destinations
     // That is, how the message is to be formatted...
@@ -93,12 +87,12 @@
     std::string hello = "hello", world = "world";
     LAPP_ << hello << ", " << world;
 
- g_log_level.set_enabled(level::error);
+ g_log_level->set_enabled(level::error);
     LDBG_ << "this will not be written anywhere";
     LAPP_ << "this won't be written anywhere either";
     LERR_ << "second error " << i++;
 
- g_log_level.set_enabled(level::info);
+ g_log_level->set_enabled(level::info);
     LAPP_ << "good to be back ;) " << i++;
     LERR_ << "third error " << i++;
 

Modified: sandbox/logging/lib/logging/samples/scenarios/mul_loggers_one_filter.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/mul_loggers_one_filter.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/mul_loggers_one_filter.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -77,39 +77,34 @@
 
 
 #define BOOST_LOGGING_COMPILE_FAST_OFF
-#include <boost/logging/logging.hpp>
-#include <boost/logging/format.hpp>
-
-using namespace boost::logging;
-
-// Optimize : use a cache string, to make formatting the message faster
-typedef optimize::cache_string_one_str<> cache_string;
+#include <boost/logging/format_fwd.hpp>
 
-// Step 1: specify your formatter & destination base classes
-typedef formatter::base< cache_string& > formatter_base;
-typedef destination::base< const std::string & > destination_base;
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
 
-// Step 2 : Define your logging class(es)
-typedef logger< use_format_write<formatter_base,destination_base> > log_type;
+#include <boost/logging/format.hpp>
+using namespace boost::logging;
 
-// Step 3 : Set up a filter
-filter::no_ts g_log_filter ;
+// Step 3 : Specify your logging class(es)
+typedef logger< use_format_write< > > log_type;
 
-// Step 4: declare which loggers you'll use
-BOOST_DECLARE_LOG(g_log_err, log_type) // normally these go into a header file ;)
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
+BOOST_DECLARE_LOG(g_log_err, log_type)
 BOOST_DECLARE_LOG(g_log_app, log_type)
 BOOST_DECLARE_LOG(g_log_dbg, log_type)
 
-// Step 5: define which loggers you'll use
+// Step 5: define the macros through which you'll log
+#define LDBG_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_dbg, g_log_filter->is_enabled() ) << "[dbg] "
+#define LERR_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_err, g_log_filter->is_enabled() )
+#define LAPP_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_app, g_log_filter->is_enabled() ) << "[app] "
+
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
 BOOST_DEFINE_LOG(g_log_err, log_type)
 BOOST_DEFINE_LOG(g_log_app, log_type)
 BOOST_DEFINE_LOG(g_log_dbg, log_type)
 
-// Step 6: define the macros through which you'll log
-#define LDBG_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_dbg, g_log_filter.is_enabled() ) << "[dbg] "
-#define LERR_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_err, g_log_filter.is_enabled() )
-#define LAPP_ BOOST_LOG_USE_LOG_IF_FILTER(g_log_app, g_log_filter.is_enabled() ) << "[app] "
-
 void mul_logger_one_filter_example() {
     // Step 7: add formatters and destinations
     // That is, how the message is to be formatted and where should it be written to
@@ -141,12 +136,12 @@
     std::string hello = "hello", world = "world";
     LAPP_ << hello << ", " << world;
 
- g_log_filter.set_enabled(false);
+ g_log_filter->set_enabled(false);
     LDBG_ << "this will not be written anywhere";
     LAPP_ << "this won't be written anywhere either";
     LERR_ << "this error is not logged " << i++;
 
- g_log_filter.set_enabled(true);
+ g_log_filter->set_enabled(true);
     LAPP_ << "good to be back ;) " << i++;
     LERR_ << "second error " << i++;
 

Modified: sandbox/logging/lib/logging/samples/scenarios/no_levels_with_route.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/no_levels_with_route.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/no_levels_with_route.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -70,32 +70,30 @@
 
 
 #define BOOST_LOGGING_COMPILE_FAST_OFF
-#include <boost/logging/logging.hpp>
+#include <boost/logging/format_fwd.hpp>
+
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_several_str<> )
+
 #include <boost/logging/format.hpp>
 
 using namespace boost::logging;
 
-typedef optimize::cache_string_several_str<> cache_string;
 
-// Step 1: specify your formatter & destination base classes
-typedef formatter::base< cache_string& > formatter_base;
-typedef destination::base< const std::string & > destination_base;
+// Step 3 : Specify your logging class(es)
+typedef logger< use_format_write< > > log_type;
 
-// Step 2 : define your logging class(es)
-typedef logger< use_format_write<formatter_base,destination_base> > log_type;
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
+BOOST_DECLARE_LOG(g_l, log_type)
 
-// Step 3 : Set up a filter
-filter::no_ts g_log_filter ;
+// Step 5: define the macros through which you'll log
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() )
 
-// Step 4: declare which loggers you'll use
-BOOST_DECLARE_LOG(g_l, log_type) // normally this goes into a header file ;)
-
-// Step 5: define which loggers you'll use
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
 BOOST_DEFINE_LOG(g_l, log_type)
 
-// Step 6: define the macros through which you'll log
-#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter.is_enabled() )
-
 void no_levels_with_route_example() {
     // Step 7: add formatters and destinations
     // That is, how the message is to be formatted...
@@ -134,11 +132,11 @@
     std::string hello = "hello", world = "world";
     L_ << hello << ", " << world;
 
- g_log_filter.set_enabled(false);
+ g_log_filter->set_enabled(false);
     L_ << "this will not be written anywhere";
     L_ << "this won't be written anywhere either";
 
- g_log_filter.set_enabled(true);
+ g_log_filter->set_enabled(true);
     L_ << "good to be back ;) " << i++;
 
     // Step 9 : Enjoy!

Modified: sandbox/logging/lib/logging/samples/scenarios/one_loger_one_filter.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/one_loger_one_filter.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/one_loger_one_filter.cpp 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -50,32 +50,30 @@
 
 
 #define BOOST_LOGGING_COMPILE_FAST_OFF
-#include <boost/logging/logging.hpp>
+#include <boost/logging/format_fwd.hpp>
+
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
+
 #include <boost/logging/format.hpp>
 
 using namespace boost::logging;
 
-// Optimize : use a cache string, to make formatting the message faster
-typedef optimize::cache_string_one_str<> cache_string;
-
-// Step 1: specify your formatter & destination base classes
-typedef formatter::base< cache_string& > formatter_base;
-typedef destination::base< const std::string & > destination_base;
+// Step 3 : Specify your logging class(es)
+typedef logger< use_format_write< > > log_type;
 
-// Step 2 : Define your logging class(es)
-typedef logger< use_format_write<formatter_base,destination_base> > log_type;
 
-// Step 3 : Set up a filter
-filter::no_ts g_log_filter ;
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
+BOOST_DECLARE_LOG(g_l, log_type)
 
-// Step 4: declare which loggers you'll use
-BOOST_DECLARE_LOG(g_l, log_type) // normally these go into a header file ;)
+// Step 5: define the macros through which you'll log
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() )
 
-// Step 5: define which loggers you'll use
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
 BOOST_DEFINE_LOG(g_l, log_type)
 
-// Step 6: define the macros through which you'll log
-#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter.is_enabled() )
 
 void one_logger_one_filter_example() {
     // Step 7: add formatters and destinations
@@ -95,11 +93,11 @@
     std::string hello = "hello", world = "world";
     L_ << hello << ", " << world;
 
- g_log_filter.set_enabled(false);
+ g_log_filter->set_enabled(false);
     L_ << "this will not be written to the log";
     L_ << "this won't be written to the log";
 
- g_log_filter.set_enabled(true);
+ g_log_filter->set_enabled(true);
     L_ << "good to be back ;) " << i++;
 
     // Step 9 : Enjoy!

Modified: sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj
==============================================================================
--- sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj (original)
+++ sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -558,13 +558,6 @@
                                 <File
                                         RelativePath="..\..\scenarios\mul_levels_one_logger.cpp"
>
- <FileConfiguration
- Name="Test|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
                                 </File>
                                 <File
                                         RelativePath="..\..\scenarios\mul_loggers_one_filter.cpp"
@@ -795,6 +788,14 @@
>
                                 </File>
                                 <File
+ RelativePath="..\..\..\..\..\boost\logging\format_fwd.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\boost\logging\detail\format_msg_type.hpp"
+ >
+ </File>
+ <File
                                         RelativePath="..\..\..\..\..\boost\logging\detail\manipulator.hpp"
>
                                 </File>

Modified: sandbox/logging/lib/logging/src/changelog.txt
==============================================================================
--- sandbox/logging/lib/logging/src/changelog.txt (original)
+++ sandbox/logging/lib/logging/src/changelog.txt 2007-10-28 08:48:46 EDT (Sun, 28 Oct 2007)
@@ -1,5 +1,19 @@
 
 
+v0.9, 28 oct 2007
+- use_format_write has 4 params now, I've added 2 new params: thread_safety and gather
+ - if you want to leave something unchanged, use "default_" as argument
+- added more complex example: Line Counter application
+- Breaking change:
+ - filters are declared with BOOST_DECLARE_LOG_FILTER, and defined with BOOST_DEFINE_LOG_FILTER
+ - filters are now used with operator->, instead of "."
+ - Example:
+ BOOST_DEFINE_LOG_LEVEL(g_log_level, level::holder )
+ ...
+ g_log_level->set_enabled(level::error);
+ - rationale: filters, same as levels, could be used before main
+
+
 v0.8.3, 22 oct 2007
 - now have 8 scenarios
 - updated documentation


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk