DebOut.hh 6.09 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
const int INVALID_LEVEL = -1;

43
class Stream;
44

45
class Command
46
47
48
49
{
public:
  enum CommandType
  {
50
51
52
    END     = 0x01,
    END_LF  = 0x03,
    END_ERR = 0x07
53
  };
54

55
  CommandType com_;
56

57
58
59
60
  CommandType com() const
  {
    return com_;
  }
61
62

  Command(CommandType _com) : com_(_com) {}
63
64
65
};


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

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

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

87
  Stream& stream(const int _warn = 0, const bool _print = true);
88

89
90
91
  Command end() const { return Command(Command::CommandType::END); }
  Command end_lf() const { return Command(Command::CommandType::END_LF); }
  Command end_err() const { return Command(Command::CommandType::END_ERR); }
92
};
93

94
class File;
95

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

107
private:
108
  File* dfile_;
109
public:
110
  File* dfile() const
111
  {
112
    return dfile_;
113
114
  }
  //! Constructor.
115
  Stream(
116
    const char* _file_name = nullptr,   //!< [in] File name if file based.
117
    const StreamType _type = APPEND    //!< [in] bitsfield enum type identifier
118
  ) ;
119
  ~Stream();
120

121
  const char* string_out() const;
122

123
124
125
126
127
  Stream& print(const int);
  Stream& print(const double);
  Stream& print(const char* const, bool fork = true);
  Stream& print(const char);
  Stream& print(const Command&);
128

129
130
  //! Get the currently active Stream
  static Stream& get_global(int _warn = 0);
131

132
133
private:
  // inhibit copy
Ian Bell's avatar
Ian Bell committed
134
135
  Stream(const Stream&);
  Stream& operator=(const Stream&);
136
137
};

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

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

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

149
Stream& operator<<(Stream& _ds, const Command& co);
150

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

162
163
164
165
166
167
168
169
170
171
172
// 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;
}

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

184
185
186
187
188
189
190
191
// 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;
}

192
193
194
195
196
197
198
199
200
#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

201
202
203
#define DEB_exec(LL, AA) DEB_exec_if(true, LL, AA)
#define DEB_exec_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) { AA; } }

204
205
206
207
208
209
210
211
212
213
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)) \
  { deb.stream(1) << "WARNING: " << AA << deb.end_lf(); } }

#define DEB_error(AA) { deb.stream(2) << "ERROR: " << AA << deb.end_err(); }
#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) \
224
  dynamic_cast<std::ostringstream &&>((std::ostringstream() << AA )).str()
225
226

}//namespace Debug
227

228
#endif // DEB_ON
229

230
#endif // BASE_DEBOUT_HH_INCLUDED