Panda3D
Loading...
Searching...
No Matches
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#if defined(CPPPARSER) && defined(HAVE_PYTHON)
39 EXTEND void set_ostream_ptr(PyObject *ostream_ptr, bool delete_later);
40#else
41 void set_ostream_ptr(std::ostream *ostream_ptr, bool delete_later);
42#endif
43 std::ostream *get_ostream_ptr() const;
44
45 typedef bool AssertHandler(const char *expression, int line,
46 const char *source_file);
47
48 void set_assert_handler(AssertHandler *assert_handler);
49 void clear_assert_handler();
50 bool has_assert_handler() const;
51 AssertHandler *get_assert_handler() const;
52
53 INLINE bool has_assert_failed() const;
54 INLINE const std::string &get_assert_error_message() const;
55 INLINE void clear_assert_failed();
56
57 NotifyCategory *get_top_category();
58 NotifyCategory *get_category(const std::string &basename,
59 NotifyCategory *parent_category);
60 NotifyCategory *get_category(const std::string &basename,
61 const std::string &parent_fullname);
62 NotifyCategory *get_category(const std::string &fullname);
63
64 static std::ostream &out();
65 static std::ostream &null();
66 static void write_string(const std::string &str);
67 static Notify *ptr();
68
69public:
70 static ios_fmtflags get_literal_flag();
71
72 bool assert_failure(const std::string &expression, int line,
73 const char *source_file);
74 bool assert_failure(const char *expression, int line,
75 const char *source_file);
76
77 static NotifySeverity string_severity(const std::string &string);
78
79 void config_initialized();
80
81private:
82 std::ostream *_ostream_ptr;
83 bool _owns_ostream_ptr;
84 std::ostream *_null_ostream_ptr;
85
86 AssertHandler *_assert_handler;
87 bool _assert_failed;
88 std::string _assert_error_message;
89
90 // This shouldn't be a pmap, since it might be invoked before we initialize
91 // the global malloc pointers.
92 typedef std::map<std::string, NotifyCategory *> Categories;
93 Categories _categories;
94
95 static Notify *_global_ptr;
96};
97
98
99// This defines the symbol nout in the same way that cerr and cout are
100// defined, for compactness of C++ code that uses Notify in its simplest form.
101// Maybe it's a good idea to define this symbol and maybe it's not, but it
102// does seem that "nout" isn't likely to collide with any other name.
103
104#define nout (Notify::out())
105
106// Here are a couple of assert-type functions. These are designed to avoid
107// simply dumping core, since that's quite troublesome when the programmer is
108// working in a higher-level environment that is calling into the C++ layer.
109
110// nassertr() is intended to be used in functions that have return values; it
111// returns the indicated value if the assertion fails.
112
113// nassertv() is intended to be used in functions that do not have return
114// values; it simply returns if the assertion fails.
115
116// nassertd() does not return from the function, but instead executes the
117// following block of code (like an if statement) if the assertion fails.
118
119// nassertr_always() and nassertv_always() are like nassertr() and nassertv(),
120// except that they will not get completely compiled out if NDEBUG is set.
121// Instead, they will quietly return from the function. These macros are
122// appropriate, for instance, for sanity checking user input parameters, where
123// optimal performance is not paramount.
124
125// nassert_static() is a compile-time assertion. It should only be used with
126// constant expressions and compilation will fail if the assertion is not
127// true.
128
129#ifdef __GNUC__
130// Tell the optimizer to optimize for the case where the condition is true.
131#define _nassert_check(condition) (__builtin_expect(!(condition), 0))
132#else
133#define _nassert_check(condition) (!(condition))
134#endif
135
136#ifdef NDEBUG
137
138#define nassertr(condition, return_value)
139#define nassertv(condition)
140#define nassertd(condition) if (false)
141// We trust the compiler to optimize the above out.
142
143#define nassertr_always(condition, return_value) \
144 { \
145 if (_nassert_check(condition)) { \
146 return return_value; \
147 } \
148 }
149
150#define nassertv_always(condition) \
151 { \
152 if (_nassert_check(condition)) { \
153 return; \
154 } \
155 }
156
157#define nassert_raise(message) Notify::write_string(message)
158
159#else // NDEBUG
160
161#define nassertr(condition, return_value) \
162 { \
163 if (_nassert_check(condition)) { \
164 if (Notify::ptr()->assert_failure(#condition, __LINE__, __FILE__)) { \
165 return return_value; \
166 } \
167 } \
168 }
169
170#define nassertv(condition) \
171 { \
172 if (_nassert_check(condition)) { \
173 if (Notify::ptr()->assert_failure(#condition, __LINE__, __FILE__)) { \
174 return; \
175 } \
176 } \
177 }
178
179#define nassertd(condition) \
180 if (_nassert_check(condition) && \
181 Notify::ptr()->assert_failure(#condition, __LINE__, __FILE__))
182
183#define nassertr_always(condition, return_value) nassertr(condition, return_value)
184#define nassertv_always(condition) nassertv(condition)
185
186#define nassert_raise(message) Notify::ptr()->assert_failure(message, __LINE__, __FILE__)
187
188#endif // NDEBUG
189
190#if __cplusplus >= 201103
191#define __nassert_static(condition, line, file) static_assert((condition), #condition " at line " #line " of " file)
192#define _nassert_static(condition, line, file) __nassert_static(condition, line, file)
193#define nassert_static(condition) _nassert_static(condition, __LINE__, __FILE__)
194#else
195#define __nassert_static(condition, suffix) typedef char nassert_static_ ## suffix [(condition) ? 1 : -1];
196#define _nassert_static(condition, suffix) __nassert_static(condition, suffix)
197#define nassert_static(condition) _nassert_static(condition, __COUNTER__)
198#endif
199
200#include "pnotify.I"
201
202#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.