Panda3D
pnotify.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pnotify.h
10 * @author drose
11 * @date 2000-02-28
12 */
13
14#ifndef NOTIFY_H
15#define NOTIFY_H
16
17#include "dtoolbase.h"
18#include "notifySeverity.h"
19#include <map>
20
21class NotifyCategory;
22
23/**
24 * An object that handles general error reporting to the user. It contains a
25 * pointer to an ostream, initially cerr, which can be reset at will to point
26 * to different output devices, according to the needs of the application.
27 * All output generated within Panda should vector through the Notify ostream.
28 *
29 * This also includes a collection of Categories and Severities, which may be
30 * independently enabled or disabled, so that error messages may be squelched
31 * or respected according to the wishes of the user.
32 */
33class EXPCL_DTOOL_PRC Notify {
34PUBLISHED:
35 Notify();
36 ~Notify();
37
38 void set_ostream_ptr(std::ostream *ostream_ptr, bool delete_later);
39 std::ostream *get_ostream_ptr() const;
40
41 typedef bool AssertHandler(const char *expression, int line,
42 const char *source_file);
43
44 void set_assert_handler(AssertHandler *assert_handler);
45 void clear_assert_handler();
46 bool has_assert_handler() const;
47 AssertHandler *get_assert_handler() const;
48
49 INLINE bool has_assert_failed() const;
50 INLINE const std::string &get_assert_error_message() const;
51 INLINE void clear_assert_failed();
52
53 NotifyCategory *get_top_category();
54 NotifyCategory *get_category(const std::string &basename,
55 NotifyCategory *parent_category);
56 NotifyCategory *get_category(const std::string &basename,
57 const std::string &parent_fullname);
58 NotifyCategory *get_category(const std::string &fullname);
59
60 static std::ostream &out();
61 static std::ostream &null();
62 static void write_string(const std::string &str);
63 static Notify *ptr();
64
65public:
66 static ios_fmtflags get_literal_flag();
67
68 bool assert_failure(const std::string &expression, int line,
69 const char *source_file);
70 bool assert_failure(const char *expression, int line,
71 const char *source_file);
72
73 static NotifySeverity string_severity(const std::string &string);
74
75 void config_initialized();
76
77private:
78 std::ostream *_ostream_ptr;
79 bool _owns_ostream_ptr;
80 std::ostream *_null_ostream_ptr;
81
82 AssertHandler *_assert_handler;
83 bool _assert_failed;
84 std::string _assert_error_message;
85
86 // This shouldn't be a pmap, since it might be invoked before we initialize
87 // the global malloc pointers.
88 typedef std::map<std::string, NotifyCategory *> Categories;
89 Categories _categories;
90
91 static Notify *_global_ptr;
92};
93
94
95// This defines the symbol nout in the same way that cerr and cout are
96// defined, for compactness of C++ code that uses Notify in its simplest form.
97// Maybe it's a good idea to define this symbol and maybe it's not, but it
98// does seem that "nout" isn't likely to collide with any other name.
99
100#define nout (Notify::out())
101
102// Here are a couple of assert-type functions. These are designed to avoid
103// simply dumping core, since that's quite troublesome when the programmer is
104// working in a higher-level environment that is calling into the C++ layer.
105
106// nassertr() is intended to be used in functions that have return values; it
107// returns the indicated value if the assertion fails.
108
109// nassertv() is intended to be used in functions that do not have return
110// values; it simply returns if the assertion fails.
111
112// nassertd() does not return from the function, but instead executes the
113// following block of code (like an if statement) if the assertion fails.
114
115// nassertr_always() and nassertv_always() are like nassertr() and nassertv(),
116// except that they will not get completely compiled out if NDEBUG is set.
117// Instead, they will quietly return from the function. These macros are
118// appropriate, for instance, for sanity checking user input parameters, where
119// optimal performance is not paramount.
120
121// nassert_static() is a compile-time assertion. It should only be used with
122// constant expressions and compilation will fail if the assertion is not
123// true.
124
125#ifdef __GNUC__
126// Tell the optimizer to optimize for the case where the condition is true.
127#define _nassert_check(condition) (__builtin_expect(!(condition), 0))
128#else
129#define _nassert_check(condition) (!(condition))
130#endif
131
132#ifdef NDEBUG
133
134#define nassertr(condition, return_value)
135#define nassertv(condition)
136#define nassertd(condition) if (false)
137// We trust the compiler to optimize the above out.
138
139#define nassertr_always(condition, return_value) \
140 { \
141 if (_nassert_check(condition)) { \
142 return return_value; \
143 } \
144 }
145
146#define nassertv_always(condition) \
147 { \
148 if (_nassert_check(condition)) { \
149 return; \
150 } \
151 }
152
153#define nassert_raise(message) Notify::write_string(message)
154
155#else // NDEBUG
156
157#define nassertr(condition, return_value) \
158 { \
159 if (_nassert_check(condition)) { \
160 if (Notify::ptr()->assert_failure(#condition, __LINE__, __FILE__)) { \
161 return return_value; \
162 } \
163 } \
164 }
165
166#define nassertv(condition) \
167 { \
168 if (_nassert_check(condition)) { \
169 if (Notify::ptr()->assert_failure(#condition, __LINE__, __FILE__)) { \
170 return; \
171 } \
172 } \
173 }
174
175#define nassertd(condition) \
176 if (_nassert_check(condition) && \
177 Notify::ptr()->assert_failure(#condition, __LINE__, __FILE__))
178
179#define nassertr_always(condition, return_value) nassertr(condition, return_value)
180#define nassertv_always(condition) nassertv(condition)
181
182#define nassert_raise(message) Notify::ptr()->assert_failure(message, __LINE__, __FILE__)
183
184#endif // NDEBUG
185
186#if __cplusplus >= 201103
187#define __nassert_static(condition, line, file) static_assert((condition), #condition " at line " #line " of " file)
188#define _nassert_static(condition, line, file) __nassert_static(condition, line, file)
189#define nassert_static(condition) _nassert_static(condition, __LINE__, __FILE__)
190#else
191#define __nassert_static(condition, suffix) typedef char nassert_static_ ## suffix [(condition) ? 1 : -1];
192#define _nassert_static(condition, suffix) __nassert_static(condition, suffix)
193#define nassert_static(condition) _nassert_static(condition, __COUNTER__)
194#endif
195
196#include "pnotify.I"
197
198#endif
A particular category of error messages.
An object that handles general error reporting to the user.
Definition: pnotify.h:33
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.