DebOut.hh 6.48 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
// (C) Copyright 2014 by Autodesk, Inc.
//
// The information contained herein is confidential, proprietary
// to Autodesk,  Inc.,  and considered a trade secret as defined
// in section 499C of the penal code of the State of California.
// Use of  this information  by  anyone  other  than  authorized
// employees of Autodesk, Inc.  is granted  only under a written
// non-disclosure agreement,  expressly  prescribing  the  scope
// and manner of such use.

11
12
#ifndef BASE_DEBOUT_HH_INCLUDED
#define BASE_DEBOUT_HH_INCLUDED
13

14
// DEB_ON is defined, or not, in CMakeLists.txt for primary project
15
#ifndef DEB_ON
16

17
18
#define DEB_module(SS)
#define DEB_enter_func
19
#define DEB_only(CC)
20
21
#define DEB_exec(LL, AA) {}
#define DEB_exec_if(CC, LL, AA) {}
22
23
24
25
26
27
28
#define DEB_out(LL, AA) {}
#define DEB_out_if(CC, LL, AA) {}
#define DEB_line(LL, AA) {}
#define DEB_line_if(CC, LL, AA) {}
#define DEB_warning(LL, AA) {}
#define DEB_warning_if(CC, LL, AA) {}
#define DEB_mesh_if(CC, LL, FF, MM) {}
29

30
31
#define DEB_error(AA) {}
#define DEB_error_if(CC, AA) {}
32

33
#else // DEB_ON
34
35

#include <string>
36
#include <vector>
37
#include <array>
38

39
namespace Debug {
40

41
42
typedef unsigned int uint;

43
const int INVALID_LEVEL = -1;
44
45
const char* const ERROR = "ERROR";
const char* const WARNING = "WARNING";
46

47
class Stream;
48

49
struct Command
50
{
51
  enum Type
52
  {
53
54
55
    END     = 0x01,
    END_LF  = 0x03,
    END_ERR = 0x07
56
  };
57
58
  
  Type cmd;
59

60
  Command(Type _cmd) : cmd(_cmd) {}
61
62
63
};


64
// Class used to maintain Stream's CallStack
65
66
// This does not currently contain a pointer to the file streamer used
// but might do in future.
67
class Enter
68
69
{
public:
70
71
72
  const char* flnm_;  //!< File name for this DEB_enter
  int nmbr_; //!< deb_nmbr for this function.
  int lvl_; //!< deb_level for this function.
73
  int id_;       /*!< Unique identifier for this Enter (used in ANCHORS) */
74
  int outs_; /*!< Number of DEB_outs encountered within this function
75
76
                    determining whether a given DEB_out should include or omit
                    a call stack or exit trace. */
77
  int lns_; /*!< Number of call stack indents including this call. */
78

79
  Enter(const char* const _flnm, const char* const _fnct, int& _nmbr, int& _lvl);
80
  ~Enter();
81
82

  //! pass the output on the level or not?
83
  bool pass(const int _lvl) const { return _lvl <= lvl_; }
84

85
  Stream& stream();
86

87
88
89
  Command end() const { return Command::END; }
  Command end_lf() const { return Command::END_LF; }
  Command end_err() const { return Command::END_ERR; }
90
};
91

92
//! This is a private implementation for Stream
93
class File;
94

95
class Stream
96
97
{
public:
98
  enum Flags
99
  {
100
101
102
103
    APPEND   = 0x01,
    HTML     = 0x02,
    RETAIN   = 0x04,
    KEEP_OPEN = 0x08
104
105
  };

106
107
public:
  //! Constructor.
108
  Stream(
109
110
111
    const char* _flnm = nullptr,   //!< [in] Filename if file based.
    const uint _flags = APPEND    //!< [in] bit-field type identifier
  );
112
  ~Stream();
113

114
115
  const std::string& string() const;
  const char* c_str() const { return string().c_str(); }
116

117
118
119
120
121
  Stream& print(const int);
  Stream& print(const double);
  Stream& print(const char* const, bool fork = true);
  Stream& print(const char);
  Stream& print(const Command&);
122

123
124
private:
  File* dfile_;
125

126
127
private:
  // inhibit copy
Ian Bell's avatar
Ian Bell committed
128
129
  Stream(const Stream&);
  Stream& operator=(const Stream&);
130
131
132
133
134

  File* dfile() const { return dfile_; }

  friend class Enter;
  friend class Controller;
135
136
};

137
138
Stream& operator<<(Stream& _ds, const int i);
Stream& operator<<(Stream& _ds, const double d);
139

140
141
142
Stream& operator<<(Stream& _ds, const size_t i);
Stream& operator<<(Stream& _ds, const unsigned int i);
Stream& operator<<(Stream& _ds, const float d);
143

144
145
146
Stream& operator<<(Stream& _ds, const char c);
Stream& operator<<(Stream& _ds, const char* const s);
Stream& operator<<(Stream& _ds, const std::string& s);
147

148
Stream& operator<<(Stream& _ds, const Command& co);
149
150
151
152
inline Stream& operator<<(Stream& _ds, const Command::Type _cmd_type)
{
  return _ds << Command(_cmd_type);
}
153

154
// Stream operator for std::vector<>
155
template< typename ElementT>
156
Stream& operator<<(Stream& _ds, const std::vector<ElementT>& _vec)
157
{
158
159
160
161
162
  _ds << "[ ";
  for (const auto el : _vec)
    _ds << el << " ";
  _ds << "]";
  return _ds;
163
164
}

165
166
167
168
169
170
171
172
173
174
175
// Stream operator for std::array<>
template< typename ElementT, size_t _el_nmbr>
Stream& operator<<(Stream& _ds, const std::array<ElementT, _el_nmbr>& _vec)
{
  _ds << "[ ";
  for (const auto el : _vec)
    _ds << el << " ";
  _ds << "]";
  return _ds;
}

176
// Stream operator for fixed size arrays
177
template <typename ElementT, size_t _el_nmbr>
178
Stream& operator<<(Stream& _ds, const ElementT(&_arr)[_el_nmbr])
179
180
181
182
183
184
185
{
  _ds << "[ ";
  for (const auto el : _arr)
    _ds << el << " ";
  _ds << "]";
  return _ds;
}
186

187
188
189
190
191
192
193
194
// Stream std::pair<>
template <typename T0, typename T1>
Stream& operator<<(Stream& _ds, const std::pair<T0, T1>& _pair)
{
  _ds << "(" << _pair.first << ", " << _pair.second << ")";
  return _ds;
}

195
196
197
198
199
200
201
extern void warning(const std::string& _wrng, const char* const _fnct, 
  const char* const _file,  const int _line);
extern void error(const std::string& _err, const char* const _fnct, 
  const char* const _file,  const int _line);

}//namespace Debug

