$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
logger.hh
1 // Copyright (C) 2011, 2012, 2013, 2014 EPITA Research and Development
2 // Laboratory (LRDE).
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
30 
31 #ifndef SCRIBO_CORE_LOGGER_HH
32 # define SCRIBO_CORE_LOGGER_HH
33 
34 # include <stack>
35 # include <iostream>
36 # include <ctype.h>
37 # include <mln/core/concept/image.hh>
38 # include <mln/data/wrap.hh>
39 # include <mln/value/int_u8.hh>
40 # include <mln/debug/filename.hh>
41 # include <mln/io/pbm/save.hh>
42 # include <mln/io/pgm/save.hh>
43 # include <mln/io/ppm/save.hh>
44 # include <mln/util/timer.hh>
45 
46 namespace scribo
47 {
48 
49  namespace debug
50  {
51 
57  enum Level
58  {
59  None = 0,
60  Special, // Reserved
61  Results,
62  AuxiliaryResults,
63  All,
64  InvalidLevel // Reserved
65  };
66 
73  {
74  Mute = 0,
75  UserDebug, // Reserved
76  Time,
77  Low,
78  Medium,
79  Full,
80  Invalid, // Reserved
81  };
82 
83 
91  VerboseMode txt_to_verbose_mode(const std::string& name);
92 
93 
94 
95  namespace internal
96  {
97  using namespace mln;
98 
99  class logger_
100  {
101  public:
102  static logger_& instance();
103 
106  bool is_verbose() const;
107  bool is_at_verbose_mode(VerboseMode mode) const;
108 
111  bool set_default_verbose_mode(VerboseMode mode);
112  VerboseMode default_verbose_mode() const;
113 
116  bool set_verbose_mode(VerboseMode mode);
117  VerboseMode verbose_mode() const;
118 
119  void set_verbose_prefix(const std::string& prefix);
120 
121  void log(VerboseMode mode, const std::string& text);
123 
124 
127  bool is_enabled() const;
128  bool is_at_level(Level level) const;
129 
130  void set_level(Level level);
131  Level level() const;
132 
133  void set_filename_prefix(const char *name);
134  const char *filename_prefix() const;
135 
136  template <typename I>
137  void log_image(Level dbg_level,
138  const Image<I>& ima, const char *name);
140 
149 
150  void start_time_logging();
151  void stop_time_logging(const std::string& time_title);
153 
154 
158  template <typename V>
159  logger_& operator<<(const V&v);
160  logger_& operator<<(std::ostream& (*f)(std::ostream&));
161 
162  private: // Methods
163  logger_();
164  logger_(const logger_&);
165 
166  ~logger_();
167 
168  template <unsigned n, typename I>
169  void log_image_dispatch(const value::int_u<n>&,
170  const Image<I>& ima, const char *name);
171 
172  template <unsigned n, typename I>
173  void
174  log_image_dispatch(const value::label<n>&,
175  const Image<I>& ima, const char *name);
176 
177  template <typename I>
178  void log_image_dispatch(const mln_value(I)&,
179  const Image<I>& ima, const char *name);
180 
181  template <typename I>
182  void log_image_dispatch(const value::rgb8&,
183  const Image<I>& ima, const char *name);
184 
185  template <typename I>
186  void log_image_dispatch(const bool&,
187  const Image<I>& ima, const char *name);
188 
189  template <typename I>
190  void log_image_rgb(const I& ima, const std::string& name);
191 
192  template <typename I>
193  void log_image_bool(const I& ima, const std::string& name);
194 
195  template <typename I>
196  void log_image_grayscale(const I& ima, const std::string& name);
197 
198  private: // Attributes
199  Level level_;
200 
201  VerboseMode verbose_mode_;
202  VerboseMode default_verbose_mode_;
203  std::string verbose_prefix_;
204  std::ostream& stream_;
205 
206  std::stack<mln::util::timer> t_locals_;
207  };
208 
209  } // end of namespace scribo::debug::internal
210 
211 
217 
218 
219 # ifndef MLN_INCLUDE_ONLY
220 
221  namespace internal
222  {
223 
224  inline
225  std::string to_upper(const std::string& s)
226  {
227  std::string out(s);
228  for (size_t i = 0; i < s.size(); ++i)
229  out[i] = toupper(s[i]);
230  return out;
231  }
232 
233  inline
234  logger_&
235  logger_::instance()
236  {
237  static logger_ log;
238  return log;
239  }
240 
241 
242  inline
243  logger_::logger_()
244  : level_(None),
245  verbose_mode_(Mute),
246  default_verbose_mode_(Low),
247  verbose_prefix_("LOG: "),
248  stream_(std::cerr)
249  {
250  }
251 
252 
253  inline
254  logger_::logger_(const logger_&)
255  : stream_(std::cerr)
256  {
257  abort();
258  }
259 
260  inline
261  logger_::~logger_()
262  {
263  // If this is not True, then a timer has not been stopped!
264  mln_assertion(t_locals_.size() == 0);
265  }
266 
267  inline
268  bool
269  logger_::is_verbose() const
270  {
271  return verbose_mode_ > Mute;
272  }
273 
274 
275  inline
276  bool
278  {
279  return mode == verbose_mode_;
280  }
281 
282 
283  inline
284  bool
286  {
287  if (mode != Invalid)
288  {
289  default_verbose_mode_ = mode;
290  return true;
291  }
292  return false;
293  }
294 
295 
296  inline
299  {
300  return default_verbose_mode_;
301  }
302 
303 
304  inline
305  bool
307  {
308  if (mode != Invalid)
309  {
310  verbose_mode_ = mode;
311  return true;
312  }
313  return false;
314  }
315 
316 
317  inline
319  logger_::verbose_mode() const
320  {
321  return verbose_mode_;
322  }
323 
324 
325  inline
326  void
327  logger_::set_verbose_prefix(const std::string& prefix)
328  {
329  verbose_prefix_ = prefix;
330  }
331 
332 
333  inline
334  void
335  logger_::log(VerboseMode mode, const std::string& text)
336  {
337  // Avoid warnings about unused arguments in non-debug mode.
338  (void) mode;
339  (void) text;
340 
341 # ifndef SCRIBO_NDEBUG
342  if (verbose_mode_ < mode)
343  return;
344 
345  std::cerr << verbose_prefix_ << text << std::endl;
346 # endif // ! SCRIBO_NDEBUG
347  }
348 
349 
350  inline
351  bool
352  logger_::is_enabled() const
353  {
354  return level_ != None;
355  }
356 
357 
358  inline
359  bool
360  logger_::is_at_level(Level level) const
361  {
362  return level_ >= level;
363  }
364 
365 
366  inline
367  void
368  logger_::set_filename_prefix(const char *name)
369  {
371  }
372 
373 
374  inline
375  const char *
377  {
379  }
380 
381 
382  inline
383  void logger_::set_level(Level level)
384  {
385  level_ = level;
386  }
387 
388 
389  inline
390  Level logger_::level() const
391  {
392  return level_;
393  }
394 
395 
396  template <typename I>
397  void
398  logger_::log_image(Level dbg_level,
399  const Image<I>& ima, const char *name)
400  {
401  // Avoid warnings about unused arguments in non-debug mode.
402  (void) dbg_level;
403  (void) ima;
404  (void) name;
405 
406 # ifndef SCRIBO_NDEBUG
407  if (level_ < dbg_level)
408  return;
409 
410  std::cerr << "Logger - Saving image " << name << std::endl;
411  mln_assertion(exact(ima).is_valid());
412 
413  typedef mln_value(I) V;
414  log_image_dispatch(V(), ima, name);
415 # endif // ! SCRIBO_NDEBUG
416  }
417 
418 
419  inline
420  void
422  {
423  t_locals_.push(mln::util::timer());
424  t_locals_.top().restart();
425  }
426 
427 
428  inline
429  void
430  logger_::stop_time_logging(const std::string& time_title)
431  {
432  mln_assertion(! t_locals_.empty());
433 
434  t_locals_.top().stop();
435  if (verbose_mode_ >= Time)
436  std::cerr << time_title << " " << t_locals_.top() << "s" << std::endl;
437  t_locals_.pop();
438  }
439 
440 
441  // Private dispatch
442 
443  template <unsigned n, typename I>
444  void
445  logger_::log_image_dispatch(const value::int_u<n>&, const Image<I>& ima, const char *name)
446  {
447  log_image_grayscale(exact(ima), name);
448  }
449 
450  template <unsigned n, typename I>
451  void
452  logger_::log_image_dispatch(const value::label<n>&, const Image<I>& ima, const char *name)
453  {
454  log_image_grayscale(exact(ima), name);
455  }
456 
457 
458  template <typename I>
459  void
460  logger_::log_image_dispatch(const value::rgb8&, const Image<I>& ima, const char *name)
461  {
462  log_image_rgb(exact(ima), name);
463  }
464 
465  template <typename I>
466  void
467  logger_::log_image_dispatch(const bool&, const Image<I>& ima, const char *name)
468  {
469  log_image_bool(exact(ima), name);
470  }
471 
472 
473  // template <typename I>
474  // void
475  // logger_::log_image_generic(const I& ima, const std::string& name)
476  // {
477  // mln::io::magick::save(ima, mln::debug::filename(name + ".png"));
478  // }
479 
480  template <typename I>
481  void
482  logger_::log_image_rgb(const I& ima, const std::string& name)
483  {
484  mln::io::ppm::save(ima, mln::debug::filename(name + ".ppm"));
485  }
486 
487 
488  template <typename I>
489  void
490  logger_::log_image_bool(const I& ima, const std::string& name)
491  {
492  mln::io::pbm::save(ima, mln::debug::filename(name + ".pbm"));
493  }
494 
495 
496  template <typename I>
497  void
498  logger_::log_image_grayscale(const I& ima, const std::string& name)
499  {
500  mln::io::pgm::save(data::wrap(value::int_u8(), ima),
501  mln::debug::filename(name + ".pgm"));
502  }
503 
504 
505  template <typename V>
506  logger_&
507  logger_::operator<<(const V& v)
508  {
509  if (verbose_mode_ >= default_verbose_mode_)
510  stream_ << v;
511  return *this;
512  }
513 
514 
515  inline
516  logger_&
517  logger_::operator<<(std::ostream& (*f)(std::ostream&))
518  {
519  if (verbose_mode_ >= default_verbose_mode_)
520  f(stream_);
521  return *this;
522  }
523 
524 
525  } // end of namespace scribo::debug::internal
526 
527 
528  inline
530  logger()
531  {
532  return scribo::debug::internal::logger_::instance();
533  }
534 
535 
536  inline
537  VerboseMode txt_to_verbose_mode(const std::string& name)
538  {
539  struct mode_name
540  {
541  const char *name;
542  VerboseMode mode;
543  };
544  static const mode_name mode[] = {
545  { "MUTE", Mute },
546  { "USERDEBUG", UserDebug },
547  { "TIME", Time },
548  { "LOW", Low },
549  { "MEDIUM", Medium },
550  { "FULL", Full },
551  { "INVALID", Invalid }
552  };
553 
554  unsigned i;
555  std::string name_ = internal::to_upper(name);
556  for (i = 0; mode[i].mode != Invalid; ++i)
557  if (mode[i].name == name_)
558  break;
559 
560  return mode[i].mode;
561  };
562 
563 # endif // ! MLN_INCLUDE_ONLY
564 
565  } // end of namespace scribo::debug
566 
567 } // end of namespace scribo
568 
569 #endif // ! SCRIBO_CORE_LOGGER_HH