📄 cyg_ass.h
字号:
#ifndef CYGONCE_INFRA_CYG_ASS_H
#define CYGONCE_INFRA_CYG_ASS_H
//==========================================================================
//
// assert.h
//
// Macros and prototypes for the assert system
//
//==========================================================================
//####COPYRIGHTBEGIN####
//
// -------------------------------------------
// The contents of this file are subject to the Red Hat eCos Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.redhat.com/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations under
// the License.
//
// The Original Code is eCos - Embedded Configurable Operating System,
// released September 30, 1998.
//
// The Initial Developer of the Original Code is Red Hat.
// Portions created by Red Hat are
// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
// All Rights Reserved.
// -------------------------------------------
//
//####COPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg from an original by hmt
// Contributors: nickg
// Date: 1997-09-08
// Purpose: Use asserts to avoid writing duff code.
// Description: Runtime tests that compile to nothing in
// release versions of the code, to allow
// as-you-go testing of alternate builds.
// Usage: #include <cyg/infra/cyg_ass.h>
// ...
// CYG_ASSERT( pcount > 0, "Number of probes should be > 0!" );
//
// which can result, for example, in a message of the form:
// ASSERT FAILED: probemgr.cxx:1340, scan_probes() :
// number of probes should be > 0!
// if the boolean "pcount > 0" is false.
//
//####DESCRIPTIONEND####
//
//==========================================================================
#include <pkgconf/infra.h>
#include <cyg/infra/cyg_type.h> // for CYGBLD_ATTRIB_NORET
// -------------------------------------------------------------------------
// If we do not have a function name macro, define it ourselves
#ifndef CYGDBG_INFRA_DEBUG_FUNCTION_PSEUDOMACRO
// __PRETTY_FUNCTION__ does not work
# ifndef __PRETTY_FUNCTION__ // And it is not already defined
# define __PRETTY_FUNCTION__ NULL
# endif
#endif
// -------------------------------------------------------------------------
// This is executed to deal with failure - breakpoint it first!
// It is declared as a weak symbol to allow user code to override the
// definition.
externC void
cyg_assert_fail( const char* /* psz_func */, const char* /* psz_file */,
cyg_uint32 /* linenum */, const char* /* psz_msg */ )
CYGBLD_ATTRIB_NORET CYGBLD_ATTRIB_WEAK;
// -------------------------------------------------------------------------
#ifdef CYGDBG_USE_ASSERTS
// -------------------------------------------------------------------------
// We define macros and appropriate prototypes for the assert/fail
// system. These are:
// CYG_FAIL - unconditional panic
// CYG_ASSERT - panic if boolean expression is false
// CYG_ASSERTC - compact version of CYG_ASSERT
# ifdef CYGDBG_INFRA_DEBUG_ASSERT_MESSAGE
# define CYG_ASSERT_DOCALL( _msg_ ) \
CYG_MACRO_START \
cyg_assert_fail( __PRETTY_FUNCTION__, __FILE__, __LINE__, _msg_ );\
CYG_MACRO_END
# else
# define CYG_ASSERT_DOCALL( _msg_ ) \
CYG_MACRO_START \
const char* _tmp1_ = _msg_; \
_tmp1_ = _tmp1_; \
cyg_assert_fail( __PRETTY_FUNCTION__, __FILE__, __LINE__, NULL ); \
CYG_MACRO_END
# endif
// unconditional failure; use like panic(), coredump() &c.
# define CYG_FAIL( _msg_ ) \
CYG_MACRO_START \
CYG_ASSERT_DOCALL( _msg_ ); \
CYG_MACRO_END
// conditioned assert; if the condition is false, fail.
# define CYG_ASSERT( _bool_, _msg_ ) \
CYG_MACRO_START \
if ( ! ( _bool_ ) ) \
CYG_ASSERT_DOCALL( _msg_ ); \
CYG_MACRO_END
# define CYG_ASSERTC( _bool_ ) \
CYG_MACRO_START \
if ( ! ( _bool_ ) ) \
CYG_ASSERT_DOCALL( #_bool_ );\
CYG_MACRO_END
#else // ! CYGDBG_USE_ASSERTS
// -------------------------------------------------------------------------
// No asserts: we define empty statements for assert & fail.
# define CYG_FAIL( _msg_ ) CYG_EMPTY_STATEMENT
# define CYG_ASSERT( _bool_, _msg_ ) CYG_EMPTY_STATEMENT
# define CYG_ASSERTC( _bool_ ) CYG_EMPTY_STATEMENT
#endif // ! CYGDBG_USE_ASSERTS
// -------------------------------------------------------------------------
// Pointer integrity checks.
// These check not only for NULL pointer, but can also check for pointers
// that are outside to defined memory areas of the platform or executable.
// We differentiate between data and function pointers, so that we can cope
// with different formats, and so we can check them against different memory
// regions.
externC cyg_bool cyg_check_data_ptr(void *ptr);
externC cyg_bool cyg_check_func_ptr(void (*ptr)(void));
#ifdef CYGDBG_USE_ASSERTS
# define CYG_CHECK_DATA_PTR( _ptr_, _msg_ ) \
CYG_MACRO_START \
if( !cyg_check_data_ptr((void *)(_ptr_))) \
CYG_ASSERT_DOCALL( _msg_ ); \
CYG_MACRO_END
# define CYG_CHECK_FUNC_PTR( _ptr_, _msg_ ) \
CYG_MACRO_START \
if( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
CYG_ASSERT_DOCALL( _msg_ ); \
CYG_MACRO_END
# define CYG_CHECK_DATA_PTRC( _ptr_ ) \
CYG_MACRO_START \
if ( !cyg_check_data_ptr((void *)(_ptr_))) \
CYG_ASSERT_DOCALL("data pointer (" #_ptr_ ") is valid");\
CYG_MACRO_END
# define CYG_CHECK_FUNC_PTRC( _ptr_ ) \
CYG_MACRO_START \
if ( !cyg_check_func_ptr((void (*)(void))(_ptr_))) \
CYG_ASSERT_DOCALL("function pointer (" #_ptr_ ") is valid"); \
CYG_MACRO_END
#else // CYGDBG_USE_ASSERTS
# define CYG_CHECK_DATA_PTR( _ptr_, _msg_ ) CYG_EMPTY_STATEMENT
# define CYG_CHECK_FUNC_PTR( _ptr_, _msg_ ) CYG_EMPTY_STATEMENT
# define CYG_CHECK_DATA_PTRC( _ptr_ ) CYG_EMPTY_STATEMENT
# define CYG_CHECK_FUNC_PTRC( _ptr_ ) CYG_EMPTY_STATEMENT
#endif // CYGDBG_USE_ASSERTS
// -------------------------------------------------------------------------
// Unconditional definitions:
// Check an object for validity by calling its own checker.
// Usage:
// ClassThing *p = &classobject;
// CYG_ASSERTCLASS( p, "Object at p is broken!" );
// this enum gives some options as to how keenly to test; avoids cluttering
// the member function declaration if the implementor wants to do more
// zealous tests themselves.
enum cyg_assert_class_zeal {
cyg_system_test = -1,
cyg_none = 0,
cyg_trivial,
cyg_quick,
cyg_thorough,
cyg_extreme
};
// -------------------------------------------------------------------------
// Define macros for checking classes:
//
// CYG_ASSERT_CLASS - do proforma check on a class pointer
// CYG_ASSERT_CLASSO - do proforma check on a class object
// CYG_ASSERT_ZERO_OR_CLASS- a class pointer is NULL or valid
// CYG_ASSERT_THIS - "this" is valid
// + 3 compact variants and two aliases for backwards compatibility.
//
// All of these end up going via CYG_ASSERT(), which will be an empty
// statement if CYGDBG_USE_ASSERTS is disabled. There is no need to
// test CYGDBG_USE_ASSERTS again here.
//
// The idiom required is that a class have a member function called
// "bool check_this( cyg_assert_class_zeal ) const" that returns true
// iff the object is OK. This need not be conditionally compiled against
// CYGDBG_USE_ASSERTS but it can be if only this macro is used to
// invoke it. Alternatively it can be invoked by hand with other
// choices from the above enum.
// Assert the checker function of an object by pointer, or in hand.
#ifdef __cplusplus
# ifndef CYG_ASSERT_CLASS_ZEAL
# define CYG_ASSERT_CLASS_ZEAL (cyg_quick) // can be redefined locally
# endif
# define CYG_ASSERT_CLASS( _pobj_, _msg_ ) \
CYG_ASSERT( ((0 != (_pobj_)) && \
(_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
# define CYG_ASSERTCLASS( _pobj_,_msg_) \
CYG_ASSERT_CLASS( (_pobj_), _msg_ )
# define CYG_ASSERT_CLASSO( _obj_, _msg_ ) \
CYG_ASSERT( (_obj_).check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
# define CYG_ASSERTCLASSO( _obj_, _msg_ ) \
CYG_ASSERT_CLASSO( (_obj_), _msg_ )
# define CYG_ASSERT_ZERO_OR_CLASS( _pobj_, _msg_ ) \
CYG_ASSERT( ((0 == (_pobj_)) || \
(_pobj_)->check_this( CYG_ASSERT_CLASS_ZEAL )), _msg_ )
# define CYG_ASSERT_THIS( _msg_ ) \
CYG_ASSERT( this->check_this( CYG_ASSERT_CLASS_ZEAL ), _msg_ )
# define CYG_ASSERT_CLASSC( _pobj_ ) \
CYG_ASSERT_CLASS( (_pobj_), "class pointer (" #_pobj_ ") is valid" )
# define CYG_ASSERT_CLASSOC( _obj_ ) \
CYG_ASSERT_CLASSO( (_obj_), "object (" #_obj_ ") is valid" )
# define CYG_ASSERT_ZERO_OR_CLASSC( _pobj_ ) \
CYG_ASSERT_ZERO_OR_CLASS((_pobj_), \
"class pointer (" #_pobj_ ") is zero or valid")
# define CYG_ASSERT_THISC( ) \
CYG_ASSERT_THIS( "\"this\" pointer is valid" )
#define CYGDBG_DEFINE_CHECK_THIS \
cyg_bool check_this( cyg_assert_class_zeal zeal ) const;
#endif // __cplusplus
// -------------------------------------------------------------------------
// Some alternative names for basic assertions that we can disable
// individually.
//
// CYG_PRECONDITION - argument checking etc
// CYG_POSTCONDITION - results etc
// CYG_LOOP_INVARIANT - for putting in loops
//
// C++ programmers have class-related variants of all of these.
#ifdef CYGDBG_INFRA_DEBUG_PRECONDITIONS
# define CYG_PRECONDITION( _bool_ , _msg_ ) CYG_ASSERT( _bool_, _msg_ )
# define CYG_PRECONDITIONC( _bool_ ) \
CYG_ASSERT( _bool_, "precondition " #_bool_)
#else
# define CYG_PRECONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
# define CYG_PRECONDITIONC( _bool_ ) CYG_EMPTY_STATEMENT
#endif
#ifdef CYGDBG_INFRA_DEBUG_POSTCONDITIONS
# define CYG_POSTCONDITION( _bool_ , _msg_ ) CYG_ASSERT( _bool_, _msg_ )
# define CYG_POSTCONDITIONC( _bool_ ) \
CYG_ASSERT( _bool_, "postcondition " #_bool_)
#else
# define CYG_POSTCONDITION( _bool_ , _msg_ ) CYG_EMPTY_STATEMENT
# define CYG_POSTCONDITIONC( _bool_ ) CYG_EMPTY_STATEMENT
#endif
#ifdef CYGDBG_INFRA_DEBUG_LOOP_INVARIANTS
# define CYG_LOOP_INVARIANT( _bool_ , _msg_ ) CYG_ASSERT( _bool_, _msg_ )
# define CYG_LOOP_INVARIANTC( _bool_ ) \
CYG_ASSERT( _bool_, "loop invariant " #_bool_ )
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -