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 //####COPYRIGHTBEGIN####
13 // ----------------------------------------------------------------------------
14 // Copyright (C) 1997, 1998, 1999, 2000 Red Hat, Inc.
16 // This file is part of the eCos host tools.
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)
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
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.
32 // ----------------------------------------------------------------------------
34 //####COPYRIGHTEND####
35 //==========================================================================
36 //#####DESCRIPTIONBEGIN####
38 // Author(s): nickg from an original by hmt
39 // Contributors: nickg
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>
47 // CYG_ASSERT( pcount > 0, "Number of probes should be > 0!" );
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.
54 //####DESCRIPTIONEND####
56 //==========================================================================
58 #include <pkgconf/infra.h>
60 #include <cyg/infra/cyg_type.h> // for CYGBLD_ATTRIB_NORET
62 // -------------------------------------------------------------------------
63 // If we do not have a function name macro, define it ourselves
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
72 // -------------------------------------------------------------------------
73 // this is executed to deal with failure - breakpoint it first!
76 cyg_assert_fail( const char* /* psz_func */, const char* /* psz_file */,
77 cyg_uint32 /* linenum */, const char* /* psz_msg */ )
80 // -------------------------------------------------------------------------
82 #ifdef CYGDBG_USE_ASSERTS
84 // -------------------------------------------------------------------------
85 // We define macros and appropriate prototypes for the assert/fail
87 // CYG_FAIL - unconditional panic
88 // CYG_ASSERT - panic if boolean expression is false
89 // CYG_ASSERTC - compact version of CYG_ASSERT
91 # ifdef CYGDBG_INFRA_DEBUG_ASSERT_MESSAGE
92 # define CYG_ASSERT_DOCALL( _msg_ ) \
93 cyg_assert_fail( __PRETTY_FUNCTION__, __FILE__, __LINE__, _msg_ );
95 # define CYG_ASSERT_DOCALL( _msg_ ) \
97 const char* _tmp1_ = _msg_; \
99 cyg_assert_fail( __PRETTY_FUNCTION__, __FILE__, __LINE__, NULL ); \
103 // unconditional failure; use like panic(), coredump() &c.
104 # define CYG_FAIL( _msg_ ) \
106 CYG_ASSERT_DOCALL( _msg_ ); \
109 // conditioned assert; if the condition is false, fail.
110 # define CYG_ASSERT( _bool_, _msg_ ) \
112 if ( ! ( _bool_ ) ) \
113 CYG_ASSERT_DOCALL( _msg_ ); \
116 # define CYG_ASSERTC( _bool_ ) \
118 if ( ! ( _bool_ ) ) \
119 CYG_ASSERT_DOCALL( #_bool_ );\
122 #else // ! CYGDBG_USE_ASSERTS
124 // -------------------------------------------------------------------------
125 // No asserts: we define empty statements for assert & fail.
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
131 #endif // ! CYGDBG_USE_ASSERTS
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
141 externC cyg_bool cyg_check_data_ptr(void *ptr);
142 externC cyg_bool cyg_check_func_ptr(void (*ptr)(void));
144 #ifdef CYGDBG_USE_ASSERTS
146 # define CYG_CHECK_DATA_PTR( _ptr_, _msg_ ) \
148 if( !cyg_check_data_ptr((void *)(_ptr_))) \
149 CYG_ASSERT_DOCALL( _msg_ ); \
152 # define CYG_CHECK_FUNC_PTR( _ptr_, _msg_ ) \
154 if( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
155 CYG_ASSERT_DOCALL( _msg_ ); \
158 # define CYG_CHECK_DATA_PTRC( _ptr_ ) \
160 if ( !cyg_check_data_ptr((void *)(_ptr_))) \
161 CYG_ASSERT_DOCALL("data pointer (" #_ptr_ ") is valid");\
164 # define CYG_CHECK_FUNC_PTRC( _ptr_ ) \
166 if ( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
167 CYG_ASSERT_DOCALL("function pointer (" #_ptr_ ") is valid"); \
170 #else // CYGDBG_USE_ASSERTS
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
177 #endif // CYGDBG_USE_ASSERTS
179 // -------------------------------------------------------------------------
180 // Unconditional definitions:
182 // Check an object for validity by calling its own checker.
184 // ClassThing *p = &classobject;
185 // CYG_ASSERTCLASS( p, "Object at p is broken!" );
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.
191 enum cyg_assert_class_zeal {
192 cyg_system_test = -1,
200 // -------------------------------------------------------------------------
201 // Define macros for checking classes:
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.
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.
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.
220 // Assert the checker function of an object by pointer, or in hand.
224 # ifndef CYG_ASSERT_CLASS_ZEAL
225 # define CYG_ASSERT_CLASS_ZEAL (cyg_quick) // can be redefined locally
228 # define CYG_ASSERT_CLASS( _pobj_, _msg_ ) \
229 CYG_ASSERT( ((0 != (_pobj_)) && \
230 (_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
232 # define CYG_ASSERTCLASS( _pobj_,_msg_) \
233 CYG_ASSERT_CLASS( (_pobj_), _msg_ )
235 # define CYG_ASSERT_CLASSO( _obj_, _msg_ ) \
236 CYG_ASSERT( (_obj_).check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
238 # define CYG_ASSERTCLASSO( _obj_, _msg_ ) \
239 CYG_ASSERT_CLASSO( (_obj_), _msg_ )
241 # define CYG_ASSERT_ZERO_OR_CLASS( _pobj_, _msg_ ) \
242 CYG_ASSERT( ((0 == (_pobj_)) || \
243 (_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
245 # define CYG_ASSERT_THIS( _msg_ ) \
246 CYG_ASSERT( this->check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
248 # define CYG_ASSERT_CLASSC( _pobj_ ) \
249 CYG_ASSERT_CLASS( (_pobj_), "class pointer (" #_pobj_ ") is valid" )
251 # define CYG_ASSERT_CLASSOC( _obj_ ) \
252 CYG_ASSERT_CLASSO( (_obj_), "object (" #_obj_ ") is valid" )
254 # define CYG_ASSERT_ZERO_OR_CLASSC( _pobj_ ) \
255 CYG_ASSERT_ZERO_OR_CLASS((_pobj_), \
256 "class pointer (" #_pobj_ ") is zero or valid")
258 # define CYG_ASSERT_THISC( ) \
259 CYG_ASSERT_THIS( "\"this\" pointer is valid" )
261 #define CYGDBG_DEFINE_CHECK_THIS \
262 bool check_this( cyg_assert_class_zeal zeal ) const;
264 #endif // __cplusplus
266 // -------------------------------------------------------------------------
267 // Some alternative names for basic assertions that we can disable
270 // CYG_PRECONDITION - argument checking etc
271 // CYG_POSTCONDITION - results etc
272 // CYG_LOOP_INVARIANT - for putting in loops
274 // C++ programmers have class-related variants of all of these.
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_)
281 # define CYG_PRECONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
282 # define CYG_PRECONDITIONC( _bool_ ) CYG_EMPTY_STATEMENT
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_)
290 # define CYG_POSTCONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
291 # define CYG_POSTCONDITIONC( _bool_ ) CYG_EMPTY_STATEMENT
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_ )
299 # define CYG_LOOP_INVARIANT( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
300 # define CYG_LOOP_INVARIANTC( _bool_ ) CYG_EMPTY_STATEMENT
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_)
310 # define CYG_PRECONDITION_CLASSC( _pobj_ ) \
311 CYG_PRECONDITION_CLASS( (_pobj_), \
312 "precondition, class pointer (" #_pobj_ ") is valid" )
314 # define CYG_POSTCONDITION_CLASS( _pobj_, _msg_ ) \
315 CYG_POSTCONDITION( ((0 != (_pobj_)) && \
316 (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
318 # define CYG_POSTCONDITION_CLASSC( _pobj_ ) \
319 CYG_POSTCONDITION_CLASS( (_pobj_), \
320 "postcondition, class pointer (" #_pobj_ ") is valid" )
322 # define CYG_LOOP_INVARIANT_CLASS( _pobj_, _msg_) \
323 CYG_LOOP_INVARIANT( ((0 != (_pobj_)) && \
324 (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
326 # define CYG_LOOP_INVARIANT_CLASSC( _pobj_ ) \
327 CYG_LOOP_INVARIANT_CLASS( (_pobj_), \
328 "loop invariant, class pointer (" #_pobj_ ") is valid" )
330 // All variants of _CLASSO
331 # define CYG_PRECONDITION_CLASSO( _obj_, _msg_ ) \
332 CYG_PRECONDITION( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
334 # define CYG_PRECONDITION_CLASSOC( _obj_ ) \
335 CYG_PRECONDITION_CLASSO( (_obj_), \
336 "precondition, object (" #_obj_ ") is valid" )
338 # define CYG_POSTCONDITION_CLASSO( _obj_, _msg_ ) \
339 CYG_POSTCONDITION( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
341 # define CYG_POSTCONDITION_CLASSOC( _obj_ ) \
342 CYG_POSTCONDITION_CLASSO( (_obj_), \
343 "postcondition, object (" #_obj_ ") is valid" )
345 # define CYG_LOOP_INVARIANT_CLASSO( _obj_, _msg_) \
346 CYG_LOOP_INVARIANT( (_obj_).check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
348 # define CYG_LOOP_INVARIANT_CLASSOC( _obj_ ) \
349 CYG_LOOP_INVARIANT_CLASSO( (_obj_), \
350 "loop invariant, object (" #_obj_ ") is valid" )
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_)
357 # define CYG_PRECONDITION_ZERO_OR_CLASSC( _pobj_ ) \
358 CYG_PRECONDITION_ZERO_OR_CLASS( (_pobj_), \
359 "precondition, class pointer (" #_pobj_ ") is zero or valid" )
361 # define CYG_POSTCONDITION_ZERO_OR_CLASS( _pobj_, _msg_ ) \
362 CYG_POSTCONDITION( ((0 == (_pobj_)) || \
363 (_pobj_)->check_this(CYG_ASSERT_CLASS_ZEAL)), _msg_)
365 # define CYG_POSTCONDITION_ZERO_OR_CLASSC( _pobj_ ) \
366 CYG_POSTCONDITION_ZERO_OR_CLASS( (_pobj_), \
367 "postcondition, class pointer (" #_pobj_ ") is zero or valid" )
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_)
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" )
377 // All variants of _THIS
378 # define CYG_PRECONDITION_THIS( _msg_ ) \
379 CYG_PRECONDITION( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
381 # define CYG_PRECONDITION_THISC() \
382 CYG_PRECONDITION_THIS( "precondition, \"this\" is valid" )
384 # define CYG_POSTCONDITION_THIS( _msg_ ) \
385 CYG_POSTCONDITION( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
387 # define CYG_POSTCONDITION_THISC() \
388 CYG_POSTCONDITION_THIS( "postcondition, \"this\" is valid" )
390 # define CYG_LOOP_INVARIANT_THIS( _msg_) \
391 CYG_LOOP_INVARIANT( this->check_this(CYG_ASSERT_CLASS_ZEAL), _msg_)
393 # define CYG_LOOP_INVARIANT_THISC() \
394 CYG_LOOP_INVARIANT_THIS( "loop invariant, \"this\" is valid" )
396 #endif // __cplusplus
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.
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.
412 #ifdef CYGDBG_INFRA_DEBUG_INVARIANTS
414 # define CYG_INVARIANT( _bool_, _msg_ ) \
416 if ( ! ( _bool_ ) ) \
417 CYG_ASSERT_DOCALL( _msg_ ); \
420 # define CYG_INVARIANTC( _bool_ ) \
422 if ( ! ( _bool_ ) ) \
423 CYG_ASSERT_DOCALL( "invariant (" #_bool_ ")" ); \
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()...
432 template<class X> class __CygInvariantObject {
437 // Prevent access to the default constructors.
438 __CygInvariantObject() { }
439 __CygInvariantObject( const __CygInvariantObject& arg ) { }
440 __CygInvariantObject & operator=( const __CygInvariantObject & arg) { return *this; }
443 __CygInvariantObject( X* arg, const char* msg ) : rep(arg) {
444 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
445 CYG_ASSERT_DOCALL( msg );
447 __CygInvariantObject( X& arg, const char* msg ) : rep(&arg) {
448 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
449 CYG_ASSERT_DOCALL( msg );
451 __CygInvariantObject( const X* arg, const char* msg ) : rep(arg) {
452 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
453 CYG_ASSERT_DOCALL( msg );
455 __CygInvariantObject( const X& arg, const char* msg ) : rep(&arg) {
456 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
457 CYG_ASSERT_DOCALL( msg );
459 ~__CygInvariantObject( ) {
460 if ( !rep->check_this( CYG_ASSERT_CLASS_ZEAL ) )
461 CYG_ASSERT_DOCALL( "invariant, object valid on exit" );
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__.
471 # define __CYG_INVARIANT_CLASSNAME_AUX( a, b) a ## b
472 # define __CYG_INVARIANT_CLASSNAME( a, b ) \
473 __CYG_INVARIANT_CLASSNAME_AUX( a, b )
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.
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
484 # define CYG_INVARIANT_CLASS( _type_, _pobj_, _msg_ ) \
485 __CygInvariantObject<_type_> \
486 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
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" )
494 # define CYG_INVARIANT_CLASSO( _type_, _obj_, _msg_ ) \
495 __CygInvariantObject<_type_> \
496 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
499 # define CYG_INVARIANT_CLASSOC( _type_, _obj_ ) \
500 __CygInvariantObject<_type_> \
501 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
502 ( _obj_, "invariant, object (" #_obj_ ") is valid" )
504 # define CYG_INVARIANT_THIS( _type_, _msg_ ) \
505 __CygInvariantObject<_type_> \
506 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
509 # define CYG_INVARIANT_THISC( _type_ ) \
510 __CygInvariantObject<_type_> \
511 __CYG_INVARIANT_CLASSNAME( __invariant_class_, __LINE__ ) \
512 ( this, "invariant, \"this\" is valid" )
514 # endif // __cplusplus
516 #else // !CYGDBG_INFRA_DEBUG_INVARIANTS
518 # define CYG_INVARIANT( _bool_, _msg_ ) CYG_EMPTY_STATEMENT
519 # define CYG_INVARIANTC( _bool_ ) CYG_EMPTY_STATEMENT
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_ )
532 #endif // CYGDBG_INFRA_DEBUG_INVARIANTS
534 // -------------------------------------------------------------------------
535 // Compile time failure; like #error but in a macro so we can use it in
536 // other definitions.
539 // #define new CYG_COMPILETIMEFAIL( "Do NOT use new!")
541 #define CYG_COMPILETIMEFAIL( _msg_ ) !!!-- _msg_ --!!!
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.
552 // These declarations are only available if the symbol
553 // CYG_DECLARE_HOST_ASSERTION_SUPPORT is defined.
554 #ifdef CYG_DECLARE_HOST_ASSERTION_SUPPORT
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 */) );
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.
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*) ));
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
584 externC void cyg_assert_failure_invoke_callbacks(
585 void (*)(const char* /* name */),
586 void (*)(const char* /* callback data */ ),
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
592 externC void cyg_assert_quickfail(void);
594 #endif // CYG_DECLARE_HOST_ASSERTION_SUPPORT
596 // -------------------------------------------------------------------------
598 #endif // CYGONCE_INFRA_CYG_ASS_H multiple inclusion protection