.. _program_listing_file_include_rcutils_error_handling.h: Program Listing for File error_handling.h ========================================= |exhale_lsh| :ref:`Return to documentation for file ` (``include/rcutils/error_handling.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Copyright 2014 Open Source Robotics Foundation, Inc. // // Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef RCUTILS__ERROR_HANDLING_H_ #define RCUTILS__ERROR_HANDLING_H_ #ifdef __cplusplus extern "C" { #endif #ifndef __STDC_WANT_LIB_EXT1__ #define __STDC_WANT_LIB_EXT1__ 1 // indicate we would like strnlen_s if available #endif #include #include #include #include #include #include #include #include "rcutils/allocator.h" #include "rcutils/macros.h" #include "rcutils/snprintf.h" #include "rcutils/testing/fault_injection.h" #include "rcutils/types/rcutils_ret.h" #include "rcutils/visibility_control.h" #ifdef __STDC_LIB_EXT1__ #define RCUTILS_SAFE_FWRITE_TO_STDERR(msg) \ do {fwrite(msg, sizeof(char), strnlen_s(msg, 4096), stderr);} while (0) #else #define RCUTILS_SAFE_FWRITE_TO_STDERR(msg) \ do {fwrite(msg, sizeof(char), strlen(msg), stderr);} while (0) #endif #define RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, ...) \ do { \ char output_msg[RCUTILS_ERROR_MESSAGE_MAX_LENGTH]; \ int ret = rcutils_snprintf(output_msg, sizeof(output_msg), format_string, __VA_ARGS__); \ if (ret < 0) { \ RCUTILS_SAFE_FWRITE_TO_STDERR("Failed to call snprintf for error message formatting\n"); \ } else { \ RCUTILS_SAFE_FWRITE_TO_STDERR(output_msg); \ } \ } while (0) #define RCUTILS_ERROR_STATE_LINE_NUMBER_STR_MAX_LENGTH 20 // "18446744073709551615" #define RCUTILS_ERROR_FORMATTING_CHARACTERS 6 // ', at ' + ':' #define RCUTILS_ERROR_MESSAGE_MAX_LENGTH 1024 #define RCUTILS_ERROR_STATE_MESSAGE_MAX_LENGTH 768 #define RCUTILS_ERROR_STATE_FILE_MAX_LENGTH ( \ RCUTILS_ERROR_MESSAGE_MAX_LENGTH - \ RCUTILS_ERROR_STATE_MESSAGE_MAX_LENGTH - \ RCUTILS_ERROR_STATE_LINE_NUMBER_STR_MAX_LENGTH - \ RCUTILS_ERROR_FORMATTING_CHARACTERS - \ 1) typedef struct rcutils_error_string_s { char str[RCUTILS_ERROR_MESSAGE_MAX_LENGTH]; } rcutils_error_string_t; typedef struct rcutils_error_state_s { char message[RCUTILS_ERROR_STATE_MESSAGE_MAX_LENGTH]; char file[RCUTILS_ERROR_STATE_FILE_MAX_LENGTH]; uint64_t line_number; } rcutils_error_state_t; // make sure our math is right... #if __STDC_VERSION__ >= 201112L static_assert( sizeof(rcutils_error_string_t) == ( RCUTILS_ERROR_STATE_MESSAGE_MAX_LENGTH + RCUTILS_ERROR_STATE_FILE_MAX_LENGTH + RCUTILS_ERROR_STATE_LINE_NUMBER_STR_MAX_LENGTH + RCUTILS_ERROR_FORMATTING_CHARACTERS + 1 /* null terminating character */), "Maximum length calculations incorrect"); #endif RCUTILS_PUBLIC RCUTILS_WARN_UNUSED rcutils_ret_t rcutils_initialize_error_handling_thread_local_storage(rcutils_allocator_t allocator); RCUTILS_PUBLIC void rcutils_set_error_state(const char * error_string, const char * file, size_t line_number); #define RCUTILS_CHECK_ARGUMENT_FOR_NULL(argument, error_return_type) \ RCUTILS_CHECK_FOR_NULL_WITH_MSG( \ argument, #argument " argument is null", \ return error_return_type) #define RCUTILS_CHECK_FOR_NULL_WITH_MSG(value, msg, error_statement) \ do { \ if (NULL == value) { \ RCUTILS_SET_ERROR_MSG(msg); \ error_statement; \ } \ } while (0) #define RCUTILS_SET_ERROR_MSG(msg) \ do {rcutils_set_error_state(msg, __FILE__, __LINE__);} while (0) #define RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(format_string, ...) \ do { \ char output_msg[RCUTILS_ERROR_MESSAGE_MAX_LENGTH]; \ int ret = rcutils_snprintf(output_msg, sizeof(output_msg), format_string, __VA_ARGS__); \ if (ret < 0) { \ RCUTILS_SAFE_FWRITE_TO_STDERR("Failed to call snprintf for error message formatting\n"); \ } else { \ RCUTILS_SET_ERROR_MSG(output_msg); \ } \ } while (0) #define RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(error_return_value) \ RCUTILS_CAN_FAIL_WITH( \ { \ RCUTILS_SET_ERROR_MSG("Injecting " RCUTILS_STRINGIFY(error_return_value)); \ return error_return_value; \ }) RCUTILS_PUBLIC RCUTILS_WARN_UNUSED bool rcutils_error_is_set(void); RCUTILS_PUBLIC RCUTILS_WARN_UNUSED const rcutils_error_state_t * rcutils_get_error_state(void); RCUTILS_PUBLIC RCUTILS_WARN_UNUSED rcutils_error_string_t rcutils_get_error_string(void); RCUTILS_PUBLIC void rcutils_reset_error(void); #ifdef __cplusplus } #endif #endif // RCUTILS__ERROR_HANDLING_H_