---
scribo/ChangeLog | 4 +
scribo/scribo/debug/logger.hh | 249 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 250 insertions(+), 3 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 69814de..1122e11 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,7 @@
+2012-05-07 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * scribo/debug/logger.hh: Improve log system.
+
2012-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
Remove useless targets in scribo/src/binarization.
diff --git a/scribo/scribo/debug/logger.hh b/scribo/scribo/debug/logger.hh
index f16dd89..5822cf3 100644
--- a/scribo/scribo/debug/logger.hh
+++ b/scribo/scribo/debug/logger.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 EPITA Research and Development Laboratory
+// Copyright (C) 2011, 2012 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of Olena.
@@ -27,6 +27,8 @@
#ifndef SCRIBO_CORE_LOGGER_HH
# define SCRIBO_CORE_LOGGER_HH
+# include <iostream>
+# include <ctype.h>
# include <mln/core/concept/image.hh>
# include <mln/data/wrap.hh>
# include <mln/value/int_u8.hh>
@@ -34,6 +36,7 @@
# include <mln/io/pbm/save.hh>
# include <mln/io/pgm/save.hh>
# include <mln/io/ppm/save.hh>
+# include <mln/util/timer.hh>
namespace scribo
{
@@ -41,15 +44,48 @@ namespace scribo
namespace debug
{
+ /*! \brief Enum defining different level of image logging
+
+ According to the debug level set in #logger_ the image may
+ be saved or not.
+ */
enum Level
{
None = 0,
Special, // Reserved
Results,
AuxiliaryResults,
- All
+ All,
+ InvalidLevel // Reserved
};
+ /*! \brief Enum defining different modes of text logging
+
+ According to the verbose mode set in #logger_ the text may
+ be logged or not.
+ */
+ enum VerboseMode
+ {
+ Mute = 0,
+ UserDebug, // Reserved
+ Time,
+ Low,
+ Medium,
+ Full,
+ Invalid, // Reserved
+ };
+
+
+ /*! \brief returns the corresponding verboseMode from its name.
+
+ \internal
+ \warning Don't forget to update this function if a VerboseMode
+ value is added.
+ \endinternal
+ */
+ VerboseMode txt_to_verbose_mode(const std::string& name);
+
+
namespace internal
{
@@ -60,6 +96,22 @@ namespace scribo
public:
static logger_& instance();
+ /// Text Logging
+ /// @{
+ bool is_verbose() const;
+ bool is_at_verbose_mode(VerboseMode mode) const;
+
+ bool set_verbose_mode(VerboseMode mode);
+ VerboseMode verbose_mode() const;
+
+ void set_verbose_prefix(const std::string& prefix);
+
+ void log(VerboseMode mode, const std::string& text);
+ /// @}
+
+
+ /// Image Logging
+ /// @{
bool is_enabled() const;
bool is_at_level(Level level) const;
@@ -72,6 +124,37 @@ namespace scribo
template <typename I>
void log_image(Level dbg_level,
const Image<I>& ima, const char *name);
+ /// @}
+
+ /*! \brief Time Logging
+
+ This class provides two timers in order to performs
+ benchmarks inside a program.
+
+ Local time logging is meant to be used for benchmarking a
+ small portion of code, whereas global time logging is meant
+ to benchmark a whole program.
+
+ They can be used both at the same time.
+
+ Stopping time logging will output the computed time if
+ Verbose mode is higher or equal to #Time.
+ */
+ /// @{
+ void start_local_time_logging();
+ void stop_local_time_logging(const std::string& time_title);
+
+ void start_global_time_logging();
+ void stop_global_time_logging(const std::string& time_title);
+ /// @}
+
+
+ /*! \brief Quickly logs text.
+ It uses the default log mode to know if the text
+ */
+ template <typename V>
+ logger_& operator<<(const V&v);
+ logger_& operator<<(std::ostream& (*f)(std::ostream&));
private: // Methods
logger_();
@@ -110,6 +193,12 @@ namespace scribo
private: // Attributes
Level level_;
+ VerboseMode verbose_mode_;
+ std::string verbose_prefix_;
+ std::ostream& stream_;
+
+ mln::util::timer t_local_;
+ mln::util::timer t_global_;
};
} // end of namespace scribo::debug::internal
@@ -124,6 +213,14 @@ namespace scribo
namespace internal
{
+ std::string to_upper(const std::string& s)
+ {
+ std::string out(s);
+ for (size_t i = 0; i < s.size(); ++i)
+ out[i] = toupper(s[i]);
+ return out;
+ }
+
inline
logger_&
logger_::instance()
@@ -135,7 +232,10 @@ namespace scribo
inline
logger_::logger_()
- : level_(None)
+ : level_(None),
+ verbose_mode_(Mute),
+ stream_(std::cerr),
+ verbose_prefix_("LOG: ")
{
// Magick::InitializeMagick(0);
}
@@ -143,6 +243,7 @@ namespace scribo
inline
logger_::logger_(const logger_&)
+ : stream_(std::cerr)
{
abort();
}
@@ -150,6 +251,64 @@ namespace scribo
inline
bool
+ logger_::is_verbose() const
+ {
+ return verbose_mode_ > Mute;
+ }
+
+
+ inline
+ bool
+ logger_::is_at_verbose_mode(VerboseMode mode) const
+ {
+ return mode == verbose_mode_;
+ }
+
+
+ inline
+ bool
+ logger_::set_verbose_mode(VerboseMode mode)
+ {
+ if (mode != Invalid)
+ {
+ verbose_mode_ = mode;
+ return true;
+ }
+ return false;
+ }
+
+
+ inline
+ VerboseMode
+ logger_::verbose_mode() const
+ {
+ return verbose_mode_;
+ }
+
+
+ inline
+ void
+ logger_::set_verbose_prefix(const std::string& prefix)
+ {
+ verbose_prefix_ = prefix;
+ }
+
+
+ inline
+ void
+ logger_::log(VerboseMode mode, const std::string& text)
+ {
+# ifndef SCRIBO_NDEBUG
+ if (verbose_mode_ < mode)
+ return;
+
+ std::cerr << verbose_prefix_ << text << std::endl;
+# endif // ! SCRIBO_NDEBUG
+ }
+
+
+ inline
+ bool
logger_::is_enabled() const
{
return level_ != None;
@@ -212,6 +371,44 @@ namespace scribo
}
+ inline
+ void
+ logger_::start_local_time_logging()
+ {
+ t_local_.restart();
+ }
+
+
+ inline
+ void
+ logger_::stop_local_time_logging(const std::string& time_title)
+ {
+ t_local_.stop();
+ if (verbose_mode_ >= Time)
+ std::cerr << time_title << " " << t_local_ <<
"s" << std::endl;
+ }
+
+
+ inline
+ void
+ logger_::start_global_time_logging()
+ {
+ t_global_.restart();
+ }
+
+
+ inline
+ void
+ logger_::stop_global_time_logging(const std::string& time_title)
+ {
+ t_global_.stop();
+ if (verbose_mode_ >= Time)
+ std::cerr << time_title << " " << t_global_ <<
"s" << std::endl;
+ }
+
+
+ // Private dispatch
+
template <unsigned n, typename I>
void
logger_::log_image_dispatch(const value::int_u<n>&, const
Image<I>& ima, const char *name)
@@ -273,6 +470,26 @@ namespace scribo
mln::debug::filename(name + ".pgm"));
}
+
+ template <typename V>
+ logger_&
+ logger_::operator<<(const V& v)
+ {
+ if (verbose_mode_ >= Low)
+ stream_ << v;
+ return *this;
+ }
+
+
+ logger_&
+ logger_::operator<<(std::ostream& (*f)(std::ostream&))
+ {
+ if (verbose_mode_ >= Low)
+ f(stream_);
+ return *this;
+ }
+
+
} // end of namespace scribo::debug::internal
@@ -284,6 +501,32 @@ namespace scribo
}
+ VerboseMode txt_to_verbose_mode(const std::string& name)
+ {
+ struct mode_name
+ {
+ const char *name;
+ VerboseMode mode;
+ };
+ static const mode_name mode[] = {
+ { "MUTE", Mute },
+ { "USERDEBUG", UserDebug },
+ { "TIME", Time },
+ { "LOW", Low },
+ { "MEDIUM", Medium },
+ { "FULL", Full },
+ { "INVALID", Invalid }
+ };
+
+ unsigned i;
+ std::string name_ = internal::to_upper(name);
+ for (i = 0; mode[i].mode != Invalid; ++i)
+ if (mode[i].name == name_)
+ break;
+
+ return mode[i].mode;
+ };
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::debug
--
1.7.2.5