DebOut.hh 4.93 KB
Newer Older
1
// (C) Copyright 2019 by Autodesk, Inc.
2

3
4
#ifndef BASE_DEBOUT_HH_INCLUDED
#define BASE_DEBOUT_HH_INCLUDED
5

6
7
#include "Base/Progress/ProgressNode.hh"

8
// DEB_ON is defined, or not, in CMakeLists.txt for primary project
9
#ifndef DEB_ON
10

11
#define DEB_enter_func PROGRESS_TICK;
12
#define DEB_only(CC)
13
14
15
16
17
18
#define DEB_exec(LL, AA) { PROGRESS_TICK; } 
#define DEB_exec_if(CC, LL, AA) { PROGRESS_TICK; } 
#define DEB_out(LL, AA) { PROGRESS_TICK; } 
#define DEB_out_if(CC, LL, AA) { PROGRESS_TICK; } 
#define DEB_line(LL, AA) { PROGRESS_TICK; } 
#define DEB_line_if(CC, LL, AA) { PROGRESS_TICK; }
19

20
21
#define DEB_warning(LL, AA) {}
#define DEB_warning_if(CC, LL, AA) {}
22
23
#define DEB_error(AA) {} 
#define DEB_error_if(CC, AA) {} 
24

25
26
27
28
29
#define DEB_os_str

#define DEB_ref
#define DEB_refc 

30
#else // DEB_ON
31

32
33
#include "Base/Code/CodeLink.hh"
#include "Base/Utils/OStringStream.hh"
34

35
#include <string>
36
37
#include <sstream>

38
39
40
41
// ERROR is occasionally defined in system headers, e.g., windows.h
#ifdef ERROR 
#undef ERROR
#endif//ERROR
42

43
namespace Debug {
44

45
typedef unsigned int uint;
46
const int INVALID_LEVEL = -1;
47
48
const char* const ERROR = "ERROR";
const char* const WARNING = "WARNING";
49

50
/*! 
51
File is a private implementation for Stream, which supplies data for several 
52
53
other Debug and Test features.
*/
54
class File;
55

56
57
58
/*! 
Stream is a specialization for the Debug system streaming.
*/
Martin Marinov's avatar
Martin Marinov committed
59
class BASEDLLEXPORT Stream : public ::Base::IOutputStream
60
61
{
public:
62
  Stream(File& _file) : file_(_file) {}
63

Martin Marinov's avatar
Martin Marinov committed
64
65
66
67
68
69
  ::Base::IOutputStream& print(const int) override;
  ::Base::IOutputStream& print(const size_t) override;
  ::Base::IOutputStream& print(const float) override;
  ::Base::IOutputStream& print(const double) override;
  ::Base::IOutputStream& print(const char* const) override;
  ::Base::IOutputStream& print(const char) override;
70

71
private:
72
  File& file_;
73

74
75
private:
  // inhibit copy
Ian Bell's avatar
Ian Bell committed
76
77
  Stream(const Stream&);
  Stream& operator=(const Stream&);
78
79
80

  friend class Enter;
  friend class Controller;
81
82
};

83
84
85
/*!
Enter point in the Debug call stack, also used to filter debug output.
*/
86
class BASEDLLEXPORT Enter
87
88
{
public:
89
90
  Enter(const char* const _flnm, const char* const _fnct, int& _nmbr, int& _lvl);
  ~Enter();
91
92
93
94
95
96
97
98

  //! pass the output on the level or not?
  bool pass(const int _lvl) const { return _lvl <= lvl_; }
  //! Get the filename
  const char* filename() const { return flnm_; }
  //! Get the function
  const char* function() const { return fnct_; }
  //! Get the number of entries in this point
99
  int number() const { return nmbr_; }
100
  //! Get the stream
101
  Stream& stream();
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

private:  
  int id_;  //!< Unique identifier for this entry
  const char* flnm_;//!< File name of this entry 
  const char* fnct_;//!< Function name of this entry
  int nmbr_;//!< number of times this entry has occurred 
  int lvl_; //!< permission level for this entry
  /*!
  Number of DEB_* outputs encountered within this entry scope.
  Determines whether a given DEB_* should include or omit a call stack, 
  or an exit trace. 
  */
  int outs_; 
  Stream strm_; //!< Stream
};

118
119
120
121
BASEDLLEXPORT extern void warning(const std::string& _wrng, 
  const ::Base::CodeLink& _lnk);
BASEDLLEXPORT extern void error(const std::string& _err, 
  const ::Base::CodeLink& _lnk);
122

123
124
125
126
127
128
129
130
131
// TODO: Move this upstream to namespace Base?!
template <typename T>
std::string to_string(const T& _t)
{
  std::ostringstream ss;
  ss << _t;
  return ss.str();
}

132
133
}//namespace Debug

134
//TODO: This should use an atomic thread-safe static int(s)
135
#define DEB_enter_func \
136
  PROGRESS_TICK; \
137
  static int deb_nmbr = 0; \
138
  static int deb_lvl = Debug::INVALID_LEVEL; \
139
  ::Debug::Enter deb(__FILE__, __FUNCTION__, deb_nmbr, deb_lvl);
140
141
142

#define DEB_only(CC) CC

143
144
145
146
147
148
149
150
151
152
153
#define DEB_if(CC, LL, EXPR) \
  { \
    PROGRESS_TICK; \
    { \
      if (deb.pass(LL) && (CC)) \
      { \
        EXPR; \
      } \
    } \
  }

154
#define DEB_exec(LL, AA) DEB_exec_if(true, LL, AA)
155
#define DEB_exec_if(CC, LL, AA) DEB_if(CC, LL, AA)
156

157
#define DEB_out(LL, AA) DEB_out_if(true, LL, AA)
158
#define DEB_out_if(CC, LL, AA) \
Martin Marinov's avatar
Martin Marinov committed
159
  DEB_if(CC, LL, deb.stream() << AA << ::Base::ENDL)
160
161

#define DEB_line(LL, AA) DEB_line_if(true, LL, AA)
162
#define DEB_line_if(CC, LL, AA) \
Martin Marinov's avatar
Martin Marinov committed
163
  DEB_if(CC, LL, deb.stream() << AA << ::Base::ENDL)
164
165

#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
166
#define DEB_warning_if(CC, LL, AA) \
167
168
  DEB_if(CC, LL, ::Base::OStringStream strm; strm << AA; \
      ::Debug::warning(strm.str, BASE_CODELINK);)
169

170
171
#define DEB_error(AA) { ::Base::OStringStream strm; strm << AA; \
    ::Debug::error(strm.str, BASE_CODELINK); }
172
173
#define DEB_error_if(CC, AA) { if (CC) DEB_error(AA); }

174
// Debug::Stream does not fulfill ostream. If you want to exploit an existing
175
176
177
// 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) )
178
179

#define DEB_os_str(AA) Debug::to_string(AA)
180

181
182
183
184
// reference the local deb context when capturing in lambdas
#define DEB_ref &deb 
#define DEB_refc &deb,

185
186
#endif // DEB_ON
#endif // BASE_DEBOUT_HH_INCLUDED