1 /*
2 ================================================================================
3     PROJECT:
4 
5         Eddy C++ Utilities Project
6 
7     CONTENTS:
8 
9         Definition of classes EDDY_DebugScope and EDDY_Debug.
10 
11     NOTES:
12 
13         These classes along with the #defined macros constitute a simple
14         debugging facility that supports assertions, messages, warnings, etc.
15         as well as a simple stack tracing functionality.  These functionalities
16         are preprocessed out unless EDDY_OPTION_DEBUG is defined.  This is
17         useful to allow expensive assertions and such during debugging and have
18         them automatically stripped out for release builds.
19 
20         See also the notes under the "Class Definition" sections of this file.
21 
22     PROGRAMMERS:
23 
24         John Eddy (jpeddy@sandia.gov) (JE)
25 
26     ORGANIZATION:
27 
28         Sandia National Laboratories
29 
30     COPYRIGHT:
31 
32         See the LICENSE file in the top level JEGA directory.
33 
34     VERSION:
35 
36         1.0.0
37 
38     CHANGES:
39 
40         Thu May 22 13:52:29 2003 - Original Version (JE)
41 
42 ================================================================================
43 */
44 
45 
46 /*
47 ================================================================================
48 Document This File
49 ================================================================================
50 */
51 /** \file
52  * \brief Contains the definition classes EDDY_DebugScope and EDDY_Debug.
53  */
54 
55 
56 
57 
58 /*
59 ================================================================================
60 Prevent Multiple Inclusions
61 ================================================================================
62 */
63 #ifndef EDDY_UTILITIES_EDDY_DEBUGSCOPE_HPP
64 #define EDDY_UTILITIES_EDDY_DEBUGSCOPE_HPP
65 
66 
67 
68 
69 
70 
71 
72 /*
73 ================================================================================
74 Includes
75 ================================================================================
76 */
77 #include "config.hpp"
78 
79 
80 
81 
82 
83 
84 
85 
86 /*
87 ================================================================================
88 Preprocessor Definitions and Macros
89 ================================================================================
90 */
91 #ifdef EDDY_OPTION_DEBUG
92 
93 #   include "../../config/include/current_function.hpp"
94 
95     /// This macro causes a scope trace with messaging and program abort.
96     /**
97      * If \a a evaluates to true, this macro will print the message of \a b,
98      * print a scope trace, and abort the program.  It will also inform of
99      * the file and line number where the problem occurred.
100      *
101      * \param a The logical test based on which to abort.
102      * \param b The message to report along with file and line.
103      */
104 #   define EDDY_DEBUG(a, b)                                                 \
105         if(a) {                                                             \
106             eddy::utilities::EDDY_Debug::_Report((b), __FILE__, __LINE__);  \
107         }
108 
109     /// This macro causes a scope trace with messaging (but no abort).
110     /**
111      * If \a a evaluates to true, this macro will print the message of \a b and
112      * print a scope trace.  It will also inform of the file and line
113      * number where the problem occurred.
114      *
115      * \param a The logical test based on which to warn.
116      * \param b The message to report along with file and line.
117      */
118 #   define EDDY_WARNING(a, b)                                               \
119         if(a) {                                                             \
120             eddy::utilities::EDDY_Debug::_Warning((b), __FILE__, __LINE__); \
121         }
122 
123     /// This macro causes a scope trace and program abort.
124     /**
125      * If \a a evaluates to true, this macro will print a scope trace
126      * and abort the program.  It will also inform of the file and line
127      * number where the problem occurred.
128      *
129      * \param a The logical description of the exceptional condition.
130      */
131 #   define EDDY_ASSERT(a)                                                   \
132         if(!(a)) {                                                          \
133             eddy::utilities::EDDY_Debug::_Assert(#a, __FILE__, __LINE__);   \
134         }
135 
136     /// This macro enables catching of signal \a a.
137     /**
138      * When a signal is caught (such as SIGSEGV, etc.), this method will
139      * indicate which signal was caught, print a scope trace, and abort
140      * the program.  The allowable signals are:
141      *
142      * -SIGSEGV - Illegal storage access.
143      * -SIGINT  - CTRL+C interrupt.
144      * -SIGFPE  - Floating-point error, such as overflow, division by zero,
145      *            or invalid operation.
146      * -SIGILL  - Illegal instruction.
147      * -SIGTERM - Termination request sent to the program.
148      * -SIGABRT - Abnormal termination.
149      *
150      * \param a The signal value to enable catching of by the EDDY_DEBUGSCOPE
151      *          project.
152      */
153 #   define EDDY_DEBUGSIGNAL(a)                                              \
154         eddy::utilities::EDDY_Debug::_RegisterSignal(a);
155 
156     /// This macro pushes \a a onto the scope trace stack.
157     /**
158      * This macro actually creates an object of type EDDY_DebugScope identified
159      * by \a a.  \a a should be a string literal like "someclass::somefunc".
160      * In case of a scope trace, the text associated with this object will be
161      * printed in turn.  This should appear at the head of each method or
162      * function.  When this object goes out of scope (when the method or
163      * function exits), its destructor will be called (guaranteed by C++) and
164      * it will be removed from the scope trace stack.
165      *
166      * \param a The text to be associated with the newly created debug scope
167      *          object.
168      */
169 #   define EDDY_DEBUGSCOPE(a)                                               \
170         eddy::utilities::EDDY_DebugScope otb_debugscope_(a);
171 
172     /**
173      * \brief This macro pushes the name of the current function onto the scope
174      *        trace stack.
175      *
176      * This macro uses the EDDY_DEBUGSCOPE macro with an argument of
177      * EDDY_CURRENT_FUNCTION.
178      */
179 #   define EDDY_FUNC_DEBUGSCOPE                                             \
180         EDDY_DEBUGSCOPE(EDDY_CURRENT_FUNCTION)
181 
182     /// This macro causes a print of the scope trace.
183     /**
184      * This causes the printing of each EDDY_DebugScope object text
185      * in the order that they were pushed onto the stack.  The text
186      * is printed to standard error.
187      */
188 #   define EDDY_TRACESCOPE                                                  \
189         eddy::utilities::EDDY_DebugScope::_PrintScopeTrace();
190 
191     /// This macro causes a message to be presented on standard error.
192     /**
193      * If \a a evaluates to true, this macro will print the message of \a b.
194      * It will neither print a scope trace nor abort the program.  It will
195      * inform of the file and line number where the message originated.
196      *
197      * \param a The logical test based on which to print a message.
198      * \param b The message to print along with file and line.
199      */
200 #   define EDDY_MESSAGE(a, b)                                               \
201         if(a) {                                                             \
202             eddy::utilities::EDDY_Debug::_Message((b),__FILE__,__LINE__);   \
203         }
204 
205     /// This macro causes execution of the statement \a a.
206     /**
207      * This macro doesn't cause abortion or scope tracing.  It simply
208      * causes execution of the statement represented by \a a.
209      *
210      * \param a The statement to execute if debug scope is enabled and not
211      *          otherwise.  A semicolon will automatically appended.
212      */
213 #   define EDDY_DEBUGEXEC(a) a;
214 
215 #else
216 
217 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
218 #   define EDDY_DEBUG(a, b)
219 
220 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
221 #   define EDDY_WARNING(a, b)
222 
223 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
224 #   define EDDY_ASSERT(a)
225 
226 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
227 #   define EDDY_DEBUGSIGNAL(a)
228 
229 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
230 #   define EDDY_DEBUGSCOPE(a)
231 
232 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
233 #   define EDDY_FUNC_DEBUGSCOPE
234 
235 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
236 #   define EDDY_TRACESCOPE
237 
238 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
239 #   define EDDY_MESSAGE(a, b)
240 
241 /// Expands to nothing because EDDY_OPTION_DEBUG is not defined.
242 #   define EDDY_DEBUGEXEC(a)
243 
244 #endif
245 
246 
247 
248 
249 
250 
251 
252 
253 
254 /*
255 ================================================================================
256 Namespace Aliases
257 ================================================================================
258 */
259 
260 
261 
262 
263 
264 
265 
266 
267 /*
268 ================================================================================
269 Begin Namespace
270 ================================================================================
271 */
272 namespace eddy {
273     namespace utilities {
274 
275 
276 
277 
278 
279 
280 /*
281 ================================================================================
282 This Code is Only Compiled in DebugMode
283 ================================================================================
284 */
285 #ifdef EDDY_OPTION_DEBUG
286 
287 
288 
289 
290 
291 /*
292 ================================================================================
293 Forward Declares
294 ================================================================================
295 */
296 class EDDY_Debug;
297 class EDDY_DebugScope;
298 
299 
300 
301 
302 
303 
304 
305 
306 
307 
308 /*
309 ================================================================================
310 Class Definition for EDDY_DebugScope
311 ================================================================================
312 */
313 
314 /// Class used to manage the rudimentary scope tracing functionality.
315 /**
316  * This class only exists if EDDY_OPTION_DEBUG is defined.
317  * This class stores a list of strings which should describe methods or
318  * functions.  When one of these is created, the string passed in is
319  * pushed onto the list and when it is destroyed, the string is popped
320  * off the list.  In case of a scope trace, all the strings currently
321  * on the stack are printed out in reverse order.
322  */
323 class EDDY_SL_IEDECL EDDY_DebugScope
324 {
325     /*
326     ============================================================================
327     Member Data Declarations
328     ============================================================================
329     */
330     private:
331 
332         /**
333          * \brief Pointer to the text spit out for this object
334          *        in the event of a scope trace.
335          */
336         const char* const _data;
337 
338         /**
339          * \brief Pointer to the next of this type to show up
340          *        in the event of a scope trace.
341          */
342         EDDY_DebugScope* _next;
343 
344         /**
345          * \brief Pointer to the very first of this type to show up
346          *        in the event of a scope trace.
347          */
348         static EDDY_DebugScope* _top;
349 
350     /*
351     ============================================================================
352     Mutators
353     ============================================================================
354     */
355     public:
356 
357 
358 
359 
360 
361     /*
362     ============================================================================
363     Accessors
364     ============================================================================
365     */
366     public:
367 
368 
369 
370 
371 
372     /*
373     ============================================================================
374     Public Methods
375     ============================================================================
376     */
377     public:
378 
379         /// This method is in the expansion of the EDDY_TRACESCOPE macro.
380         /**
381          * It causes a listing of entered but not yet exited method and
382          * functions having an EDDY_DEBUGSCOPE statement.  The listing is
383          * printed to the standard output.
384          */
385         static
386         void
387         _PrintScopeTrace(
388             ) throw();
389 
390     /*
391     ============================================================================
392     Subclass Visible Methods
393     ============================================================================
394     */
395     protected:
396 
397 
398 
399 
400 
401     /*
402     ============================================================================
403     Subclass Overridable Methods
404     ============================================================================
405     */
406     public:
407 
408 
409     protected:
410 
411 
412     private:
413 
414 
415 
416 
417 
418     /*
419     ============================================================================
420     Private Methods
421     ============================================================================
422     */
423     private:
424 
425 
426 
427 
428 
429     /*
430     ============================================================================
431     Structors
432     ============================================================================
433     */
434     public:
435 
436         /// Constructs an EDDY_DebugScope object with _data = name
437         /**
438          * \param name The name to be associated with this stack entry.
439          */
440         EDDY_DebugScope(
441             const char* name
442             ) throw();
443 
444         /// Destructs an EDDY_DebugScope object
445         /**
446          * This has the effect of removing it from the list of scope traced
447          * objects.
448          */
449         ~EDDY_DebugScope(
450             ) throw();
451 
452 }; // class EDDY_DebugScope
453 
454 
455 
456 
457 
458 /*
459 ================================================================================
460 Class Definition for EDDY_Debug
461 ================================================================================
462 */
463 
464 /// Class used to manage errors, warnings, etc. and show them to the user.
465 /**
466  * Like the EDDY_DebugScope class, this class only exists if EDDY_OPTION_DEBUG
467  * is defined.  This class handles errors, warning, messages, etc. issued
468  * by the user in debug mode.  It is part of this rudimentary debugging
469  * facility that supports assertions and scope tracing.
470  */
471 class EDDY_SL_IEDECL EDDY_Debug
472 {
473     /*
474     ============================================================================
475     Member Data Declarations
476     ============================================================================
477     */
478     private:
479 
480 
481 
482     /*
483     ============================================================================
484     Mutators
485     ============================================================================
486     */
487     public:
488 
489 
490 
491     /*
492     ============================================================================
493     Accessors
494     ============================================================================
495     */
496     public:
497 
498 
499 
500     /*
501     ============================================================================
502     Public Methods
503     ============================================================================
504     */
505     public:
506 
507         /**
508          * \brief This method is in the expansion of the
509          *        EDDY_DEBUG(cond, message) macro.
510          *
511          * It causes the supplied failure message \a message to appear.
512          * This method causes a scope trace print and program abort.
513          *
514          * \param message The message to display.
515          * \param fileName The name of the file in which the problem occurred.
516          * \param line The line number in the file on which the problem
517          *             occurred.
518          */
519         static
520         void
521         _Report(
522             const char* message,
523             const char* fileName,
524             long line
525             ) throw();
526 
527 
528         /**
529          * \brief This method is in the expansion of the
530          *        EDDY_WARNING(cond, message) macro.
531          *
532          * It causes the supplied warning message \a message to appear.
533          * This method causes a scope trace print (without program abort).
534          *
535          * \param message The message to display.
536          * \param fileName The name of the file in which the problem occurred.
537          * \param line The line number in the file on which the problem
538          *             occurred.
539          */
540         static
541         void
542         _Warning(
543             const char* message,
544             const char* fileName,
545             long line
546             ) throw();
547 
548         /**
549          * \brief This method is in the expansion of the
550          *        EDDY_MESSAGE(cond, message) macro.
551          *
552          * It causes the supplied message \a message to appear.
553          * This method does not cause a scope trace or program abort.
554          *
555          * \param message The message to display.
556          * \param fileName The name of the file from which the message was
557          *                 sent.
558          * \param line The line number in the file from which the message was
559          *             sent.
560          */
561         static
562         void
563         _Message(
564             const char* message,
565             const char* fileName,
566             long line
567             ) throw();
568 
569         /// This method is in the expansion of the EDDY_ASSERT(cond) macro.
570         /**
571          * It causes the supplied message \a message which is the text
572          * equivalent of the \a cond if the EDDY_ASSERT macro is used to
573          * appear.  This method causes a scope trace print and program abort.
574          *
575          * \param message The message to display.
576          * \param fileName The name of the file in which the problem occurred.
577          * \param line The line number in the file on which the problem
578          *             occurred.
579          */
580         static
581         void
582         _Assert(
583             const char* message,
584             const char* fileName,
585             long line
586             ) throw();
587 
588         /// This method is in the expansion of the EDDY_DEBUGSIGNAL(sig) macro.
589         /**
590          * The macro registers this function as a callback in the case of
591          * the supplied signal.
592          *
593          * \param val The value of the signal that was caught and sent here.
594          */
595         static
596         void
597         _Signal(
598             int val
599             ) throw();
600 
601         /// This method is the expansion of EDDY_DEBUGSIGNAL(a)
602         /**
603          * This method registers the signal handler for \a sig as
604          * _Signal(int).
605          *
606          * \param sig The value of the signal that will be caught and sent to
607          *            _Signal(int).
608          */
609         static
610         void
611         _RegisterSignal(
612             int sig
613             ) throw();
614 
615     /*
616     ============================================================================
617     Subclass Visible Methods
618     ============================================================================
619     */
620     protected:
621 
622 
623 
624 
625 
626     /*
627     ============================================================================
628     Subclass Overridable Methods
629     ============================================================================
630     */
631     public:
632 
633 
634     protected:
635 
636 
637     private:
638 
639 
640 
641 
642 
643     /*
644     ============================================================================
645     Private Methods
646     ============================================================================
647     */
648     private:
649 
650 
651 
652 
653 
654     /*
655     ============================================================================
656     Structors
657     ============================================================================
658     */
659     public:
660 
661     private:
662 
663         /// This constructor is private and has no implementation.
664         /**
665          * All methods of this class are static and thus it should not and
666          * can not be instantiated.
667          */
668         EDDY_Debug(
669             );
670 
671 
672 }; // class EDDY_Debug
673 
674 
675 
676 #endif // #ifdef EDDY_OPTION_DEBUG
677 
678 
679 
680 
681 /*
682 ================================================================================
683 End Namespace
684 ================================================================================
685 */
686     } // namespace utilities
687 } // namespace eddy
688 
689 
690 
691 
692 
693 
694 
695 /*
696 ================================================================================
697 Include Inlined Methods File
698 ================================================================================
699 */
700 #include "./inline/EDDY_DebugScope.hpp.inl"
701 
702 
703 
704 
705 /*
706 ================================================================================
707 End of Multiple Inclusion Check
708 ================================================================================
709 */
710 #endif // EDDY_UTILITIES_EDDY_DEBUGSCOPE_HPP
711