$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
trace.hh
1 // Copyright (C) 2013 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_DEBUG_TRACE_HH
27 # define MLN_DEBUG_TRACE_HH
28 
32 
33 # include <ctime>
34 
35 # include <iostream>
36 # include <string>
37 # include <stack>
38 
39 # include <mln/core/contract.hh>
40 
41 # define mln_trace(S) \
42  mln::debug::trace mln_trace_(S); \
43  (void) mln_trace_;
44 
45 # define mln_trace_warning(S) \
46  mln::debug::trace::warning(S);
47 
48 namespace mln
49 {
50 
51  namespace debug
52  {
53 
72 
80  class trace
81  {
82  public:
83 
84  trace(const std::string& scope);
85  ~trace();
86 
87  static void resume();
88  static void stop();
89  static void warning(const std::string& message);
90 
93  static bool quiet;
94  static unsigned tab;
95  static bool full_trace;
97 
98  private:
99  static std::stack<std::clock_t> start_times_;
100  static std::stack<std::string> scopes_;
101  static unsigned max_tab_;
102  static bool is_quiet_;
103  };
104 
105 
106 # ifndef MLN_INCLUDE_ONLY
107 
108 
109  // Initialization of static attributes.
110 # ifndef MLN_WO_GLOBAL_VARS
111 
112  bool trace::quiet = true;
113  unsigned trace::tab = 0;
114  bool trace::full_trace = false;
115 
116  std::stack<std::clock_t> trace::start_times_;
117  std::stack<std::string> trace::scopes_;
118  unsigned trace::max_tab_ = 0;
119  bool trace::is_quiet_ = quiet;
120 
121 # endif // ! MLN_WO_GLOBAL_VARS
122 
123 
124 
125  // Implementations.
126 
127  inline
128  trace::trace(const std::string& scope)
129  {
130  if (quiet)
131  return;
132 
133  start_times_.push(std::clock());
134  scopes_.push(scope);
135 
136  if ((tab != 0) && (max_tab_ == tab))
137  std::cout << std::endl;
138 
139  for (unsigned i = 0; i < tab; ++i)
140  std::cout << " ";
141  std::cout << scope << " {";
142 
143  max_tab_ = ++tab;
144  }
145 
146 
147  inline
148  trace::~trace()
149  {
150  if (quiet)
151  return;
152 
153  std::string scope = scopes_.top();
154  scopes_.pop();
155 
156  bool has_inner_trace = (max_tab_ == tab);
157  --tab;
158 
159  if (!has_inner_trace)
160  for (unsigned i = 0; i < tab; ++i)
161  std::cout << " ";
162 
163  std::cout << "} ";
164 
165  if (!has_inner_trace)
166  std::cout << scope << " ";
167 
168  mln_assertion(! start_times_.empty());
169  std::clock_t now = std::clock();
170 
171  if (start_times_.top() > now)
172  std::cerr
173  << "Warning: Clock skew detected (start time in the future)."
174  << std::endl;
175 
176  if (start_times_.top() < now)
177  {
178  std::cout
179  << "- "
180  << ((float(now) - float(start_times_.top())) / CLOCKS_PER_SEC)
181  << "s ";
182  }
183 
184  start_times_.pop();
185 
186  if (has_inner_trace || (max_tab_ - tab > 1))
187  std::cout << std::endl;
188  }
189 
190 
191  inline
192  void trace::resume()
193  {
194  quiet = is_quiet_;
195  }
196 
197 
198  inline
199  void trace::stop()
200  {
201  is_quiet_ = quiet;
202  if (!full_trace)
203  quiet = true;
204  }
205 
206 
207  inline
208  void trace::warning(const std::string& message)
209  {
210  std::cerr << "Warning: " << message << std::endl;
211  }
212 
213 # endif // ! MLN_INCLUDE_ONLY
214 
215  } // end of namespace mln::debug
216 
217 } // end of namespace mln
218 
219 
220 #endif // ! MLN_DEBUG_TRACE_HH