checking in the recent efforts at optimizing clam
[feisty_meow.git] / nucleus / library / loggers / critical_events.h
1 #ifndef CRITICAL_EVENTS_GROUP
2 #define CRITICAL_EVENTS_GROUP
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : critical_events                                                   *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
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 \*****************************************************************************/
17
18 #include <basis/astring.h>
19
20 namespace loggers {
21
22 //! This macro wraps the notion of stopping in the debugger.
23 //#ifndef _MSC_VER
24   #define CAUSE_BREAKPOINT
25 //hmmm: need a unix equivalent for this, see old below for doze?
26 /*
27 #else
28   #ifdef __MINGW32__
29     extern "C" {
30 //      #include <ddk/winddi.h>
31 //for debugbreak.  does this cause other problems?
32     }
33     #define CAUSE_BREAKPOINT 
34 //    #define CAUSE_BREAKPOINT __debugbreak()
35   #else
36     #define CAUSE_BREAKPOINT __debugbreak()
37   #endif
38 #endif
39 */
40
41 //! Tests the value "check" to ensure that it's not zero.
42 /*! This can be used instead of an ASSERT macro to check conditions in
43 builds with ERRORS_ARE_FATAL turned on.  This macro is orthogonal to the
44 build being built with debugging or release features. */
45 #ifdef ERRORS_ARE_FATAL
46   #define REQUIRE(check) if (!check) CAUSE_BREAKPOINT;
47 #else
48   #define REQUIRE(check)
49 #endif
50
51 // now more dangerous or potent guards...
52
53 //! an extra piece of information used, if available, in bounds_halt below.
54 //#define BH_ERROR_ADDITION ((basis::astring(" in ") + _global_argv[0]).s())
55
56 //! Verifies that "value" is between "low" and "high", inclusive.
57 /*! "Value" must be an object for which greater than and less than are defined.
58 The static_class_name() method and func definition are used to tag the
59 complaint that is emitted when problems are detected.  Note that if
60 CATCH_ERRORS is defined, then the program is _halted_ if the value is out
61 of bounds.  Otherwise, the "to_return" value is returned. */
62 //#ifdef CATCH_ERRORS
63 //  #define bounds_halt(value, low, high, to_return) { 
64 //    if (((value) < (low)) || ((value) > (high))) { 
65 //      critical_events::implement_bounds_halt(static_class_name(), func, #value, #low, 
66 //          #high, BH_ERROR_ADDITION); 
67 //      return to_return; 
68 //    } 
69 //  }
70 //#else
71 //  #define bounds_halt(a, b, c, d) bounds_return(a, b, c, d)
72 //#endif
73
74 //////////////
75
76 //! Provide some macros that will automatically add the file and line number.
77 /*! These use the functions below to report different types of error
78 situations and in some cases, exit the program. */
79 #define non_continuable_error(c, f, i) \
80   critical_events::FL_non_continuable_error(__FILE__, __LINE__, c, f, i, \
81       "A Non-Continuable Runtime Problem Has Occurred")
82 #define continuable_error(c, f, i) \
83   critical_events::FL_continuable_error(__FILE__, __LINE__, c, f, i, \
84       "Runtime Problem Information")
85 #define console_error(c, f, i) \
86   critical_events::FL_console_error(__FILE__, __LINE__, c, f, i)
87 #define deadly_error(c, f, i) \
88   critical_events::FL_deadly_error(__FILE__, __LINE__, c, f, i)
89 #define out_of_memory_now(c, f) \
90   critical_events::FL_out_of_memory_now(__FILE__, __LINE__, c, f)
91
92 //////////////
93
94 //! Provides a means of logging events for runtime problems.
95
96 class critical_events : public virtual basis::root_object
97 {
98 public:
99   virtual ~critical_events() {}
100
101   // super handy system inter-operation functions...
102
103   static basis::un_int system_error();
104     //!< gets the most recent system error reported on this thread.
105
106   static basis::astring system_error_text(basis::un_int error_to_show);
107     //!< returns the OS's string form of the "error_to_show".
108     /*!< this often comes from the value reported by system_error(). */
109
110   // some noisemaking methods...
111
112   //! Prints out a message to the standard error file stream.
113   static void write_to_console(const char *message);
114
115   //! shows the message in "info", with an optional "title" on the message.
116   /*! the message is sent to the program wide logger, if one is expected to
117   exist in this program. */
118   static void alert_message(const char *info, const char *title = "Alert Message");
119   static void alert_message(const basis::astring &info);  // uses default title.
120   static void alert_message(const basis::astring &info, const basis::astring &title);  // use "title".
121
122   static void write_to_critical_events(const char *message);
123     //!< sends the "message" to the critical events log file.
124     /*!< Prints out a message to the specially named file that captures all
125     serious events written to error logging functions.  If you use the
126     functions in this file, you are likely already writing to this log. */
127
128   static void set_critical_events_directory(const basis::astring &directory);
129     //!< sets the internal location where the critical events will be logged.
130     /*!< this is postponed to a higher level, although the default
131     will work too. */
132
133   static basis::astring critical_events_directory();
134     //!< returns the current location where critical events are written.
135
136   // this section implements the error macros.
137
138   //! Prints out an error message and then exits the program.
139   /*! The parameters describe the location where the error was detected.  This
140   call should only be used in test programs or where absolutely necessary
141   because it causes an almost immediate exit from the program!  deadly_error
142   should be reserved for when the program absolutely has to exit right then,
143   because this function will actually enforce a crash / abort / break into
144   debugger action rather than just calling exit(). */
145   static void FL_deadly_error(const char *file, int line, const char *classname,
146       const char *function_name, const char *info);
147   //! A version that takes strings instead of char pointers.
148   static void FL_deadly_error(const basis::astring &file, int line,
149       const basis::astring &classname, const basis::astring &function_name,
150       const basis::astring &info);
151
152   //! Describes an error like deadly_error, but does not exit the program.
153   static void FL_continuable_error(const char *file, int line,
154       const char *classname, const char *function_name, const char *info,
155       const char *title);
156
157   //! A version using astring instead of char pointers.
158   static void FL_continuable_error(const basis::astring &file, int line,
159       const basis::astring &classname, const basis::astring &function_name,
160       const basis::astring &info, const basis::astring &title);
161
162   //! Shows the same information as continuable_error, but causes an exit.
163   /*! This is a friendlier program exit than deadly_error.  This version can
164   be used when the program must stop, possibly because of a precondition failure
165   or a problem in input data or basically whatever.  it is not intended to
166   abort or break into the debugger, but to simply exit(). */
167   static void FL_non_continuable_error(const char *file, int line,
168       const char *classname, const char *function_name, const char *info,
169       const char *title);
170
171   //! A version using astring instead of char pointers.
172   static void FL_non_continuable_error(const basis::astring &file, int line,
173       const basis::astring &classname, const basis::astring &function_name,
174       const basis::astring &info, const basis::astring &title);
175
176   //! Causes the program to exit due to a memory allocation failure.
177   static void FL_out_of_memory_now(const char *file, int line,
178       const char *classname, const char *function_name);
179   
180   //! Prints out an error message to the standard error file stream.
181   static void FL_console_error(const char *file, int line, const char *error_class,
182       const char *error_function, const char *info);
183
184   //! Used to build our particular type of error message.
185   /*! It writes an error message into "guards_message_space" using our stylized
186   object::method formatting. */
187   static void make_error_message(const char *file, int line,
188       const char *error_class, const char *error_function,
189       const char *info, char *guards_message_space);
190
191   //! Provides the real implementation of bounds_halt to save code space.
192   static void implement_bounds_halt(const char *the_class_name, const char *func,
193       const char *value, const char *low, const char *high,
194       const char *error_addition);
195
196 private:
197   static basis::astring &hidden_critical_events_dir();
198
199   static void FL_continuable_error_real(const char *file, int line,
200       const char *error_class, const char *error_function, const char *info,
201       const char *title);
202 };
203
204 } //namespace.
205
206 #endif
207