1 #ifndef CYGONCE_INFRA_CYG_ASS_H
2 #define CYGONCE_INFRA_CYG_ASS_H
4 //==========================================================================
8 // Macros and prototypes for the assert system
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.
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.
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
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.
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.
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.
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####
46 // Author(s): nickg from an original by hmt
47 // Contributors: nickg
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>
55 // CYG_ASSERT( pcount > 0, "Number of probes should be > 0!" );
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.
62 //####DESCRIPTIONEND####
64 //==========================================================================
66 #include <pkgconf/infra.h>
68 #include <cyg/infra/cyg_type.h> // for CYGBLD_ATTRIB_NORET
70 // -------------------------------------------------------------------------
71 // If we do not have a function name macro, define it ourselves
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
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
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;
91 cyg_assert_msg( const char *psz_func, const char *psz_file,
92 cyg_uint32 linenum, const char *psz_msg ) __THROW;
94 // -------------------------------------------------------------------------
96 #ifdef CYGDBG_USE_ASSERTS
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
105 # ifdef CYGDBG_INFRA_DEBUG_ASSERT_MESSAGE
106 # define CYG_ASSERT_DOCALL( _msg_ ) \
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_ );\
113 # define CYG_ASSERT_DOCALL( _msg_ ) \
115 const char* _tmp1_ = _msg_; \
117 cyg_assert_fail( __PRETTY_FUNCTION__, __FILE__, __LINE__, NULL ); \
121 // unconditional failure; use like panic(), coredump() &c.
122 # define CYG_FAIL( _msg_ ) \
124 CYG_ASSERT_DOCALL( _msg_ ); \
127 // conditioned assert; if the condition is false, fail.
128 # define CYG_ASSERT( _bool_, _msg_ ) \
130 if ( ! ( _bool_ ) ) \
131 CYG_ASSERT_DOCALL( _msg_ ); \
134 # define CYG_ASSERTC( _bool_ ) \
136 if ( ! ( _bool_ ) ) \
137 CYG_ASSERT_DOCALL( #_bool_ );\
140 #else // ! CYGDBG_USE_ASSERTS
142 // -------------------------------------------------------------------------
143 // No asserts: we define empty statements for assert & fail.
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
149 #endif // ! CYGDBG_USE_ASSERTS
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
159 externC cyg_bool cyg_check_data_ptr(const void *ptr);
160 externC cyg_bool cyg_check_func_ptr(void (*ptr)(void));
162 #ifdef CYGDBG_USE_ASSERTS
164 # define CYG_CHECK_DATA_PTR( _ptr_, _msg_ ) \
166 if( !cyg_check_data_ptr((const void *)(_ptr_))) \
167 CYG_ASSERT_DOCALL( _msg_ ); \
170 # define CYG_CHECK_FUNC_PTR( _ptr_, _msg_ ) \
172 if( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
173 CYG_ASSERT_DOCALL( _msg_ ); \
176 # define CYG_CHECK_DATA_PTRC( _ptr_ ) \
178 if ( !cyg_check_data_ptr((const void *)(_ptr_))) \
179 CYG_ASSERT_DOCALL("data pointer (" #_ptr_ ") is valid");\
182 # define CYG_CHECK_FUNC_PTRC( _ptr_ ) \
184 if ( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
185 CYG_ASSERT_DOCALL("function pointer (" #_ptr_ ") is valid"); \
188 #else // CYGDBG_USE_ASSERTS
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
195 #endif // CYGDBG_USE_ASSERTS
197 // -------------------------------------------------------------------------
198 // Unconditional definitions:
200 // Check an object for validity by calling its own checker.
202 // ClassThing *p = &classobject;
203 // CYG_ASSERTCLASS( p, "Object at p is broken!" );
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.
209 enum cyg_assert_class_zeal {
210 cyg_system_test = -1,
218 // -------------------------------------------------------------------------
219 // Define macros for checking classes:
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.
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.
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.
238 // Assert the checker function of an object by pointer, or in hand.
242 # ifndef CYG_ASSERT_CLASS_ZEAL
243 # define CYG_ASSERT_CLASS_ZEAL (cyg_quick) // can be redefined locally
246 # define CYG_ASSERT_CLASS( _pobj_, _msg_ ) \
247 CYG_ASSERT( ((0 != (_pobj_)) && \
248 (_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
250 # define CYG_ASSERTCLASS( _pobj_,_msg_) \
251 CYG_ASSERT_CLASS( (_pobj_), _msg_ )
253 # define CYG_ASSERT_CLASSO( _obj_, _msg_ ) \
254 CYG_ASSERT( (_obj_).check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
256 # define CYG_ASSERTCLASSO( _obj_, _msg_ ) \
257 CYG_ASSERT_CLASSO( (_obj_), _msg_ )
259 # define CYG_ASSERT_ZERO_OR_CLASS( _pobj_, _msg_ ) \
260 CYG_ASSERT( ((0 == (_pobj_)) || \
261 (_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
263 # define CYG_ASSERT_THIS( _msg_ ) \
264 CYG_ASSERT( this->check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
266 # define CYG_ASSERT_CLASSC( _pobj_ ) \
267 CYG_ASSERT_CLASS( (_pobj_), "class pointer (" #_pobj_ ") is valid" )
269 # define CYG_ASSERT_CLASSOC( _obj_ ) \
270 CYG_ASSERT_CLASSO( (_obj_), "object (" #_obj_ ") is valid" )
272 # define CYG_ASSERT_ZERO_OR_CLASSC( _pobj_ ) \
273 CYG_ASSERT_ZERO_OR_CLASS((_pobj_), \
274 "class pointer (" #_pobj_ ") is zero or valid")
276 # define CYG_ASSERT_THISC( ) \
277 CYG_ASSERT_THIS( "\"this\" pointer is valid" )
279 #define CYGDBG_DEFINE_CHECK_THIS \
280 cyg_bool check_this( cyg_assert_class_zeal zeal ) const;
282 #endif // __cplusplus
284 // -------------------------------------------------------------------------
285 // Some alternative names for basic assertions that we can disable
288 // CYG_PRECONDITION - argument checking etc
289 // CYG_POSTCONDITION - results etc
290 // CYG_LOOP_INVARIANT - for putting in loops
292 // C++ programmers have class-related variants of all of these.
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_)
299 # define CYG_PRECONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
300 # define CYG_PRECONDITIONC( _bool_ ) CYG_EMPTY_STATEMENT
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_)
308 # define CYG_POSTCONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
309 # define CYG_POSTCONDITIONC( _bool_ ) CYG_EMPTY_STATEMENT
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_ )
317 # define CYG_LOOP_INVARIANT( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
318 # define CYG_LOOP_INVARIANTC( _bool_ ) CYG_EMPTY_STATEMENT
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_)
328 # define CYG_PRECONDITION_CLASSC( _pobj_ ) \
329 CYG_PRECONDITION_CLASS( (_pobj_), \
330 "precondition, class pointer (" #_pobj_ ") is valid" )
332 # define CYG_POSTCONDITION_CLASS( _pobj_, _msg_ ) \
333 CYG_POSTCONDITION( ((0 != (_pobj_)) && \
334 (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
336 # define CYG_POSTCONDITION_CLASSC( _pobj_ ) \
337 CYG_POSTCONDITION_CLASS( (_pobj_), \
338 "postcondition, class pointer (" #_pobj_ ") is valid" )
340 # define CYG_LOOP_INVARIANT_CLASS( _pobj_, _msg_) \
341 CYG_LOOP_INVARIANT( ((0 != (_pobj_)) && \
342 (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
344 # define CYG_LOOP_INVARIANT_CLASSC( _pobj_ ) \
345 CYG_LOOP_INVARIANT_CLASS( (_pobj_), \
346 "loop invariant, class pointer (" #_pobj_ ") is valid" )
348 // All variants of _CLASSO
349 # define CYG_PRECONDITION_CLASSO( _obj_, _msg_ ) \
350 CYG_PRECONDITION( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
352 # define CYG_PRECONDITION_CLASSOC( _obj_ ) \
353 CYG_PRECONDITION_CLASSO( (_obj_), \
354 "precondition, object (" #_obj_ ") is valid" )
356 # define CYG_POSTCONDITION_CLASSO( _obj_, _msg_ ) \
357 CYG_POSTCONDITION( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
359 # define CYG_POSTCONDITION_CLASSOC( _obj_ ) \
360 CYG_POSTCONDITION_CLASSO( (_obj_), \
361 "postcondition, object (" #_obj_ ") is valid" )
363 # define CYG_LOOP_INVARIANT_CLASSO( _obj_, _msg_) \
364 CYG_LOOP_INVARIANT( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
366 # define CYG_LOOP_INVARIANT_CLASSOC( _obj_ ) \
367 CYG_LOOP_INVARIANT_CLASSO( (_obj_), \
368 "loop invariant, object (" #_obj_ ") is valid" )
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_)
375 # define CYG_PRECONDITION_ZERO_OR_CLASSC( _pobj_ ) \
376 CYG_PRECONDITION_ZERO_OR_CLASS( (_pobj_), \
377 "precondition, class pointer (" #_pobj_ ") is zero or valid" )
379 # define CYG_POSTCONDITION_ZERO_OR_CLASS( _pobj_, _msg_ ) \
380 CYG_POSTCONDITION( ((0 == (_pobj_)) || \
381 (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
383 # define CYG_POSTCONDITION_ZERO_OR_CLASSC( _pobj_ ) \
384 CYG_POSTCONDITION_ZERO_OR_CLASS( (_pobj_), \
385 "postcondition, class pointer (" #_pobj_ ") is zero or valid" )
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_)
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" )
395 // All variants of _THIS
396 # define CYG_PRECONDITION_THIS( _msg_ ) \
397 CYG_PRECONDITION( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
399 # define CYG_PRECONDITION_THISC() \
400 CYG_PRECONDITION_THIS( "precondition, \"this\" is valid" )
402 # define CYG_POSTCONDITION_THIS( _msg_ ) \
403 CYG_POSTCONDITION( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
405 # define CYG_POSTCONDITION_THISC() \
406 CYG_POSTCONDITION_THIS( "postcondition, \"this\" is valid" )
408 # define CYG_LOOP_INVARIANT_THIS( _msg_) \
409 CYG_LOOP_INVARIANT( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
411 # define CYG_LOOP_INVARIANT_THISC() \
412 CYG_LOOP_INVARIANT_THIS( "loop invariant, \"this\" is valid" )
414 #endif // __cplusplus
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.
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.
430 #ifdef CYGDBG_INFRA_DEBUG_INVARIANTS
432 # define CYG_INVARIANT( _bool_, _msg_ ) \
434 if ( ! ( _bool_ ) ) \
435 CYG_ASSERT_DOCALL( _msg_ ); \
438 # define CYG_INVARIANTC( _bool_ ) \
440 if ( ! ( _bool_ ) ) \
441 CYG_ASSERT_DOCALL( "invariant (" #_bool_ ")" ); \
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()...
450 template<class X> class __CygInvariantObject {
455 // Prevent access to the default constructors.
456 __CygInvariantObject() { }
457 __CygInvariantObject( const __CygInvariantObject& arg ) { }
458 __CygInvariantObject & operator=( const __CygInvariantObject & arg) { return *this; }
461 __CygInvariantObject( X* arg, const char* msg ) : rep(arg) {
462 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
463 CYG_ASSERT_DOCALL( msg );
465 __CygInvariantObject( X& arg, const char* msg ) : rep(&arg) {
466 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
467 CYG_ASSERT_DOCALL( msg );
469 __CygInvariantObject( const X* arg, const char* msg ) : rep(arg) {
470 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
471 CYG_ASSERT_DOCALL( msg );
473 __CygInvariantObject( const X& arg, const char* msg ) : rep(&arg) {
474 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
475 CYG_ASSERT_DOCALL( msg );
477 ~__CygInvariantObject( ) {
478 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
479 CYG_ASSERT_DOCALL( "invariant, object valid on exit" );
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__.
489 # define __CYG_INVARIANT_CLASSNAME_AUX( a, b) a ## b
490 # define __CYG_INVARIANT_CLASSNAME( a, b ) \
491 __CYG_INVARIANT_CLASSNAME_AUX( a, b )
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.
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
502 # define CYG_INVARIANT_CLASS( _type_, _pobj_, _msg_ ) \
503 __CygInvariantObject<_type_> \
504 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
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" )
512 # define CYG_INVARIANT_CLASSO( _type_, _obj_, _msg_ ) \
513 __CygInvariantObject<_type_> \
514 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
517 # define CYG_INVARIANT_CLASSOC( _type_, _obj_ ) \
518 __CygInvariantObject<_type_> \
519 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
520 ( _obj_, "invariant, object (" #_obj_ ") is valid" )
522 # define CYG_INVARIANT_THIS( _type_, _msg_ ) \
523 __CygInvariantObject<_type_> \
524 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
527 # define CYG_INVARIANT_THISC( _type_ ) \
528 __CygInvariantObject<_type_> \
529 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
530 ( this, "invariant, \"this\" is valid" )
532 # endif // __cplusplus
534 #else // !CYGDBG_INFRA_DEBUG_INVARIANTS
536 # define CYG_INVARIANT( _bool_, _msg_ ) CYG_EMPTY_STATEMENT
537 # define CYG_INVARIANTC( _bool_ ) CYG_EMPTY_STATEMENT
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_ )
550 #endif // CYGDBG_INFRA_DEBUG_INVARIANTS
552 // -------------------------------------------------------------------------
553 // Compile time failure; like #error but in a macro so we can use it in
554 // other definitions.
557 // #define new CYG_COMPILETIMEFAIL( "Do NOT use new!")
559 #define CYG_COMPILETIMEFAIL( _msg_ ) !!!-- _msg_ --!!!
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.
570 // These declarations are only available if the symbol
571 // CYG_DECLARE_HOST_ASSERTION_SUPPORT is defined.
572 #ifdef CYG_DECLARE_HOST_ASSERTION_SUPPORT
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 */) );
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.
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*) ));
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
602 externC void cyg_assert_failure_invoke_callbacks(
603 void (*)(const char* /* name */),
604 void (*)(const char* /* callback data */ ),
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
610 externC void cyg_assert_quickfail(void);
612 #endif // CYG_DECLARE_HOST_ASSERTION_SUPPORT
614 // -------------------------------------------------------------------------
616 #endif // CYGONCE_INFRA_CYG_ASS_H multiple inclusion protection