Debug

Includes:
"Common.h"

Introduction

This header contains defines, macros, and functions to aid in debugging the WAC project.



Macro Definitions

check

Check that an expression is true (non-zero).

check_ptr_overlap

Checks that two ptrs do not overlap.

require

Requires that an expression evaluate to true.

require_action

Requires that an expression evaluate to true with an action to execute otherwise.

require_action_quiet

Requires that an expression evaluate to true with an action to execute otherwise.

require_action_string

Requires that an expression evaluate to true with an explanation and action to execute otherwise.

require_noerr

Require that an error code is noErr (0).

require_noerr_action

Require that an error code is noErr (0) with an action to execute otherwise.

require_noerr_action_quiet

Require that an error code is noErr (0) with an action to execute otherwise.

require_noerr_action_string

Require that an error code is noErr (0).

require_noerr_quiet

Require that an error code is noErr (0).

require_noerr_string

Require that an error code is noErr (0).

require_quiet

Requires that an expression evaluate to true.

require_string

Requires that an expression evaluate to true with an explanation.


check


Check that an expression is true (non-zero).

#if( !defined( check ) ) 
#if( DEBUG ) 
#define check( X ) \ 
    do \ 
    { \ 
    if( unlikely( !(X) ) ) \ 
    { \ 
    debug_print_assert( 0, #X, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    } \ 
    \ 
    } while( 0 ) 
#else 
#define check( X ) 
#endif  
#endif  
Discussion

If expression evalulates to false, this prints debugging information (actual expression string, file, line number, function name, etc.) using the default debugging output method.

Code inside check() statements is not compiled into production builds.


check_ptr_overlap


Checks that two ptrs do not overlap.

#define check_ptr_overlap( P1, P1_SIZE, P2, P2_SIZE ) \ 
    do \ 
    { \ 
    check( !( ( (uintptr_t)(P1) >= (uintptr_t)(P2) ) && \ 
    ( (uintptr_t)(P1) < ( ( (uintptr_t)(P2) ) + (P2_SIZE) ) ) ) ); \ 
    check( !( ( (uintptr_t)(P2) >= (uintptr_t)(P1) ) && \ 
    ( (uintptr_t)(P2) < ( ( (uintptr_t)(P1) ) + (P1_SIZE) ) ) ) ); \ 
    \ 
    } while( 0 ) 

require


Requires that an expression evaluate to true.

#if( !defined( require ) ) 
#define require( X, LABEL ) \ 
    do \ 
    { \ 
    if( unlikely( !(X) ) ) \ 
    { \ 
    debug_print_assert( 0, #X, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If expression evalulates to false, this prints debugging information (actual expression string, file, line number, function name, etc.) using the default debugging output method then jumps to a label.


require_action


Requires that an expression evaluate to true with an action to execute otherwise.

#if( !defined( require_action ) ) 
#define require_action( X, LABEL, ACTION ) \ 
    do \ 
    { \ 
    if( unlikely( !(X) ) ) \ 
    { \ 
    debug_print_assert( 0, #X, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    { ACTION; } \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If expression evalulates to false, this prints debugging information (actual expression string, file, line number, function name, etc.) using the default debugging output method then executes an action and jumps to a label.


require_action_quiet


Requires that an expression evaluate to true with an action to execute otherwise.

#if( !defined( require_action_quiet ) ) 
#define require_action_quiet( X, LABEL, ACTION ) \ 
    do \ 
    { \ 
    if( unlikely( !(X) ) ) \ 
    { \ 
    { ACTION; } \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If expression evalulates to false, this executes an action and jumps to a label. No debugging information is printed.


require_action_string


Requires that an expression evaluate to true with an explanation and action to execute otherwise.

#if( !defined( require_action_string ) ) 
#define require_action_string( X, LABEL, ACTION, STR ) \ 
    do \ 
    { \ 
    if( unlikely( !(X) ) ) \ 
    { \ 
    debug_print_assert( 0, #X, STR, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    { ACTION; } \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If expression evalulates to false, this prints debugging information (actual expression string, file, line number, function name, etc.) and a custom explanation string using the default debugging output method then executes an action and jumps to a label.


require_noerr


Require that an error code is noErr (0).

#if( !defined( require_noerr ) ) 
#define require_noerr( ERR, LABEL ) \ 
    do \ 
    { \ 
    OSStatus localErr; \ 
    \ 
    localErr = (OSStatus)(ERR); \ 
    if( unlikely( localErr != 0 ) ) \ 
    { \ 
    debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If the error code is non-0, this prints debugging information (actual expression string, file, line number, function name, etc.) using the default debugging output method then jumps to a label.


require_noerr_action


Require that an error code is noErr (0) with an action to execute otherwise.

#if( !defined( require_noerr_action ) ) 
#define require_noerr_action( ERR, LABEL, ACTION ) \ 
    do \ 
    { \ 
    OSStatus localErr; \ 
    \ 
    localErr = (OSStatus)(ERR); \ 
    if( unlikely( localErr != 0 ) ) \ 
    { \ 
    debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    { ACTION; } \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If the error code is non-0, this prints debugging information (actual expression string, file, line number, function name, etc.) using the default debugging output method then executes an action and jumps to a label.


require_noerr_action_quiet


Require that an error code is noErr (0) with an action to execute otherwise.

#if( !defined( require_noerr_action_quiet ) ) 
#define require_noerr_action_quiet( ERR, LABEL, ACTION ) \ 
    do \ 
    { \ 
    if( unlikely( (ERR) != 0 ) ) \ 
    { \ 
    { ACTION; } \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If the error code is non-0, this executes an action and jumps to a label. No debugging information is printed.


require_noerr_action_string


Require that an error code is noErr (0).

#if( !defined( require_noerr_action_string ) ) 
#define require_noerr_action_string( ERR, LABEL, ACTION, STR ) \ 
    do \ 
    { \ 
    OSStatus localErr; \ 
    \ 
    localErr = (OSStatus)(ERR); \ 
    if( unlikely( localErr != 0 ) ) \ 
    { \ 
    debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    { ACTION; } \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If the error code is non-0, this prints debugging information (actual expression string, file, line number, function name, etc.), and a custom explanation string using the default debugging output method using the default debugging output method then executes an action and jumps to a label.


require_noerr_quiet


Require that an error code is noErr (0).

#if( !defined( require_noerr_quiet ) ) 
#define require_noerr_quiet( ERR, LABEL ) \ 
    do \ 
    { \ 
    if( unlikely( (ERR) != 0 ) ) \ 
    { \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If the error code is non-0, this jumps to a label. No debugging information is printed.


require_noerr_string


Require that an error code is noErr (0).

#if( !defined( require_noerr_string ) ) 
#define require_noerr_string( ERR, LABEL, STR ) \ 
    do \ 
    { \ 
    OSStatus localErr; \ 
    \ 
    localErr = (OSStatus)(ERR); \ 
    if( unlikely( localErr != 0 ) ) \ 
    { \ 
    debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If the error code is non-0, this prints debugging information (actual expression string, file, line number, function name, etc.), and a custom explanation string using the default debugging output method using the default debugging output method then jumps to a label.


require_quiet


Requires that an expression evaluate to true.

#if( !defined( require_quiet ) ) 
#define require_quiet( X, LABEL ) \ 
    do \ 
    { \ 
    if( unlikely( !(X) ) ) \ 
    { \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If expression evalulates to false, this jumps to a label. No debugging information is printed.


require_string


Requires that an expression evaluate to true with an explanation.

#if( !defined( require_string ) ) 
#define require_string( X, LABEL, STR ) \ 
    do \ 
    { \ 
    if( unlikely( !(X) ) ) \ 
    { \ 
    debug_print_assert( 0, #X, STR, __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ 
    goto LABEL; \ 
    } \ 
    \ 
    } while( 0 ) 
#endif  
Discussion

If expression evalulates to false, this prints debugging information (actual expression string, file, line number, function name, etc.) and a custom explanation string using the default debugging output method then jumps to a label.