From fed5d64b364acd0e21c0f6dbfdbd1a9ebbba62e9 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sun, 9 Apr 2023 05:52:55 -0700 Subject: [PATCH 1/3] Add convenience error handling macros Signed-off-by: methylDragon --- include/rcutils/error_handling.h | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/include/rcutils/error_handling.h b/include/rcutils/error_handling.h index 23e84fa7..7e0b25c6 100644 --- a/include/rcutils/error_handling.h +++ b/include/rcutils/error_handling.h @@ -314,6 +314,93 @@ RCUTILS_PUBLIC void rcutils_reset_error(void); +// Helper macro for nested macro expansion +#define _RCUTILS_EXPAND(x) x + +/// Set the error message, as well as append the current file, line number, and previous error. +/** + * If there is no previous error, has same behavior as RCUTILS_SET_ERROR_MSG. + * \param[in] msg The error message to be set. + */ +#define RCUTILS_SET_ERROR_MSG_AND_APPEND_PREV_ERROR(msg) \ + do { \ + if (rcutils_error_is_set()) { \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ + _RCUTILS_EXPAND(msg ":\n%s"), error_string.str); \ + } else { \ + RCUTILS_SET_ERROR_MSG(msg); \ + } \ + } while (0) + +/// Set the error message using a format string, format arguments, and previous error. +/** + * This function sets the error message using the given format string, and appends and resets the + * latest error string. + * The resulting formatted string is silently truncated at RCUTILS_ERROR_MESSAGE_MAX_LENGTH. + * + * If there is no previous error, has same behavior as RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING. + * + * \param[in] format_string The string to be used as the format of the error message. + * \param[in] ... Arguments for the format string. + */ +#define RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING_AND_APPEND_PREV_ERROR(format_string, ...) \ + do { \ + if (rcutils_error_is_set()) { \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ + _RCUTILS_EXPAND(format_string ":\n%s"), __VA_ARGS__, error_string.str); \ + } else { \ + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ + } \ + } while (0) + +/// Write the given msg out to stderr, limiting the buffer size in the `fwrite`, appending the +/// previous error. +/** + * This will reset the previous error, if it exists. + * If there is no previous error, has same behavior as RCUTILS_SAFE_FWRITE_TO_STDERR. + */ +#define RCUTILS_SAFE_FWRITE_TO_STDERR_AND_APPEND_PREV_ERROR(msg) \ + do { \ + if (rcutils_error_is_set()) { \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING( \ + _RCUTILS_EXPAND(msg ":\n%s"), error_string.str); \ + } else { \ + RCUTILS_SAFE_FWRITE_TO_STDERR(msg); \ + } \ + } while (0) + +/// Set the error message to stderr using a format string and format arguments, appending the +/// previous error. +/** + * This function sets the error message to stderr using the given format string, appending and + * resetting the previous error.. + * The resulting formatted string is silently truncated at RCUTILS_ERROR_MESSAGE_MAX_LENGTH. + * + * This will reset the previous error, if it exists. + * If there is no previous error, has same behavior as + * RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING. + * + * \param[in] format_string The string to be used as the format of the error message. + * \param[in] ... Arguments for the format string. + */ +#define RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING_AND_APPEND_PREV_ERROR(format_string, ...) \ + do { \ + if (rcutils_error_is_set()) { \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING( \ + _RCUTILS_EXPAND(format_string ":\n%s"), __VA_ARGS__, error_string.str); \ + } else { \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ + } \ + } while (0) + #ifdef __cplusplus } #endif From 8f93decff4e6a539158284c1dd1e598a32d1fd4a Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sun, 9 Apr 2023 13:33:08 -0700 Subject: [PATCH 2/3] Refine error handling macros Signed-off-by: methylDragon --- include/rcutils/error_handling.h | 26 ++++++++++++++------------ include/rcutils/macros.h | 2 ++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/include/rcutils/error_handling.h b/include/rcutils/error_handling.h index 7e0b25c6..25c0250d 100644 --- a/include/rcutils/error_handling.h +++ b/include/rcutils/error_handling.h @@ -314,10 +314,7 @@ RCUTILS_PUBLIC void rcutils_reset_error(void); -// Helper macro for nested macro expansion -#define _RCUTILS_EXPAND(x) x - -/// Set the error message, as well as append the current file, line number, and previous error. +/// Set the error message using RCUTILS_SET_ERROR_MSG and append the previous error. /** * If there is no previous error, has same behavior as RCUTILS_SET_ERROR_MSG. * \param[in] msg The error message to be set. @@ -328,13 +325,15 @@ rcutils_reset_error(void); rcutils_error_string_t error_string = rcutils_get_error_string(); \ rcutils_reset_error(); \ RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ - _RCUTILS_EXPAND(msg ":\n%s"), error_string.str); \ + RCUTILS_EXPAND(msg ": %s"), error_string.str); \ } else { \ + RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ RCUTILS_SET_ERROR_MSG(msg); \ } \ } while (0) -/// Set the error message using a format string, format arguments, and previous error. +/// Set the error message with RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING and append the previous +/// error. /** * This function sets the error message using the given format string, and appends and resets the * latest error string. @@ -351,8 +350,9 @@ rcutils_reset_error(void); rcutils_error_string_t error_string = rcutils_get_error_string(); \ rcutils_reset_error(); \ RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ - _RCUTILS_EXPAND(format_string ":\n%s"), __VA_ARGS__, error_string.str); \ + RCUTILS_EXPAND(format_string ": %s"), __VA_ARGS__, error_string.str); \ } else { \ + RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ } \ } while (0) @@ -368,9 +368,10 @@ rcutils_reset_error(void); if (rcutils_error_is_set()) { \ rcutils_error_string_t error_string = rcutils_get_error_string(); \ rcutils_reset_error(); \ - RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING( \ - _RCUTILS_EXPAND(msg ":\n%s"), error_string.str); \ + RCUTILS_SAFE_FWRITE_TO_STDERR(msg); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(": %s", error_string.str); \ } else { \ + RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ RCUTILS_SAFE_FWRITE_TO_STDERR(msg); \ } \ } while (0) @@ -379,7 +380,7 @@ rcutils_reset_error(void); /// previous error. /** * This function sets the error message to stderr using the given format string, appending and - * resetting the previous error.. + * resetting the previous error. * The resulting formatted string is silently truncated at RCUTILS_ERROR_MESSAGE_MAX_LENGTH. * * This will reset the previous error, if it exists. @@ -394,9 +395,10 @@ rcutils_reset_error(void); if (rcutils_error_is_set()) { \ rcutils_error_string_t error_string = rcutils_get_error_string(); \ rcutils_reset_error(); \ - RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING( \ - _RCUTILS_EXPAND(format_string ":\n%s"), __VA_ARGS__, error_string.str); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(": %s", error_string.str); \ } else { \ + RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ } \ } while (0) diff --git a/include/rcutils/macros.h b/include/rcutils/macros.h index bf6325a1..c18d36ea 100644 --- a/include/rcutils/macros.h +++ b/include/rcutils/macros.h @@ -64,6 +64,8 @@ extern "C" #define RCUTILS_THREAD_LOCAL _Thread_local #endif +// Helper macros for nested macro expansion +#define RCUTILS_EXPAND(x) x #define RCUTILS_STRINGIFY_IMPL(x) #x #define RCUTILS_STRINGIFY(x) RCUTILS_STRINGIFY_IMPL(x) From 0bd97d4d8dc8079749bbaf58d81d4dcafea682bb Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sun, 9 Apr 2023 23:49:43 -0700 Subject: [PATCH 3/3] Remove conditional in error handling macros Signed-off-by: methylDragon --- include/rcutils/error_handling.h | 52 ++++++++++---------------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/include/rcutils/error_handling.h b/include/rcutils/error_handling.h index 25c0250d..ee5667aa 100644 --- a/include/rcutils/error_handling.h +++ b/include/rcutils/error_handling.h @@ -321,15 +321,10 @@ rcutils_reset_error(void); */ #define RCUTILS_SET_ERROR_MSG_AND_APPEND_PREV_ERROR(msg) \ do { \ - if (rcutils_error_is_set()) { \ - rcutils_error_string_t error_string = rcutils_get_error_string(); \ - rcutils_reset_error(); \ - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ - RCUTILS_EXPAND(msg ": %s"), error_string.str); \ - } else { \ - RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ - RCUTILS_SET_ERROR_MSG(msg); \ - } \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ + RCUTILS_EXPAND(msg ": %s"), error_string.str); \ } while (0) /// Set the error message with RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING and append the previous @@ -346,15 +341,10 @@ rcutils_reset_error(void); */ #define RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING_AND_APPEND_PREV_ERROR(format_string, ...) \ do { \ - if (rcutils_error_is_set()) { \ - rcutils_error_string_t error_string = rcutils_get_error_string(); \ - rcutils_reset_error(); \ - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ - RCUTILS_EXPAND(format_string ": %s"), __VA_ARGS__, error_string.str); \ - } else { \ - RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ - } \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \ + RCUTILS_EXPAND(format_string ": %s"), __VA_ARGS__, error_string.str); \ } while (0) /// Write the given msg out to stderr, limiting the buffer size in the `fwrite`, appending the @@ -365,15 +355,10 @@ rcutils_reset_error(void); */ #define RCUTILS_SAFE_FWRITE_TO_STDERR_AND_APPEND_PREV_ERROR(msg) \ do { \ - if (rcutils_error_is_set()) { \ - rcutils_error_string_t error_string = rcutils_get_error_string(); \ - rcutils_reset_error(); \ - RCUTILS_SAFE_FWRITE_TO_STDERR(msg); \ - RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(": %s", error_string.str); \ - } else { \ - RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ - RCUTILS_SAFE_FWRITE_TO_STDERR(msg); \ - } \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SAFE_FWRITE_TO_STDERR(msg); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(": %s", error_string.str); \ } while (0) /// Set the error message to stderr using a format string and format arguments, appending the @@ -392,15 +377,10 @@ rcutils_reset_error(void); */ #define RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING_AND_APPEND_PREV_ERROR(format_string, ...) \ do { \ - if (rcutils_error_is_set()) { \ - rcutils_error_string_t error_string = rcutils_get_error_string(); \ - rcutils_reset_error(); \ - RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ - RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(": %s", error_string.str); \ - } else { \ - RCUTILS_SAFE_FWRITE_TO_STDERR("No previous error set\n"); \ - RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ - } \ + rcutils_error_string_t error_string = rcutils_get_error_string(); \ + rcutils_reset_error(); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \ + RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(": %s", error_string.str); \ } while (0) #ifdef __cplusplus