Program Listing for File error_handling.h
↰ Return to documentation for file (include/rcutils/error_handling.h
)
// 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 <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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_