1 #ifndef CRITICAL_EVENTS_GROUP
2 #define CRITICAL_EVENTS_GROUP
4 /*****************************************************************************\
6 * Name : critical_events *
7 * Author : Chris Koeritz *
9 *******************************************************************************
10 * Copyright (c) 1989-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
18 #include <basis/astring.h>
22 //! This macro wraps the notion of stopping in the debugger.
24 #define CAUSE_BREAKPOINT
25 //hmmm: need a unix equivalent for this. supporting gcc might be enough.
29 // #include <ddk/winddi.h>
30 //for debugbreak. does this cause other problems?
32 #define CAUSE_BREAKPOINT
33 // #define CAUSE_BREAKPOINT __debugbreak()
35 #define CAUSE_BREAKPOINT __debugbreak()
39 //! Tests the value "check" to ensure that it's not zero.
40 /*! This can be used instead of an ASSERT macro to check conditions in
41 builds with ERRORS_ARE_FATAL turned on. This macro is orthogonal to the
42 build being built with debugging or release features. */
43 #ifdef ERRORS_ARE_FATAL
44 #define REQUIRE(check) if (!check) CAUSE_BREAKPOINT;
46 #define REQUIRE(check)
49 // now more dangerous or potent guards...
51 //! an extra piece of information used, if available, in bounds_halt below.
52 //#define BH_ERROR_ADDITION ((basis::astring(" in ") + _global_argv[0]).s())
54 //! Verifies that "value" is between "low" and "high", inclusive.
55 /*! "Value" must be an object for which greater than and less than are defined.
56 The static_class_name() method and func definition are used to tag the
57 complaint that is emitted when problems are detected. Note that if
58 CATCH_ERRORS is defined, then the program is _halted_ if the value is out
59 of bounds. Otherwise, the "to_return" value is returned. */
61 // #define bounds_halt(value, low, high, to_return) {
62 // if (((value) < (low)) || ((value) > (high))) {
63 // critical_events::implement_bounds_halt(static_class_name(), func, #value, #low,
64 // #high, BH_ERROR_ADDITION);
69 // #define bounds_halt(a, b, c, d) bounds_return(a, b, c, d)
74 //! Provide some macros that will automatically add the file and line number.
75 /*! These use the functions below to report different types of error
76 situations and in some cases, exit the program. */
77 #define non_continuable_error(c, f, i) \
78 critical_events::FL_non_continuable_error(__FILE__, __LINE__, c, f, i, \
79 "A Non-Continuable Runtime Problem Has Occurred")
80 #define continuable_error(c, f, i) \
81 critical_events::FL_continuable_error(__FILE__, __LINE__, c, f, i, \
82 "Runtime Problem Information")
83 #define console_error(c, f, i) \
84 critical_events::FL_console_error(__FILE__, __LINE__, c, f, i)
85 #define deadly_error(c, f, i) \
86 critical_events::FL_deadly_error(__FILE__, __LINE__, c, f, i)
87 #define out_of_memory_now(c, f) \
88 critical_events::FL_out_of_memory_now(__FILE__, __LINE__, c, f)
92 //! Provides a means of logging events for runtime problems.
94 class critical_events : public virtual basis::root_object
97 virtual ~critical_events() {}
99 // super handy system inter-operation functions...
101 static basis::un_int system_error();
102 //!< gets the most recent system error reported on this thread.
104 static basis::astring system_error_text(basis::un_int error_to_show);
105 //!< returns the OS's string form of the "error_to_show".
106 /*!< this often comes from the value reported by system_error(). */
108 // some noisemaking methods...
110 //! Prints out a message to the standard error file stream.
111 static void write_to_console(const char *message);
113 //! shows the message in "info", with an optional "title" on the message.
114 /*! the message is sent to the program wide logger, if one is expected to
115 exist in this program. */
116 static void alert_message(const char *info, const char *title = "Alert Message");
117 static void alert_message(const basis::astring &info); // uses default title.
118 static void alert_message(const basis::astring &info, const basis::astring &title); // use "title".
120 static void write_to_critical_events(const char *message);
121 //!< sends the "message" to the critical events log file.
122 /*!< Prints out a message to the specially named file that captures all
123 serious events written to error logging functions. If you use the
124 functions in this file, you are likely already writing to this log. */
126 static void set_critical_events_directory(const basis::astring &directory);
127 //!< sets the internal location where the critical events will be logged.
128 /*!< this is postponed to a higher level, although the default
131 static basis::astring critical_events_directory();
132 //!< returns the current location where critical events are written.
134 // this section implements the error macros.
136 //! Prints out an error message and then exits the program.
137 /*! The parameters describe the location where the error was detected. This
138 call should only be used in test programs or where absolutely necessary
139 because it causes an almost immediate exit from the program! deadly_error
140 should be reserved for when the program absolutely has to exit right then,
141 because this function will actually enforce a crash / abort / break into
142 debugger action rather than just calling exit(). */
143 static void FL_deadly_error(const char *file, int line, const char *classname,
144 const char *function_name, const char *info);
145 //! A version that takes strings instead of char pointers.
146 static void FL_deadly_error(const basis::astring &file, int line,
147 const basis::astring &classname, const basis::astring &function_name,
148 const basis::astring &info);
150 //! Describes an error like deadly_error, but does not exit the program.
151 static void FL_continuable_error(const char *file, int line,
152 const char *classname, const char *function_name, const char *info,
155 //! A version using astring instead of char pointers.
156 static void FL_continuable_error(const basis::astring &file, int line,
157 const basis::astring &classname, const basis::astring &function_name,
158 const basis::astring &info, const basis::astring &title);
160 //! Shows the same information as continuable_error, but causes an exit.
161 /*! This is a friendlier program exit than deadly_error. This version can
162 be used when the program must stop, possibly because of a precondition failure
163 or a problem in input data or basically whatever. it is not intended to
164 abort or break into the debugger, but to simply exit(). */
165 static void FL_non_continuable_error(const char *file, int line,
166 const char *classname, const char *function_name, const char *info,
169 //! A version using astring instead of char pointers.
170 static void FL_non_continuable_error(const basis::astring &file, int line,
171 const basis::astring &classname, const basis::astring &function_name,
172 const basis::astring &info, const basis::astring &title);
174 //! Causes the program to exit due to a memory allocation failure.
175 static void FL_out_of_memory_now(const char *file, int line,
176 const char *classname, const char *function_name);
178 //! Prints out an error message to the standard error file stream.
179 static void FL_console_error(const char *file, int line, const char *error_class,
180 const char *error_function, const char *info);
182 //! Used to build our particular type of error message.
183 /*! It writes an error message into "guards_message_space" using our stylized
184 object::method formatting. */
185 static void make_error_message(const char *file, int line,
186 const char *error_class, const char *error_function,
187 const char *info, char *guards_message_space);
189 //! Provides the real implementation of bounds_halt to save code space.
190 static void implement_bounds_halt(const char *the_class_name, const char *func,
191 const char *value, const char *low, const char *high,
192 const char *error_addition);
195 static basis::astring &hidden_critical_events_dir();
197 static void FL_continuable_error_real(const char *file, int line,
198 const char *error_class, const char *error_function, const char *info,