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