summaryrefslogtreecommitdiff
path: root/debug.h
blob: 090d5830241be892dc84966e270ae4c626239cf8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef _DEBUG_H
#define _DEBUG_H

#define DEVELOPER   4
#define ALPHA       3
#define BETA        2
#define RELEASE     1
#define NO_SEATBELT 0

#ifndef RELEASE_LEVEL
#define RELEASE_LEVEL RELEASE
#endif

#if RELEASE_LEVEL >= ALPHA
#include <cstdlib>              // for `getenv'
#include <cstring>              // for `strcmp'
#endif

#if RELEASE_LEVEL >= BETA
#include <cassert>
#endif

#if RELEASE_LEVEL >= RELEASE
#include <iostream>
#endif

#include <sstream>              // used for constructing exceptions

namespace ledger {

//////////////////////////////////////////////////////////////////////
//
// Debugging facilities for Ledger
//
// - In developer level, all checking and debugging facilities are
//   active.
//
// - Alpha level does not include performance degrading
//   VALIDATE calls.
//
// - Beta level is like Alpha, but does not include debugging
//   facilities.
//
// - Release level does not include CONFIRM checks, but does include
//   assert calls.
//
// - Running with no seatbelt disables all checking except for normal
//   syntax and semantic error checking.

#define WARN(x)							\
  if (ledger::warning_stream)					\
    *ledger::warning_stream << "Warning: "<< x << std::endl

#define ERR(exc, x) {				\
    std::ostringstream s;                       \
    s << x;                                     \
    throw exc(s.str().c_str());                 \
  }

#if RELEASE_LEVEL >= ALPHA

#define DEBUG_ENABLED

extern std::ostream * warning_stream;
extern std::ostream * debug_stream;
extern bool           free_debug_stream;

inline bool _debug_active(const char * const cls) {
  char * debug = std::getenv("DEBUG_CLASS");
  return debug && std::strcmp(debug, cls) == 0;
}

#define DEBUG_CLASS(cls) static const char * const _debug_cls = (cls)

#define DEBUG(cls) (ledger::_debug_active(cls))
#define DEBUG_() DEBUG(_debug_cls)

#define DEBUG_PRINT(cls, x)					\
  if (ledger::debug_stream && ledger::_debug_active(cls)) {	\
    *ledger::debug_stream << x << std::endl;			\
  }
#define DEBUG_PRINT_(x) DEBUG_PRINT(_debug_cls, x)

#define CONFIRM(x) assert(x)

#if RELEASE_LEVEL == DEVELOPER
#define VALIDATE(x) assert(x)
#else
#define VALIDATE(x)
#endif

#else // RELEASE_LEVEL

#define DEBUG_CLASS(cls)
#define DEBUG(cls) 0
#define DEBUG_() 0
#define DEBUG_PRINT(cls, x)
#define DEBUG_PRINT_(x)

#define VALIDATE(x)

#if RELEASE_LEVEL == NO_SEATBELT

#undef assert
#define assert(x)
#define CONFIRM(x)

#elif RELEASE_LEVEL >= RELEASE

extern std::ostream * warning_stream;
#define CONFIRM(x)

#elif RELEASE_LEVEL >= BETA

#define CONFIRM(x) assert(x)

#endif

#endif // RELEASE_LEVEL

} // namespace ledger

#endif // _DEBUG_H