2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* error_macros.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2020-01-01 11:16:22 +01:00
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# ifndef ERROR_MACROS_H
# define ERROR_MACROS_H
2018-09-11 18:13:45 +02:00
# include "core/typedefs.h"
2014-02-10 02:10:30 +01:00
2019-11-06 08:38:23 +01:00
class String ;
2014-02-10 02:10:30 +01:00
enum ErrorHandlerType {
ERR_HANDLER_ERROR ,
ERR_HANDLER_WARNING ,
2016-10-10 23:31:01 +02:00
ERR_HANDLER_SCRIPT ,
ERR_HANDLER_SHADER ,
2014-02-10 02:10:30 +01:00
} ;
2019-11-06 08:38:23 +01:00
// Pointer to the error handler printing function. Reassign to any function to have errors printed.
// Parameters: userdata, function, file, line, error, explanation, type.
2017-03-05 16:44:50 +01:00
typedef void ( * ErrorHandlerFunc ) ( void * , const char * , const char * , int p_line , const char * , const char * , ErrorHandlerType p_type ) ;
2014-02-10 02:10:30 +01:00
struct ErrorHandlerList {
2020-05-12 17:01:17 +02:00
ErrorHandlerFunc errfunc = nullptr ;
void * userdata = nullptr ;
2014-02-10 02:10:30 +01:00
2020-05-12 17:01:17 +02:00
ErrorHandlerList * next = nullptr ;
2014-02-10 02:10:30 +01:00
2020-05-12 17:01:17 +02:00
ErrorHandlerList ( ) { }
2014-02-10 02:10:30 +01:00
} ;
void add_error_handler ( ErrorHandlerList * p_handler ) ;
void remove_error_handler ( ErrorHandlerList * p_handler ) ;
2019-11-06 08:38:23 +01:00
// Functions used by the error macros.
2017-03-05 16:44:50 +01:00
void _err_print_error ( const char * p_function , const char * p_file , int p_line , const char * p_error , ErrorHandlerType p_type = ERR_HANDLER_ERROR ) ;
2019-11-06 08:38:23 +01:00
void _err_print_error ( const char * p_function , const char * p_file , int p_line , const String & p_error , ErrorHandlerType p_type = ERR_HANDLER_ERROR ) ;
2019-11-10 07:44:31 +01:00
void _err_print_error ( const char * p_function , const char * p_file , int p_line , const char * p_error , const char * p_message , ErrorHandlerType p_type = ERR_HANDLER_ERROR ) ;
void _err_print_error ( const char * p_function , const char * p_file , int p_line , const String & p_error , const char * p_message , ErrorHandlerType p_type = ERR_HANDLER_ERROR ) ;
void _err_print_error ( const char * p_function , const char * p_file , int p_line , const char * p_error , const String & p_message , ErrorHandlerType p_type = ERR_HANDLER_ERROR ) ;
void _err_print_error ( const char * p_function , const char * p_file , int p_line , const String & p_error , const String & p_message , ErrorHandlerType p_type = ERR_HANDLER_ERROR ) ;
void _err_print_index_error ( const char * p_function , const char * p_file , int p_line , int64_t p_index , int64_t p_size , const char * p_index_str , const char * p_size_str , const char * p_message = " " , bool fatal = false ) ;
void _err_print_index_error ( const char * p_function , const char * p_file , int p_line , int64_t p_index , int64_t p_size , const char * p_index_str , const char * p_size_str , const String & p_message , bool fatal = false ) ;
2014-02-10 02:10:30 +01:00
# ifdef __GNUC__
//#define FUNCTION_STR __PRETTY_FUNCTION__ - too annoying
# define FUNCTION_STR __FUNCTION__
# else
# define FUNCTION_STR __FUNCTION__
# endif
2017-05-26 21:11:16 +02:00
# ifdef _MSC_VER
2020-02-05 14:39:12 +01:00
/**
* Don ' t use GENERATE_TRAP ( ) directly , should only be used be the macros below .
*/
2019-11-06 08:38:23 +01:00
# define GENERATE_TRAP() __debugbreak()
2017-05-26 21:11:16 +02:00
# else
2020-02-05 14:39:12 +01:00
/**
* Don ' t use GENERATE_TRAP ( ) directly , should only be used be the macros below .
*/
2019-11-06 08:38:23 +01:00
# define GENERATE_TRAP() __builtin_trap()
2017-05-26 21:11:16 +02:00
# endif
2019-11-13 14:07:54 +01:00
// Used to strip debug messages in release mode
# ifdef DEBUG_ENABLED
# define DEBUG_STR(m_msg) m_msg
# else
# define DEBUG_STR(m_msg) ""
# endif
2020-01-24 16:53:52 +01:00
/**
2019-11-06 08:38:23 +01:00
* Error macros .
* WARNING : These macros work in the opposite way to assert ( ) .
*
* Unlike exceptions and asserts , these macros try to maintain consistency and stability .
* In most cases , bugs and / or invalid data are not fatal . They should never allow a perfectly
* running application to fail or crash .
* Always try to return processable data , so the engine can keep running well .
* Use the _MSG versions to print a meaningful message to help with debugging .
2020-05-15 17:48:09 +02:00
*
* The ` ( ( void ) 0 ) ` no - op statement is used as a trick to force us to put a semicolon after
* those macros , making them look like proper statements .
* The if wrappers are used to ensure that the macro replacement does not trigger unexpected
* issues when expanded e . g . after an ` if ( cond ) ERR_FAIL ( ) ; ` without braces .
2020-01-24 16:53:52 +01:00
*/
2019-11-06 08:38:23 +01:00
// Index out of bounds error macros.
// These macros should be used instead of `ERR_FAIL_COND` for bounds checking.
// Integer index out of bounds error macros.
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_INDEX_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures an integer index ` m_index ` is less than ` m_size ` and greater than or equal to 0.
* If not , the current function returns .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_INDEX(m_index, m_size) \
if ( unlikely ( ( m_index ) < 0 | | ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) ) ; \
return ; \
} else \
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures an integer index ` m_index ` is less than ` m_size ` and greater than or equal to 0.
* If not , prints ` m_msg ` and the current function returns .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \
if ( unlikely ( ( m_index ) < 0 | | ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , DEBUG_STR ( m_msg ) ) ; \
return ; \
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_INDEX_V_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures an integer index ` m_index ` is less than ` m_size ` and greater than or equal to 0.
* If not , the current function returns ` m_retval ` .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \
if ( unlikely ( ( m_index ) < 0 | | ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) ) ; \
return m_retval ; \
} else \
( ( void ) 0 )
2017-05-26 21:11:16 +02:00
2020-02-05 14:39:12 +01:00
/**
* Ensures an integer index ` m_index ` is less than ` m_size ` and greater than or equal to 0.
* If not , prints ` m_msg ` and the current function returns ` m_retval ` .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
if ( unlikely ( ( m_index ) < 0 | | ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , DEBUG_STR ( m_msg ) ) ; \
return m_retval ; \
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_INDEX_MSG ` or ` ERR_FAIL_INDEX_V_MSG ` .
* Only use this macro if there is no sensible fallback i . e . the error is unrecoverable , and
* there is no sensible error message .
*
* Ensures an integer index ` m_index ` is less than ` m_size ` and greater than or equal to 0.
* If not , the application crashes .
*/
2020-02-08 08:35:52 +01:00
# define CRASH_BAD_INDEX(m_index, m_size) \
if ( unlikely ( ( m_index ) < 0 | | ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , " " , true ) ; \
GENERATE_TRAP ( ) ; \
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_INDEX_MSG ` or ` ERR_FAIL_INDEX_V_MSG ` .
* Only use this macro if there is no sensible fallback i . e . the error is unrecoverable .
*
* Ensures an integer index ` m_index ` is less than ` m_size ` and greater than or equal to 0.
* If not , prints ` m_msg ` and the application crashes .
*/
2020-02-08 08:35:52 +01:00
# define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
if ( unlikely ( ( m_index ) < 0 | | ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , DEBUG_STR ( m_msg ) , true ) ; \
GENERATE_TRAP ( ) ; \
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
// Unsigned integer index out of bounds error macros.
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_UNSIGNED_INDEX_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures an unsigned integer index ` m_index ` is less than ` m_size ` .
* If not , the current function returns .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_UNSIGNED_INDEX(m_index, m_size) \
if ( unlikely ( ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) ) ; \
return ; \
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures an unsigned integer index ` m_index ` is less than ` m_size ` .
* If not , prints ` m_msg ` and the current function returns .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
if ( unlikely ( ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , DEBUG_STR ( m_msg ) ) ; \
return ; \
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_UNSIGNED_INDEX_V_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures an unsigned integer index ` m_index ` is less than ` m_size ` .
* If not , the current function returns ` m_retval ` .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval) \
if ( unlikely ( ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) ) ; \
return m_retval ; \
} else \
( ( void ) 0 )
2019-02-20 21:59:03 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures an unsigned integer index ` m_index ` is less than ` m_size ` .
* If not , prints ` m_msg ` and the current function returns ` m_retval ` .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
if ( unlikely ( ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , DEBUG_STR ( m_msg ) ) ; \
return m_retval ; \
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_UNSIGNED_INDEX_MSG ` or ` ERR_FAIL_UNSIGNED_INDEX_V_MSG ` .
* Only use this macro if there is no sensible fallback i . e . the error is unrecoverable , and
* there is no sensible error message .
*
* Ensures an unsigned integer index ` m_index ` is less than ` m_size ` .
* If not , the application crashes .
*/
2020-02-08 08:35:52 +01:00
# define CRASH_BAD_UNSIGNED_INDEX(m_index, m_size) \
if ( unlikely ( ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , " " , true ) ; \
GENERATE_TRAP ( ) ; \
} else \
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_UNSIGNED_INDEX_MSG ` or ` ERR_FAIL_UNSIGNED_INDEX_V_MSG ` .
* Only use this macro if there is no sensible fallback i . e . the error is unrecoverable .
*
* Ensures an unsigned integer index ` m_index ` is less than ` m_size ` .
* If not , prints ` m_msg ` and the application crashes .
*/
2020-02-08 08:35:52 +01:00
# define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
if ( unlikely ( ( m_index ) > = ( m_size ) ) ) { \
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , DEBUG_STR ( m_msg ) , true ) ; \
GENERATE_TRAP ( ) ; \
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
// Null reference error macros.
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_NULL_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures a pointer ` m_param ` is not null .
* If it is null , the current function returns .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_NULL(m_param) \
2020-06-12 20:37:47 +02:00
if ( unlikely ( m_param = = nullptr ) ) { \
2020-02-08 08:35:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " ) ; \
return ; \
} else \
( ( void ) 0 )
2017-03-05 16:44:50 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures a pointer ` m_param ` is not null .
* If it is null , prints ` m_msg ` and the current function returns .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_NULL_MSG(m_param, m_msg) \
2020-06-12 20:37:47 +02:00
if ( unlikely ( m_param = = nullptr ) ) { \
2020-02-08 08:35:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " , DEBUG_STR ( m_msg ) ) ; \
return ; \
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_NULL_V_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures a pointer ` m_param ` is not null .
* If it is null , the current function returns ` m_retval ` .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_NULL_V(m_param, m_retval) \
2020-06-12 20:37:47 +02:00
if ( unlikely ( m_param = = nullptr ) ) { \
2020-02-08 08:35:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " ) ; \
return m_retval ; \
} else \
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures a pointer ` m_param ` is not null .
* If it is null , prints ` m_msg ` and the current function returns ` m_retval ` .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \
2020-06-12 20:37:47 +02:00
if ( unlikely ( m_param = = nullptr ) ) { \
2020-02-08 08:35:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " , DEBUG_STR ( m_msg ) ) ; \
return m_retval ; \
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_MSG ` .
* Only use this macro if there is no sensible error message .
* If checking for null use ERR_FAIL_NULL_MSG instead .
* If checking index bounds use ERR_FAIL_INDEX_MSG instead .
*
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , the current function returns .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_COND(m_cond) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. " ) ; \
return ; \
} else \
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , prints ` m_msg ` and the current function returns .
*
* If checking for null use ERR_FAIL_NULL_MSG instead .
* If checking index bounds use ERR_FAIL_INDEX_MSG instead .
*/
2020-02-08 08:35:52 +01:00
# define ERR_FAIL_COND_MSG(m_cond, m_msg) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. " , DEBUG_STR ( m_msg ) ) ; \
return ; \
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_V_MSG ` .
* Only use this macro if there is no sensible error message .
* If checking for null use ERR_FAIL_NULL_V_MSG instead .
* If checking index bounds use ERR_FAIL_INDEX_V_MSG instead .
*
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , the current function returns ` m_retval ` .
*/
2020-05-15 17:48:09 +02:00
# define ERR_FAIL_COND_V(m_cond, m_retval) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Returning: " _STR ( m_retval ) ) ; \
return m_retval ; \
} else \
2020-02-08 08:35:52 +01:00
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , prints ` m_msg ` and the current function returns ` m_retval ` .
*
* If checking for null use ERR_FAIL_NULL_V_MSG instead .
* If checking index bounds use ERR_FAIL_INDEX_V_MSG instead .
*/
2020-05-15 17:48:09 +02:00
# define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Returning: " _STR ( m_retval ) , DEBUG_STR ( m_msg ) ) ; \
return m_retval ; \
} else \
2020-02-08 08:35:52 +01:00
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_CONTINUE_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , the current loop continues .
*/
2020-02-08 08:35:52 +01:00
# define ERR_CONTINUE(m_cond) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Continuing. " ) ; \
continue ; \
} else \
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , prints ` m_msg ` and the current loop continues .
*/
2020-02-08 08:35:52 +01:00
# define ERR_CONTINUE_MSG(m_cond, m_msg) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Continuing. " , DEBUG_STR ( m_msg ) ) ; \
continue ; \
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_BREAK_MSG ` .
* Only use this macro if there is no sensible error message .
*
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , the current loop breaks .
*/
2020-02-08 08:35:52 +01:00
# define ERR_BREAK(m_cond) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Breaking. " ) ; \
break ; \
} else \
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , prints ` m_msg ` and the current loop breaks .
*/
2020-02-08 08:35:52 +01:00
# define ERR_BREAK_MSG(m_cond, m_msg) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Breaking. " , DEBUG_STR ( m_msg ) ) ; \
break ; \
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_MSG ` or ` ERR_FAIL_COND_V_MSG ` .
* Only use this macro if there is no sensible fallback i . e . the error is unrecoverable , and
* there is no sensible error message .
*
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , the application crashes .
*/
2020-02-08 08:35:52 +01:00
# define CRASH_COND(m_cond) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " FATAL: Condition \" " _STR ( m_cond ) " \" is true. " ) ; \
GENERATE_TRAP ( ) ; \
} else \
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_MSG ` or ` ERR_FAIL_COND_V_MSG ` .
* Only use this macro if there is no sensible fallback i . e . the error is unrecoverable .
*
* Ensures ` m_cond ` is false .
* If ` m_cond ` is true , prints ` m_msg ` and the application crashes .
*/
2020-02-08 08:35:52 +01:00
# define CRASH_COND_MSG(m_cond, m_msg) \
if ( unlikely ( m_cond ) ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " FATAL: Condition \" " _STR ( m_cond ) " \" is true. " , DEBUG_STR ( m_msg ) ) ; \
GENERATE_TRAP ( ) ; \
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2019-11-06 08:38:23 +01:00
// Generic error macros.
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_MSG ` or ` ERR_FAIL_MSG ` .
* Only use this macro if more complex error detection or recovery is required , and
* there is no sensible error message .
*
* The current function returns .
*/
2019-11-06 08:38:23 +01:00
# define ERR_FAIL() \
2020-02-08 08:35:52 +01:00
if ( 1 ) { \
2020-05-15 17:48:09 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/function failed. " ) ; \
2019-11-06 08:38:23 +01:00
return ; \
2020-02-08 08:35:52 +01:00
} else \
( ( void ) 0 )
2017-05-26 21:11:16 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_MSG ` .
* Only use this macro if more complex error detection or recovery is required .
*
* Prints ` m_msg ` , and the current function returns .
*/
2019-11-06 08:38:23 +01:00
# define ERR_FAIL_MSG(m_msg) \
2020-02-08 08:35:52 +01:00
if ( 1 ) { \
2020-05-15 17:48:09 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/function failed. " , DEBUG_STR ( m_msg ) ) ; \
2019-11-06 08:38:23 +01:00
return ; \
2020-02-08 08:35:52 +01:00
} else \
( ( void ) 0 )
2017-05-26 21:11:16 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_V_MSG ` or ` ERR_FAIL_V_MSG ` .
* Only use this macro if more complex error detection or recovery is required , and
* there is no sensible error message .
*
* The current function returns ` m_retval ` .
*/
2020-03-11 21:01:02 +01:00
# define ERR_FAIL_V(m_retval) \
if ( 1 ) { \
2020-05-15 17:48:09 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/function failed. Returning: " _STR ( m_retval ) ) ; \
2020-03-11 21:01:02 +01:00
return m_retval ; \
} else \
2020-02-08 08:35:52 +01:00
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_V_MSG ` .
* Only use this macro if more complex error detection or recovery is required .
*
* Prints ` m_msg ` , and the current function returns ` m_retval ` .
*/
2020-03-11 21:01:02 +01:00
# define ERR_FAIL_V_MSG(m_retval, m_msg) \
if ( 1 ) { \
2020-05-15 17:48:09 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/function failed. Returning: " _STR ( m_retval ) , DEBUG_STR ( m_msg ) ) ; \
2020-03-11 21:01:02 +01:00
return m_retval ; \
} else \
2020-02-08 08:35:52 +01:00
( ( void ) 0 )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Try using ` ERR_FAIL_COND_MSG ` , ` ERR_FAIL_COND_V_MSG ` , ` ERR_CONTINUE_MSG ` or ERR_BREAK_MSG .
* Only use this macro at the start of a function that has not been implemented yet , or
* if more complex error detection or recovery is required .
*
* Prints ` m_msg ` .
*/
2020-02-08 08:35:52 +01:00
# define ERR_PRINT(m_msg) \
2020-05-01 14:34:23 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_msg )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Prints ` m_msg ` once during the application lifetime .
*/
2020-05-01 14:34:23 +02:00
# define ERR_PRINT_ONCE(m_msg) \
if ( 1 ) { \
static bool first_print = true ; \
if ( first_print ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_msg ) ; \
first_print = false ; \
} \
} else \
2020-02-08 08:35:52 +01:00
( ( void ) 0 )
2019-03-01 20:01:21 +01:00
2019-11-06 08:38:23 +01:00
// Print warning message macros.
2020-02-05 14:39:12 +01:00
/**
* Prints ` m_msg ` .
*
* If warning about deprecated usage , use ` WARN_DEPRECATED ` or ` WARN_DEPRECATED_MSG ` instead .
*/
2020-02-08 08:35:52 +01:00
# define WARN_PRINT(m_msg) \
2020-05-01 14:34:23 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_msg , ERR_HANDLER_WARNING )
2014-02-10 02:10:30 +01:00
2020-02-05 14:39:12 +01:00
/**
* Prints ` m_msg ` once during the application lifetime .
*
* If warning about deprecated usage , use ` WARN_DEPRECATED ` or ` WARN_DEPRECATED_MSG ` instead .
*/
2020-05-01 14:34:23 +02:00
# define WARN_PRINT_ONCE(m_msg) \
if ( 1 ) { \
static bool first_print = true ; \
if ( first_print ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_msg , ERR_HANDLER_WARNING ) ; \
first_print = false ; \
} \
} else \
2020-02-08 08:35:52 +01:00
( ( void ) 0 )
2019-03-01 20:01:21 +01:00
2019-11-06 08:38:23 +01:00
// Print deprecated warning message macros.
2020-02-05 14:39:12 +01:00
/**
* Warns that the current function is deprecated .
*/
# define WARN_DEPRECATED \
2020-02-08 08:35:52 +01:00
if ( 1 ) { \
2020-02-05 14:39:12 +01:00
static volatile bool warning_shown = false ; \
if ( ! warning_shown ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " This method has been deprecated and will be removed in the future. " , ERR_HANDLER_WARNING ) ; \
2020-02-05 14:39:12 +01:00
warning_shown = true ; \
} \
2020-02-08 08:35:52 +01:00
} else \
( ( void ) 0 )
2019-11-07 10:37:44 +01:00
2020-02-05 14:39:12 +01:00
/**
* Warns that the current function is deprecated and prints ` m_msg ` .
*/
# define WARN_DEPRECATED_MSG(m_msg) \
2020-02-08 08:35:52 +01:00
if ( 1 ) { \
2020-02-05 14:39:12 +01:00
static volatile bool warning_shown = false ; \
if ( ! warning_shown ) { \
2019-11-06 08:38:23 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " This method has been deprecated and will be removed in the future. " , DEBUG_STR ( m_msg ) , ERR_HANDLER_WARNING ) ; \
2020-02-05 14:39:12 +01:00
warning_shown = true ; \
} \
2020-02-08 08:35:52 +01:00
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
2020-02-05 14:39:12 +01:00
/**
* Do not use .
* If the application should never reach this point use CRASH_NOW_MSG ( m_msg ) to explain why .
*
* The application crashes .
*/
2019-11-06 08:38:23 +01:00
# define CRASH_NOW() \
2020-02-08 08:35:52 +01:00
if ( 1 ) { \
2020-05-15 17:48:09 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " FATAL: Method/function failed. " ) ; \
2019-11-06 08:38:23 +01:00
GENERATE_TRAP ( ) ; \
2020-02-08 08:35:52 +01:00
} else \
( ( void ) 0 )
2019-11-06 08:38:23 +01:00
2020-02-05 14:39:12 +01:00
/**
* Only use if the application should never reach this point .
*
* Prints ` m_msg ` , and then the application crashes .
*/
2019-11-06 08:38:23 +01:00
# define CRASH_NOW_MSG(m_msg) \
2020-02-08 08:35:52 +01:00
if ( 1 ) { \
2020-05-15 17:48:09 +02:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " FATAL: Method/function failed. " , DEBUG_STR ( m_msg ) ) ; \
2019-11-06 08:38:23 +01:00
GENERATE_TRAP ( ) ; \
2020-02-08 08:35:52 +01:00
} else \
( ( void ) 0 )
2019-07-28 17:00:50 +02:00
2020-03-25 11:10:34 +01:00
# endif // ERROR_MACROS_H