]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/infra/cyg_ass.h
Initial revision
[karo-tx-redboot.git] / tools / src / infra / cyg_ass.h
1 #ifndef CYGONCE_INFRA_CYG_ASS_H
2 #define CYGONCE_INFRA_CYG_ASS_H
3
4 //==========================================================================
5 //
6 //      cyg_ass.h
7 //
8 //      Macros and prototypes for the assert system
9 //
10 //==========================================================================
11 //####COPYRIGHTBEGIN####
12 //                                                                          
13 // ----------------------------------------------------------------------------
14 // Copyright (C) 1997, 1998, 1999, 2000 Red Hat, Inc.
15 //
16 // This file is part of the eCos host tools.
17 //
18 // This program is free software; you can redistribute it and/or modify it 
19 // under the terms of the GNU General Public License as published by the Free 
20 // Software Foundation; either version 2 of the License, or (at your option) 
21 // any later version.
22 // 
23 // This program is distributed in the hope that it will be useful, but WITHOUT 
24 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
25 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
26 // more details.
27 // 
28 // You should have received a copy of the GNU General Public License along with
29 // this program; if not, write to the Free Software Foundation, Inc., 
30 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31 //
32 // ----------------------------------------------------------------------------
33 //                                                                          
34 //####COPYRIGHTEND####
35 //==========================================================================
36 //#####DESCRIPTIONBEGIN####
37 //
38 // Author(s):   nickg from an original by hmt
39 // Contributors:        nickg
40 // Date:        1997-09-08
41 // Purpose:     Use asserts to avoid writing duff code.
42 // Description: Runtime tests that compile to nothing in
43 //              release versions of the code, to allow
44 //              as-you-go testing of alternate builds.
45 // Usage:       #include <cyg/infra/cyg_ass.h>
46 //              ...
47 //              CYG_ASSERT( pcount > 0, "Number of probes should be > 0!" );
48 //
49 //      which can result, for example, in a message of the form:
50 //      ASSERT FAILED: probemgr.cxx:1340, scan_probes() :
51 //                     number of probes should be > 0!
52 //      if the boolean "pcount > 0" is false.
53 //
54 //####DESCRIPTIONEND####
55 //
56 //==========================================================================
57
58 #include <pkgconf/infra.h>
59
60 #include <cyg/infra/cyg_type.h>         // for CYGBLD_ATTRIB_NORET
61
62 // -------------------------------------------------------------------------
63 // If we do not have a function name macro, define it ourselves
64
65 #ifndef CYGDBG_INFRA_DEBUG_FUNCTION_PSEUDOMACRO
66                                         // __PRETTY_FUNCTION__ does not work
67 # ifndef __PRETTY_FUNCTION__            // And it is not already defined
68 #  define __PRETTY_FUNCTION__ NULL
69 # endif
70 #endif
71
72 // -------------------------------------------------------------------------
73 // this is executed to deal with failure - breakpoint it first!
74
75 externC void
76 cyg_assert_fail( const char* /* psz_func */, const char* /* psz_file */,
77                  cyg_uint32 /* linenum */, const char* /* psz_msg */ )
78     CYGBLD_ATTRIB_NORET;
79
80 // -------------------------------------------------------------------------
81
82 #ifdef CYGDBG_USE_ASSERTS
83
84 // -------------------------------------------------------------------------
85 // We define macros and appropriate prototypes for the assert/fail
86 // system.  These are:
87 //      CYG_FAIL        - unconditional panic
88 //      CYG_ASSERT      - panic if boolean expression is false
89 //      CYG_ASSERTC     - compact version of CYG_ASSERT
90
91 # ifdef CYGDBG_INFRA_DEBUG_ASSERT_MESSAGE
92 #  define CYG_ASSERT_DOCALL( _msg_ ) \
93         cyg_assert_fail( __PRETTY_FUNCTION__, __FILE__, __LINE__, _msg_ );
94 # else
95 #   define CYG_ASSERT_DOCALL( _msg_ )    \
96         CYG_MACRO_START                 \
97         const char* _tmp1_ = _msg_;     \
98         _tmp1_ = _tmp1_;                \
99         cyg_assert_fail( __PRETTY_FUNCTION__, __FILE__, __LINE__, NULL ); \
100         CYG_MACRO_END
101 # endif
102
103 // unconditional failure; use like panic(), coredump() &c.
104 # define CYG_FAIL( _msg_ )              \
105         CYG_MACRO_START                 \
106         CYG_ASSERT_DOCALL( _msg_ );      \
107         CYG_MACRO_END
108
109 // conditioned assert; if the condition is false, fail.
110 # define CYG_ASSERT( _bool_, _msg_ )    \
111         CYG_MACRO_START                 \
112         if ( ! ( _bool_ ) )             \
113             CYG_ASSERT_DOCALL( _msg_ );  \
114         CYG_MACRO_END
115
116 # define CYG_ASSERTC( _bool_ )          \
117        CYG_MACRO_START                  \
118        if ( ! ( _bool_ ) )              \
119            CYG_ASSERT_DOCALL( #_bool_ );\
120        CYG_MACRO_END
121
122 #else // ! CYGDBG_USE_ASSERTS
123
124 // -------------------------------------------------------------------------
125 // No asserts: we define empty statements for assert & fail.
126
127 # define CYG_FAIL( _msg_ )           CYG_EMPTY_STATEMENT
128 # define CYG_ASSERT( _bool_, _msg_ ) CYG_EMPTY_STATEMENT
129 # define CYG_ASSERTC( _bool_ )       CYG_EMPTY_STATEMENT
130
131 #endif // ! CYGDBG_USE_ASSERTS
132
133 // -------------------------------------------------------------------------
134 // Pointer integrity checks.
135 // These check not only for NULL pointer, but can also check for pointers
136 // that are outside to defined memory areas of the platform or executable.
137 // We differentiate between data and function pointers, so that we can cope
138 // with different formats, and so we can check them against different memory
139 // regions.
140
141 externC cyg_bool cyg_check_data_ptr(void *ptr);
142 externC cyg_bool cyg_check_func_ptr(void (*ptr)(void));
143
144 #ifdef CYGDBG_USE_ASSERTS
145
146 # define CYG_CHECK_DATA_PTR( _ptr_, _msg_ )             \
147         CYG_MACRO_START                                 \
148         if( !cyg_check_data_ptr((void *)(_ptr_)))       \
149            CYG_ASSERT_DOCALL( _msg_ );                   \
150         CYG_MACRO_END
151
152 # define CYG_CHECK_FUNC_PTR( _ptr_, _msg_ )             \
153         CYG_MACRO_START                                 \
154         if( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
155            CYG_ASSERT_DOCALL( _msg_ );                   \
156         CYG_MACRO_END
157         
158 # define CYG_CHECK_DATA_PTRC( _ptr_ )                   \
159          CYG_MACRO_START                                \
160          if ( !cyg_check_data_ptr((void *)(_ptr_)))     \
161              CYG_ASSERT_DOCALL("data pointer (" #_ptr_ ") is valid");\
162          CYG_MACRO_END
163
164 # define CYG_CHECK_FUNC_PTRC( _ptr_ )                       \
165          CYG_MACRO_START                                    \
166          if ( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
167              CYG_ASSERT_DOCALL("function pointer (" #_ptr_ ") is valid"); \
168          CYG_MACRO_END
169
170 #else // CYGDBG_USE_ASSERTS
171
172 # define CYG_CHECK_DATA_PTR( _ptr_, _msg_ ) CYG_EMPTY_STATEMENT
173 # define CYG_CHECK_FUNC_PTR( _ptr_, _msg_ ) CYG_EMPTY_STATEMENT
174 # define CYG_CHECK_DATA_PTRC( _ptr_ )       CYG_EMPTY_STATEMENT
175 # define CYG_CHECK_FUNC_PTRC( _ptr_ )       CYG_EMPTY_STATEMENT
176
177 #endif // CYGDBG_USE_ASSERTS
178             
179 // -------------------------------------------------------------------------
180 // Unconditional definitions:
181
182 // Check an object for validity by calling its own checker.
183 // Usage:
184 //   ClassThing *p = &classobject;
185 //   CYG_ASSERTCLASS( p, "Object at p is broken!" );
186
187 // this enum gives some options as to how keenly to test; avoids cluttering
188 // the member function declaration if the implementor wants to do more
189 // zealous tests themselves.
190
191 enum cyg_assert_class_zeal {
192   cyg_system_test       = -1,
193   cyg_none              = 0,
194   cyg_trivial,
195   cyg_quick,
196   cyg_thorough,
197   cyg_extreme
198 };
199
200 // -------------------------------------------------------------------------
201 // Define macros for checking classes:
202 //
203 //      CYG_ASSERT_CLASS        - do proforma check on a class pointer
204 //      CYG_ASSERT_CLASSO       - do proforma check on a class object
205 //      CYG_ASSERT_ZERO_OR_CLASS- a class pointer is NULL or valid
206 //      CYG_ASSERT_THIS         - "this" is valid
207 //      + 3 compact variants and two aliases for backwards compatibility.
208 //
209 // All of these end up going via CYG_ASSERT(), which will be an empty
210 // statement if CYGDBG_USE_ASSERTS is disabled. There is no need to
211 // test CYGDBG_USE_ASSERTS again here.
212 //
213 // The idiom required is that a class have a member function called
214 // "bool check_this( cyg_assert_class_zeal ) const" that returns true
215 // iff the object is OK.  This need not be conditionally compiled against
216 // CYGDBG_USE_ASSERTS but it can be if only this macro is used to
217 // invoke it.  Alternatively it can be invoked by hand with other
218 // choices from the above enum.
219
220 // Assert the checker function of an object by pointer, or in hand.
221
222 #ifdef __cplusplus
223
224 # ifndef CYG_ASSERT_CLASS_ZEAL
225 #  define CYG_ASSERT_CLASS_ZEAL (cyg_quick) // can be redefined locally
226 # endif
227
228 # define CYG_ASSERT_CLASS( _pobj_, _msg_ ) \
229     CYG_ASSERT( ((0 != (_pobj_)) &&        \
230                  (_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
231
232 # define CYG_ASSERTCLASS( _pobj_,_msg_) \
233     CYG_ASSERT_CLASS( (_pobj_), _msg_ )
234
235 # define CYG_ASSERT_CLASSO( _obj_, _msg_ ) \
236     CYG_ASSERT( (_obj_).check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
237
238 # define CYG_ASSERTCLASSO( _obj_, _msg_ ) \
239     CYG_ASSERT_CLASSO( (_obj_), _msg_ )
240
241 # define CYG_ASSERT_ZERO_OR_CLASS( _pobj_, _msg_ ) \
242     CYG_ASSERT( ((0 == (_pobj_)) ||                \
243                  (_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
244
245 # define CYG_ASSERT_THIS( _msg_ ) \
246     CYG_ASSERT( this->check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
247
248 # define CYG_ASSERT_CLASSC( _pobj_ ) \
249     CYG_ASSERT_CLASS( (_pobj_), "class pointer (" #_pobj_ ") is valid" )
250
251 # define CYG_ASSERT_CLASSOC( _obj_ ) \
252     CYG_ASSERT_CLASSO( (_obj_), "object (" #_obj_ ") is valid" )
253
254 # define CYG_ASSERT_ZERO_OR_CLASSC( _pobj_ ) \
255     CYG_ASSERT_ZERO_OR_CLASS((_pobj_),       \
256         "class pointer (" #_pobj_ ") is zero or valid")
257
258 # define CYG_ASSERT_THISC( ) \
259     CYG_ASSERT_THIS( "\"this\" pointer is valid" )
260     
261 #define CYGDBG_DEFINE_CHECK_THIS \
262     bool check_this( cyg_assert_class_zeal zeal ) const;
263
264 #endif // __cplusplus
265
266 // -------------------------------------------------------------------------
267 // Some alternative names for basic assertions that we can disable
268 // individually.
269 //
270 //      CYG_PRECONDITION        - argument checking etc
271 //      CYG_POSTCONDITION       - results etc
272 //      CYG_LOOP_INVARIANT      - for putting in loops
273 //
274 // C++ programmers have class-related variants of all of these.
275
276 #ifdef CYGDBG_INFRA_DEBUG_PRECONDITIONS
277 # define CYG_PRECONDITION( _bool_ , _msg_ ) CYG_ASSERT( _bool_, _msg_ )
278 # define CYG_PRECONDITIONC( _bool_ ) \
279     CYG_ASSERT( _bool_, "precondition " #_bool_)
280 #else
281 # define CYG_PRECONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
282 # define CYG_PRECONDITIONC( _bool_ )        CYG_EMPTY_STATEMENT
283 #endif
284
285 #ifdef CYGDBG_INFRA_DEBUG_POSTCONDITIONS
286 # define CYG_POSTCONDITION( _bool_ , _msg_ ) CYG_ASSERT( _bool_, _msg_ )
287 # define CYG_POSTCONDITIONC( _bool_ ) \
288     CYG_ASSERT( _bool_, "postcondition " #_bool_)
289 #else
290 # define CYG_POSTCONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
291 # define CYG_POSTCONDITIONC( _bool_ )        CYG_EMPTY_STATEMENT
292 #endif
293
294 #ifdef CYGDBG_INFRA_DEBUG_LOOP_INVARIANTS
295 # define CYG_LOOP_INVARIANT( _bool_ , _msg_ ) CYG_ASSERT( _bool_, _msg_ )
296 # define CYG_LOOP_INVARIANTC( _bool_ ) \
297     CYG_ASSERT( _bool_, "loop invariant " #_bool_ )
298 #else
299 # define CYG_LOOP_INVARIANT( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
300 # define CYG_LOOP_INVARIANTC( _bool_ )        CYG_EMPTY_STATEMENT
301 #endif
302
303 #ifdef __cplusplus
304
305 // All variants of _CLASS
306 # define CYG_PRECONDITION_CLASS( _pobj_, _msg_ )  \
307     CYG_PRECONDITION( ((0 != (_pobj_)) &&         \
308                        (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
309
310 # define CYG_PRECONDITION_CLASSC( _pobj_ )        \
311     CYG_PRECONDITION_CLASS( (_pobj_),             \
312        "precondition, class pointer (" #_pobj_ ") is valid" )
313     
314 # define CYG_POSTCONDITION_CLASS( _pobj_, _msg_ ) \
315     CYG_POSTCONDITION( ((0 != (_pobj_)) &&        \
316                         (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
317
318 # define CYG_POSTCONDITION_CLASSC( _pobj_ )       \
319     CYG_POSTCONDITION_CLASS( (_pobj_),            \
320        "postcondition, class pointer (" #_pobj_ ") is valid" )
321
322 # define CYG_LOOP_INVARIANT_CLASS( _pobj_, _msg_) \
323     CYG_LOOP_INVARIANT( ((0 != (_pobj_)) &&       \
324                          (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
325         
326 # define CYG_LOOP_INVARIANT_CLASSC( _pobj_ )      \
327     CYG_LOOP_INVARIANT_CLASS( (_pobj_),           \
328        "loop invariant, class pointer (" #_pobj_ ") is valid" )
329
330 // All variants of _CLASSO
331 # define CYG_PRECONDITION_CLASSO( _obj_, _msg_ )  \
332     CYG_PRECONDITION( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
333     
334 # define CYG_PRECONDITION_CLASSOC( _obj_ )        \
335     CYG_PRECONDITION_CLASSO( (_obj_),             \
336         "precondition, object (" #_obj_ ") is valid" )
337
338 # define CYG_POSTCONDITION_CLASSO( _obj_, _msg_ ) \
339     CYG_POSTCONDITION( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
340     
341 # define CYG_POSTCONDITION_CLASSOC( _obj_ )       \
342     CYG_POSTCONDITION_CLASSO( (_obj_),            \
343        "postcondition, object (" #_obj_ ") is valid" )
344                              
345 # define CYG_LOOP_INVARIANT_CLASSO( _obj_, _msg_) \
346     CYG_LOOP_INVARIANT( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
347
348 # define CYG_LOOP_INVARIANT_CLASSOC( _obj_ )      \
349     CYG_LOOP_INVARIANT_CLASSO( (_obj_),           \
350        "loop invariant, object (" #_obj_ ") is valid" )
351
352 // All variants of _ZERO_OR_CLASS
353 # define CYG_PRECONDITION_ZERO_OR_CLASS( _pobj_, _msg_ )  \
354     CYG_PRECONDITION( ((0 == (_pobj_)) ||                 \
355                        (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
356     
357 # define CYG_PRECONDITION_ZERO_OR_CLASSC( _pobj_ )        \
358     CYG_PRECONDITION_ZERO_OR_CLASS( (_pobj_),             \
359        "precondition, class pointer (" #_pobj_ ") is zero or valid" )
360     
361 # define CYG_POSTCONDITION_ZERO_OR_CLASS( _pobj_, _msg_ ) \
362     CYG_POSTCONDITION( ((0 == (_pobj_)) ||                \
363                         (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
364
365 # define CYG_POSTCONDITION_ZERO_OR_CLASSC( _pobj_ )       \
366     CYG_POSTCONDITION_ZERO_OR_CLASS( (_pobj_),            \
367        "postcondition, class pointer (" #_pobj_ ") is zero or valid" )
368                              
369 # define CYG_LOOP_INVARIANT_ZERO_OR_CLASS( _pobj_, _msg_) \
370     CYG_LOOP_INVARIANT( ((0 == (_pobj_)) ||               \
371                          (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
372         
373 # define CYG_LOOP_INVARIANT_ZERO_OR_CLASSC( _pobj_ )      \
374     CYG_LOOP_INVARIANT_ZERO_OR_CLASS( (_pobj_),           \
375        "loop invariant, class pointer (" #_pobj_ ") is zero or valid" )
376
377 // All variants of _THIS
378 # define CYG_PRECONDITION_THIS( _msg_ )  \
379     CYG_PRECONDITION( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
380     
381 # define CYG_PRECONDITION_THISC()        \
382     CYG_PRECONDITION_THIS( "precondition, \"this\"  is valid" )
383     
384 # define CYG_POSTCONDITION_THIS( _msg_ ) \
385     CYG_POSTCONDITION( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
386     
387 # define CYG_POSTCONDITION_THISC()       \
388     CYG_POSTCONDITION_THIS( "postcondition, \"this\" is valid" )
389                              
390 # define CYG_LOOP_INVARIANT_THIS( _msg_) \
391     CYG_LOOP_INVARIANT( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
392         
393 # define CYG_LOOP_INVARIANT_THISC()      \
394     CYG_LOOP_INVARIANT_THIS( "loop invariant, \"this\" is valid" )
395
396 #endif // __cplusplus
397
398 // -------------------------------------------------------------------------
399 // Invariants. These are a bit more interesting. The ordinary invariants
400 // take an arbitrary boolean expression, and C++ does not provide any way
401 // of evaluating this expression automatically on entry and exit - any
402 // attempt to use local objects leads to trying to evaluate the expression
403 // when it is not in scope. This problem does not arise with objects.
404 //
405 // For C++ objects it is possible to do a bit better. A template can be
406 // used to create a local object whose constructor will validate the
407 // target object and whose destructor will validate the target object
408 // again. Unfortunately it is necessary to pass the type as well as
409 // the object: typeof() is a gcc extension, and RTTI's typeid facility
410 // would provide the derived class and not what we actually want.            
411
412 #ifdef CYGDBG_INFRA_DEBUG_INVARIANTS    
413
414 # define CYG_INVARIANT( _bool_, _msg_ ) \
415         CYG_MACRO_START                 \
416         if ( ! ( _bool_ ) )             \
417             CYG_ASSERT_DOCALL( _msg_ ); \
418         CYG_MACRO_END
419
420 # define CYG_INVARIANTC( _bool_ )       \
421         CYG_MACRO_START                 \
422         if ( ! ( _bool_ ) )             \
423             CYG_ASSERT_DOCALL( "invariant (" #_bool_ ")" ); \
424         CYG_MACRO_END
425
426 # ifdef __cplusplus
427 // NOTE: if the compiler does not manage to inline the appropriate
428 // template functions then the impact on code size and performance becomes
429 // rather large. But there are significant performance overheads anyway
430 // simply because of the call to check_this()...            
431 //
432 template<class X> class __CygInvariantObject {
433
434     const X*  rep;
435
436   private:
437     // Prevent access to the default constructors.
438     __CygInvariantObject() { }
439     __CygInvariantObject( const __CygInvariantObject&  arg ) { }
440     __CygInvariantObject & operator=( const __CygInvariantObject & arg) { return *this; }
441     
442   public:
443     __CygInvariantObject( X* arg, const char* msg ) : rep(arg) {
444         if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
445             CYG_ASSERT_DOCALL( msg );
446     }
447     __CygInvariantObject( X& arg, const char* msg ) : rep(&arg) {
448         if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
449             CYG_ASSERT_DOCALL( msg );
450     }
451     __CygInvariantObject( const X* arg, const char* msg ) : rep(arg) {
452         if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
453             CYG_ASSERT_DOCALL( msg );
454     }
455     __CygInvariantObject( const X& arg, const char* msg ) : rep(&arg) {
456         if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
457             CYG_ASSERT_DOCALL( msg );
458     }
459     ~__CygInvariantObject( ) {
460         if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
461             CYG_ASSERT_DOCALL( "invariant, object valid on exit" );
462         rep = 0;
463     };
464 };
465
466 //
467 // These macros provide sensible concatenation facilities at
468 // the C preprocessor level, getting around complications in the
469 // macro expansion rules related to __LINE__ and __FILE__.
470
471 # define __CYG_INVARIANT_CLASSNAME_AUX( a, b) a ## b
472 # define __CYG_INVARIANT_CLASSNAME( a, b ) \
473               __CYG_INVARIANT_CLASSNAME_AUX( a, b )
474
475
476 // These macro definitions do not use CYG_MACRO_START because
477 // I do not want the scope of the local objects to get confused.
478 //
479 // The first line of the macro expansion specifies the type of
480 // the local object being created. The second line invents a
481 // name for this object. The third line provides command-line
482 // arguments.    
483
484 # define CYG_INVARIANT_CLASS( _type_, _pobj_, _msg_ )          \
485      __CygInvariantObject<_type_>                              \
486      __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
487               ( _pobj_, _msg_ )
488
489 # define CYG_INVARIANT_CLASSC( _type_, _pobj_ )                \
490      __CygInvariantObject<_type_>                              \
491      __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
492               ( _pobj_, "invariant, class pointer (" #_pobj_ ") is valid" )
493          
494 # define CYG_INVARIANT_CLASSO( _type_, _obj_, _msg_ )          \
495      __CygInvariantObject<_type_>                              \
496      __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
497               ( _obj_, _msg_ )
498
499 # define CYG_INVARIANT_CLASSOC( _type_, _obj_ )                \
500      __CygInvariantObject<_type_>                              \
501      __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
502               ( _obj_, "invariant, object (" #_obj_ ") is valid" )
503
504 # define CYG_INVARIANT_THIS( _type_, _msg_ )                   \
505      __CygInvariantObject<_type_>                              \
506      __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
507               ( this, _msg_ )
508          
509 # define CYG_INVARIANT_THISC( _type_ )                         \
510      __CygInvariantObject<_type_>                              \
511      __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
512               ( this, "invariant, \"this\" is valid" )
513
514 # endif // __cplusplus
515
516 #else  // !CYGDBG_INFRA_DEBUG_INVARIANTS
517
518 # define CYG_INVARIANT( _bool_, _msg_ ) CYG_EMPTY_STATEMENT
519 # define CYG_INVARIANTC( _bool_ )       CYG_EMPTY_STATEMENT
520
521 # ifdef __cplusplus
522
523 #  define CYG_INVARIANT_CLASS( _type_, _pobj_, _msg_ )
524 #  define CYG_INVARIANT_CLASSC( _type_, _pobj_ )
525 #  define CYG_INVARIANT_CLASSO( _type_, _obj_, _msg_ )
526 #  define CYG_INVARIANT_CLASSOC( _type_, _obj_ )
527 #  define CYG_INVARIANT_THIS( _type_, _msg_ )
528 #  define CYG_INVARIANT_THISC( _type_ )
529
530 # endif
531     
532 #endif // CYGDBG_INFRA_DEBUG_INVARIANTS
533
534 // -------------------------------------------------------------------------
535 // Compile time failure; like #error but in a macro so we can use it in
536 // other definitions.
537 //
538 // Usage:
539 // #define new CYG_COMPILETIMEFAIL( "Do NOT use new!")
540
541 #define CYG_COMPILETIMEFAIL( _msg_ ) !!!-- _msg_ --!!!
542
543
544 // -------------------------------------------------------------------------
545 // The host-side implementation of the infrastructure provides a number
546 // of additional functions that allow applications to provide their own
547 // implementation of cyg_assert_fail(). This is not strictly necessary
548 // since the presence of cyg_assert_fail() in the application would
549 // override the one in the library anyway, but it is useful to make
550 // certain functionality more readily available.
551 //
552 // These declarations are only available if the symbol
553 // CYG_DECLARE_HOST_ASSERTION_SUPPORT is defined.
554 #ifdef CYG_DECLARE_HOST_ASSERTION_SUPPORT
555
556 // The default assertion handler writes its output to a file and
557 // if possible a suitable message to stdout. It is possible to
558 // install an alternative handler. If this alternative returns false
559 // then the default handler will be invoked instead, otherwise the
560 // application will exit.
561 externC void cyg_assert_install_failure_handler(
562                 bool (*)(const char* /* psz_func */,
563                          const char* /* psz_file */,
564                          cyg_uint32  /* linenum */,
565                          const char* /* psz_msg */) );
566
567 // Register a callback that should get invoked as part of handling an
568 // assertion failure and that will typically produce some additional
569 // output. For example the trace code will install a callback to output
570 // trace information.
571 //
572 // The first argument is a string identifying the callback. The second
573 // argument is a function pointer for the callback itself, whose
574 // argument is another function that can be invoked for output.
575 externC void cyg_assert_install_failure_callback(
576                 const char* /* name */,
577                 void (*)( void (*)(const char*) ));
578
579 // This function can be called by assert failure handlers to invoke
580 // the installed callbacks. The three arguments are function pointers
581 // that get invoked prior to callback invocation, by the callback itself,
582 // and after each callback. In the first case the argument will be the
583 // callback name.
584 externC void cyg_assert_failure_invoke_callbacks(
585                 void (*)(const char* /* name */),
586                 void (*)(const char* /* callback data */ ),
587                 void (*)(void) );
588
589 // This function is intended to be called from inside gdb instead of
590 // cyg_assert_fail(),, without the need to specify a filename or
591 // anything else.
592 externC void cyg_assert_quickfail(void);
593
594 #endif // CYG_DECLARE_HOST_ASSERTION_SUPPORT
595     
596 // -------------------------------------------------------------------------
597
598 #endif // CYGONCE_INFRA_CYG_ASS_H multiple inclusion protection
599 // EOF cyg_ass.h