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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
#ifndef _DEBUG_H
#define _DEBUG_H
#define DEVELOPER 4
#define ALPHA 3
#define BETA 2
#define RELEASE 1
#define NO_SEATBELT 0
#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL RELEASE
#endif
#if DEBUG_LEVEL >= ALPHA
#include <cstdlib> // for `getenv'
#include <cstring> // for `strcmp'
#endif
#if DEBUG_LEVEL >= BETA
#include <cassert>
#endif
#if DEBUG_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 DEBUG_LEVEL >= ALPHA
#include <pcre.h>
#include <cstring>
#define DEBUG_ENABLED
extern std::ostream * warning_stream;
extern std::ostream * debug_stream;
extern bool free_debug_stream;
bool _debug_active(const char * const cls);
#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 DEBUG_PRINT_TIME(cls, x) { \
char buf[256]; \
std::strftime(buf, 255, "%Y/%m/%d", std::localtime(&x)); \
DEBUG_PRINT(cls, #x << " is " << buf); \
}
#define DEBUG_PRINT_TIME_(x) DEBUG_PRINT_TIME(_debug_cls, x)
#define CONFIRM(x) assert(x)
#if DEBUG_LEVEL == DEVELOPER
#define VALIDATE(x) assert(x)
#else
#define VALIDATE(x)
#endif
#else // DEBUG_LEVEL
#define DEBUG_CLASS(cls)
#define DEBUG(cls) 0
#define DEBUG_() 0
#define DEBUG_PRINT(cls, x)
#define DEBUG_PRINT_(x)
#define DEBUG_PRINT_TIME(cls, x)
#define DEBUG_PRINT_TIME_(x)
#define VALIDATE(x)
#if DEBUG_LEVEL == NO_SEATBELT
#undef assert
#define assert(x)
#define CONFIRM(x)
#elif DEBUG_LEVEL >= RELEASE
extern std::ostream * warning_stream;
#define CONFIRM(x)
#elif DEBUG_LEVEL >= BETA
#define CONFIRM(x) assert(x)
#endif
#endif // DEBUG_LEVEL
} // namespace ledger
#ifdef DEBUG_ENABLED
void * operator new(std::size_t) throw (std::bad_alloc);
void * operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
void * operator new(std::size_t, const std::nothrow_t&) throw();
void * operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
#endif // DEBUG_ENABLED
#endif // _DEBUG_H
|