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

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_module(SS)
12
#define DEB_enter_func PROGRESS_TICK;
13
#define DEB_only(CC)
14 15 16 17 18 19
#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; }
20

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

26
#else // DEB_ON
27

28 29
#include "Base/Code/CodeLink.hh"
#include "Base/Utils/OStringStream.hh"
30

31
#include <string>
32
#include <sstream>
33
#include <vector>
34

35 36 37 38
// ERROR is occasionally defined in system headers, e.g., windows.h
#ifdef ERROR 
#undef ERROR
#endif//ERROR
39

40
namespace Debug {
41

42 43
typedef unsigned int uint;

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

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

54 55 56
/*! 
Stream is a specialization for the Debug system streaming.
*/
57
class BASEDLLEXPORT Stream : public Base::IOutputStream
58 59
{
public:
60
  Stream(File& _file) : file_(_file) {}
61

62 63 64 65 66 67
  Base::IOutputStream& print(const int);
  Base::IOutputStream& print(const size_t);
  Base::IOutputStream& print(const double);
  Base::IOutputStream& print(const char* const);
  Base::IOutputStream& print(const char);
  Base::IOutputStream& print(const Base::Command&);
68

69
private:
70
  File& file_;
71

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

  friend class Enter;
  friend class Controller;
79 80
};

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

  //! 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
97
  int number() const { return nmbr_; }
98
  //! Get the stream
99
  Stream& stream();
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

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
};

Max Lyon's avatar
Max Lyon committed
116 117
BASEDLLEXPORT extern void warning(const std::string& _wrng, const ::Base::CodeLink& _lnk);
BASEDLLEXPORT extern void error(const std::string& _err, const ::Base::CodeLink& _lnk);
118

119 120 121 122 123 124 125 126 127
// 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();
}

128 129
}//namespace Debug

130
// Obsolete, use gradually removed
131 132 133
#define DEB_module(MODULE)

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

#define DEB_only(CC) CC

142
#define DEB_exec(LL, AA) DEB_exec_if(true, LL, AA)
143
#define DEB_exec_if(CC, LL, AA) { PROGRESS_TICK; \
144
  { if (deb.pass(LL) && (CC)) { AA; } } }
145

146
#define DEB_out(LL, AA) DEB_out_if(true, LL, AA)
147
#define DEB_out_if(CC, LL, AA) { PROGRESS_TICK; \
148
  { if (deb.pass(LL) && (CC)) { deb.stream() << AA << ::Base::Command::END; } } }
149 150

#define DEB_line(LL, AA) DEB_line_if(true, LL, AA)
151
#define DEB_line_if(CC, LL, AA) { PROGRESS_TICK; \
152
  { if (deb.pass(LL) && (CC)) { deb.stream() << AA << ::Base::LF; } } }
153 154

#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
155
#define DEB_warning_if(CC, LL, AA) \
156
  { if (deb.pass(LL) && (CC)) { ::Base::OStringStream strm; strm << AA; \
157
      ::Debug::warning(strm.str, BASE_CODELINK); } } 
158

159 160
#define DEB_error(AA) { ::Base::OStringStream strm; strm << AA; \
    ::Debug::error(strm.str, BASE_CODELINK); }
161 162
#define DEB_error_if(CC, AA) { if (CC) DEB_error(AA); }

163
// Debug::Stream does not fulfill ostream. If you want to exploit an existing
164 165 166
// 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) )
167 168

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

170 171
#endif // DEB_ON
#endif // BASE_DEBOUT_HH_INCLUDED