2014-02-09 22:10:30 -03:00
/*************************************************************************/
/* error_macros.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03:00
# ifndef ERROR_MACROS_H
# define ERROR_MACROS_H
2018-09-11 18:13:45 +02:00
# include "core/typedefs.h"
2014-02-09 22:10:30 -03:00
2019-11-06 08:38:23 +01:00
class String ;
2014-02-09 22:10:30 -03:00
enum ErrorHandlerType {
ERR_HANDLER_ERROR ,
ERR_HANDLER_WARNING ,
2016-10-10 18:31:01 -03:00
ERR_HANDLER_SCRIPT ,
ERR_HANDLER_SHADER ,
2014-02-09 22:10:30 -03: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-09 22:10:30 -03:00
struct ErrorHandlerList {
ErrorHandlerFunc errfunc ;
void * userdata ;
2017-03-05 16:44:50 +01:00
ErrorHandlerList * next ;
2014-02-09 22:10:30 -03:00
2017-03-05 16:44:50 +01:00
ErrorHandlerList ( ) {
errfunc = 0 ;
next = 0 ;
userdata = 0 ;
}
2014-02-09 22:10:30 -03: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-09 22:10:30 -03: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
// Don't use this directly; instead, use any of the CRASH_* macros
# ifdef _MSC_VER
2019-11-06 08:38:23 +01:00
# define GENERATE_TRAP() __debugbreak()
2017-05-26 21:11:16 +02:00
# else
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 .
*
* Note : See https : //stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for
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.
// Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0.
// The current function returns.
2017-10-17 11:37:40 -03:00
# define ERR_FAIL_INDEX(m_index, m_size) \
do { \
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 ; \
2019-06-26 15:08:25 +02:00
} \
2019-11-06 08:38:23 +01:00
} while ( 0 ) ;
2014-02-09 22:10:30 -03:00
2019-11-13 14:07:54 +01:00
# define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \
do { \
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 ; \
} \
2019-11-06 08:38:23 +01:00
} while ( 0 ) ;
// The current function returns m_retval.
2019-07-28 17:00:50 +02:00
2017-10-17 11:37:40 -03:00
# define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \
do { \
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 ; \
2019-06-26 15:08:25 +02:00
} \
2019-11-06 08:38:23 +01:00
} while ( 0 ) ;
2017-05-26 21:11:16 +02:00
2019-11-13 14:07:54 +01:00
# define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
do { \
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 ; \
} \
2019-11-06 08:38:23 +01:00
} while ( 0 ) ;
// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
# define CRASH_BAD_INDEX(m_index, m_size) \
do { \
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 ( ) ; \
} \
} while ( 0 ) ;
# define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
do { \
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 ( ) ; \
} \
} while ( 0 ) ;
// Unsigned integer index out of bounds error macros.
// Ensures an unsigned integer index `m_index` is less than `m_size`
// The current function returns.
# define ERR_FAIL_UNSIGNED_INDEX(m_index, m_size) \
do { \
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 ; \
} \
} while ( 0 ) ;
# define ERR_FAIL_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
do { \
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 ; \
} \
} while ( 0 ) ;
// The current function returns m_retval.
2019-07-28 17:00:50 +02:00
2019-02-20 21:59:03 +01:00
# define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval) \
do { \
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 ; \
2019-06-26 15:08:25 +02:00
} \
2019-11-06 08:38:23 +01:00
} while ( 0 ) ;
2019-02-20 21:59:03 +01:00
2019-11-13 14:07:54 +01:00
# define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
do { \
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 ; \
} \
2019-11-06 08:38:23 +01:00
} while ( 0 ) ;
2019-07-28 17:00:50 +02:00
2019-11-06 08:38:23 +01:00
// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
# define CRASH_BAD_UNSIGNED_INDEX(m_index, m_size) \
2019-11-10 07:44:31 +01:00
do { \
2019-11-06 08:38:23 +01:00
if ( unlikely ( ( m_index ) > = ( m_size ) ) ) { \
2019-11-10 07:44:31 +01:00
_err_print_index_error ( FUNCTION_STR , __FILE__ , __LINE__ , m_index , m_size , _STR ( m_index ) , _STR ( m_size ) , " " , true ) ; \
2019-11-06 08:38:23 +01:00
GENERATE_TRAP ( ) ; \
2019-11-10 07:44:31 +01:00
} \
2019-11-06 08:38:23 +01:00
} while ( 0 ) ;
2014-02-09 22:10:30 -03:00
2019-11-06 08:38:23 +01:00
# define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
do { \
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 ( ) ; \
} \
} while ( 0 ) ;
// Null reference error macros.
// Ensures a pointer `m_param` is not null.
// The current function returns.
2019-07-28 17:00:50 +02:00
2017-03-05 16:44:50 +01:00
# define ERR_FAIL_NULL(m_param) \
{ \
2017-09-20 11:04:50 +02:00
if ( unlikely ( ! m_param ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " ) ; \
2017-03-05 16:44:50 +01:00
return ; \
2019-06-26 15:08:25 +02:00
} \
2017-03-05 16:44:50 +01:00
}
2019-11-13 14:07:54 +01:00
# define ERR_FAIL_NULL_MSG(m_param, m_msg) \
{ \
if ( unlikely ( ! m_param ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " , DEBUG_STR ( m_msg ) ) ; \
2019-11-13 14:07:54 +01:00
return ; \
} \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
// The current function returns m_retval.
2017-03-05 16:44:50 +01:00
# define ERR_FAIL_NULL_V(m_param, m_retval) \
{ \
2017-09-20 11:04:50 +02:00
if ( unlikely ( ! m_param ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " ) ; \
2017-03-05 16:44:50 +01:00
return m_retval ; \
2019-06-26 15:08:25 +02:00
} \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2019-11-13 14:07:54 +01:00
# define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \
{ \
if ( unlikely ( ! m_param ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Parameter \" " _STR ( m_param ) " \" is null. " , DEBUG_STR ( m_msg ) ) ; \
2019-11-13 14:07:54 +01:00
return m_retval ; \
} \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
// Error condition macros.
// Ensures that `m_cond` is not true.
// The current function returns.
2017-03-05 16:44:50 +01:00
# define ERR_FAIL_COND(m_cond) \
{ \
2017-09-20 11:04:50 +02:00
if ( unlikely ( m_cond ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. " ) ; \
2017-03-05 16:44:50 +01:00
return ; \
2019-06-26 15:08:25 +02:00
} \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2019-11-13 14:07:54 +01:00
# define ERR_FAIL_COND_MSG(m_cond, m_msg) \
{ \
if ( unlikely ( m_cond ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. " , DEBUG_STR ( m_msg ) ) ; \
2019-11-13 14:07:54 +01:00
return ; \
} \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
// The current function returns m_retval.
2019-07-28 17:00:50 +02:00
2017-03-05 16:44:50 +01:00
# define ERR_FAIL_COND_V(m_cond, m_retval) \
{ \
2017-09-20 11:04:50 +02:00
if ( unlikely ( m_cond ) ) { \
2019-11-06 08:38:23 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. returned: " _STR ( m_retval ) ) ; \
2017-03-05 16:44:50 +01:00
return m_retval ; \
2019-06-26 15:08:25 +02:00
} \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2019-11-13 14:07:54 +01:00
# define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
{ \
if ( unlikely ( m_cond ) ) { \
2019-11-06 08:38:23 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. returned: " _STR ( m_retval ) , DEBUG_STR ( m_msg ) ) ; \
2019-11-13 14:07:54 +01:00
return m_retval ; \
} \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
// The current loop continues.
2020-01-24 16:53:52 +01:00
# define ERR_CONTINUE(m_cond) \
2017-03-05 16:44:50 +01:00
{ \
2017-09-20 11:04:50 +02:00
if ( unlikely ( m_cond ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Continuing. " ) ; \
continue ; \
2019-06-26 15:08:25 +02:00
} \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2020-01-24 16:53:52 +01:00
# define ERR_CONTINUE_MSG(m_cond, m_msg) \
2019-11-13 14:07:54 +01:00
{ \
if ( unlikely ( m_cond ) ) { \
2020-01-24 16:53:52 +01:00
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Condition \" " _STR ( m_cond ) " \" is true. Continuing. " , DEBUG_STR ( m_msg ) ) ; \
continue ; \
2019-11-13 14:07:54 +01:00
} \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
// The current loop breaks.
2020-01-24 16:53: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 ; \
} \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2020-01-24 16:53: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 ; \
} \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
# 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 ( ) ; \
} \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2019-11-06 08:38:23 +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 ( ) ; \
} \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
// Generic error macros.
// The current function returns.
# define ERR_FAIL() \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/Function Failed. " ) ; \
return ; \
2020-01-24 16:53:52 +01:00
}
2017-05-26 21:11:16 +02:00
2019-11-06 08:38:23 +01:00
# define ERR_FAIL_MSG(m_msg) \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/Function Failed. " , DEBUG_STR ( m_msg ) ) ; \
return ; \
2017-05-26 21:11:16 +02:00
}
2019-11-06 08:38:23 +01:00
// The current function returns m_retval.
# define ERR_FAIL_V(m_retval) \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/Function Failed, returning: " __STR ( m_value ) ) ; \
return m_retval ; \
2019-07-28 17:00:50 +02:00
}
2019-11-06 08:38:23 +01:00
# define ERR_FAIL_V_MSG(m_value, m_msg) \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " Method/Function Failed, returning: " __STR ( m_value ) , DEBUG_STR ( m_msg ) ) ; \
return m_value ; \
2020-01-24 16:53:52 +01:00
}
2014-02-09 22:10:30 -03:00
2019-11-06 08:38:23 +01:00
// Print error message macros.
# define ERR_PRINT(m_msg) \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , DEBUG_STR ( m_msg ) ) ; \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2019-11-06 08:38:23 +01:00
// Only prints the error message once.
# define ERR_PRINT_ONCE(m_msg) \
{ \
static bool first_print = true ; \
if ( first_print ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , DEBUG_STR ( m_msg ) ) ; \
first_print = false ; \
} \
2019-03-01 16:01:21 -03:00
}
2019-11-06 08:38:23 +01:00
// Print warning message macros.
// To warn about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
# define WARN_PRINT(m_msg) \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , DEBUG_STR ( m_msg ) , ERR_HANDLER_WARNING ) ; \
2017-03-05 16:44:50 +01:00
}
2014-02-09 22:10:30 -03:00
2019-11-06 08:38:23 +01:00
// Only prints the warning message once.
# define WARN_PRINT_ONCE(m_msg) \
{ \
static bool first_print = true ; \
if ( first_print ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , DEBUG_STR ( m_msg ) , ERR_HANDLER_WARNING ) ; \
first_print = false ; \
} \
2019-03-01 16:01:21 -03:00
}
2019-11-06 08:38:23 +01:00
// Print deprecated warning message macros.
// Only prints the warning message once.
2020-01-24 16:53:52 +01:00
# define WARN_DEPRECATED \
{ \
static volatile bool warning_shown = false ; \
if ( ! warning_shown ) { \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " This method has been deprecated and will be removed in the future. " , ERR_HANDLER_WARNING ) ; \
warning_shown = true ; \
} \
2018-04-18 09:10:25 -03:00
}
2019-11-06 08:38:23 +01:00
# define WARN_DEPRECATED_MSG(m_msg) \
{ \
static volatile bool warning_shown = false ; \
if ( ! warning_shown ) { \
_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 ) ; \
warning_shown = true ; \
} \
}
// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
# define CRASH_NOW() \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " FATAL: Method/Function Failed. " ) ; \
GENERATE_TRAP ( ) ; \
}
# define CRASH_NOW_MSG(m_msg) \
{ \
_err_print_error ( FUNCTION_STR , __FILE__ , __LINE__ , " FATAL: Method/Function Failed. " , DEBUG_STR ( m_msg ) ) ; \
GENERATE_TRAP ( ) ; \
2019-07-28 17:00:50 +02:00
}
2014-02-09 22:10:30 -03:00
# endif