202
203
204
205
206
207
208
209
210
#define DEB_module(MODULE)

//TODO: This should use an atomic thread-safe static int(s)
#define DEB_enter_func static int deb_nmbr = 0; \
  static int deb_lvl = Debug::INVALID_LEVEL; \
  Debug::Enter deb(__FILE__, __FUNCTION__, deb_nmbr, deb_lvl);

#define DEB_only(CC) CC

211
212
213
#define DEB_exec(LL, AA) DEB_exec_if(true, LL, AA)
#define DEB_exec_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) { AA; } }

214
215
216
217
218
219
220
221
222
223
#define DEB_out(LL, AA) DEB_out_if(true, LL, AA)
#define DEB_out_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
  { deb.stream() << AA << deb.end(); } }

#define DEB_line(LL, AA) DEB_line_if(true, LL, AA)
#define DEB_line_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
  { deb.stream() << AA << deb.end_lf(); } }

#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
#define DEB_warning_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
224
225
  { Debug::Stream strm; strm << AA; \
    Debug::warning(strm.string(), __FUNCTION__, __FILE__, __LINE__); } }
226

227
228
#define DEB_error(AA) { Debug::Stream strm; strm << AA; \
    Debug::error(strm.string(), __FUNCTION__, __FILE__, __LINE__); }
229
230
231
232
233
234
235
#define DEB_error_if(CC, AA) { if (CC) DEB_error(AA); }

// Stream does not fulfill ostream. If you want to exploit an existing
// ostream streamer to DEB_out a class as text without exploiting any
// numeric processing or custom Stream streamers then use this macro thus
// DEB_out(1, "my_class is " << DEB_os_str(my_c) )
#define DEB_os_str(AA) \
236
  dynamic_cast<std::ostringstream &&>((std::ostringstream() << AA )).str()
237

238
#endif // DEB_ON
239

240
#endif // BASE_DEBOUT_HH_INCLUDED