rmw  master
C API providing a middleware abstraction layer which is used to implement the rest of ROS.
macros.hpp
Go to the documentation of this file.
1 // Copyright 2015 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RMW__IMPL__CPP__MACROS_HPP_
16 #define RMW__IMPL__CPP__MACROS_HPP_
17 
18 #include <iostream>
19 #include <sstream>
20 #include <string>
21 
22 #include "rcutils/snprintf.h"
23 
24 #include "rmw/allocators.h"
25 #include "rmw/error_handling.h"
26 #include "rmw/impl/config.h" // For RMW_AVOID_MEMORY_ALLOCATION
27 #include "rmw/impl/cpp/demangle.hpp" // For demangle.
28 
29 // *INDENT-OFF* (prevent uncrustify from using four space indention here)
30 #define RMW_TRY_PLACEMENT_NEW(Destination, BufferForNew, FailureAction, Type, ...) try { \
31  Destination = new(BufferForNew) Type(__VA_ARGS__); \
32 } catch(const std::exception & exception) { \
33  RMW_SET_ERROR_MSG(( \
34  std::string("caught C++ exception ") + rmw::impl::cpp::demangle(exception) + \
35  " constructing " #Type ": " + exception.what() \
36  ).c_str()); \
37  FailureAction; \
38 } catch(...) { \
39  RMW_SET_ERROR_MSG("caught unknown C++ exception constructing " #Type); \
40  FailureAction; \
41 }
42 
43 #define RMW_TRY_DESTRUCTOR(Statement, Type, FailureAction) try { \
44  Statement; \
45 } catch(const std::exception & exception) { \
46  RMW_SET_ERROR_MSG(( \
47  std::string("caught C++ exception in destructor of " #Type ": ") + \
48  rmw::impl::cpp::demangle(exception) + ": " + exception.what() \
49  ).c_str()); \
50  FailureAction; \
51 } catch(...) { \
52  RMW_SET_ERROR_MSG("caught unknown C++ exception in destructor of " #Type); \
53  FailureAction; \
54 }
55 
56 #define RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE(Statement, Type) try { \
57  Statement; \
58 } catch(const std::exception & exception) { \
59  std::stringstream ss; \
60  ss << "caught C++ exception in destructor of " #Type " while handling a failure: " \
61  << rmw::impl::cpp::demangle(exception) << ": " << exception.what() \
62  << ", at: " << __FILE__ << ":" << __LINE__ << '\n'; \
63  (std::cerr << ss.str()).flush(); \
64 } catch(...) { \
65  std::stringstream ss; \
66  ss << "caught unknown C++ exception in destructor of " #Type \
67  << " while handling a failure at: " << __FILE__ << ":" << __LINE__ << '\n'; \
68  (std::cerr << ss.str()).flush(); \
69 }
70 
71 #if RMW_AVOID_MEMORY_ALLOCATION
72 #define RMW_CHECK_TYPE_IDENTIFIERS_MATCH(ElementName, ElementTypeID, ExpectedTypeID, OnFailure) { \
73  if (ElementTypeID != ExpectedTypeID) { \
74  char __msg[1024]; \
75  rcutils_snprintf( \
76  __msg, 1024, \
77  #ElementName " implementation '%s'(%p) does not match rmw implementation '%s'(%p)", \
78  ElementTypeID, reinterpret_cast<const void *>(ElementTypeID), \
79  ExpectedTypeID, reinterpret_cast<const void *>(ExpectedTypeID)); \
80  RMW_SET_ERROR_MSG(__msg); \
81  OnFailure; \
82  } \
83 }
84 #else // RMW_AVOID_MEMORY_ALLOCATION
85 #define RMW_CHECK_TYPE_IDENTIFIERS_MATCH(ElementName, ElementTypeID, ExpectedTypeID, OnFailure) { \
86  if (ElementTypeID != ExpectedTypeID) { \
87  size_t __bytes_that_would_have_been_written = rcutils_snprintf( \
88  NULL, 0, \
89  #ElementName " implementation '%s'(%p) does not match rmw implementation '%s'(%p)", \
90  ElementTypeID, reinterpret_cast<const void *>(ElementTypeID), \
91  ExpectedTypeID, reinterpret_cast<const void *>(ExpectedTypeID)); \
92  char * __msg = \
93  reinterpret_cast<char *>(rmw_allocate(__bytes_that_would_have_been_written + 1)); \
94  rcutils_snprintf( \
95  __msg, __bytes_that_would_have_been_written + 1, \
96  #ElementName " implementation '%s'(%p) does not match rmw implementation '%s'(%p)", \
97  ElementTypeID, reinterpret_cast<const void *>(ElementTypeID), \
98  ExpectedTypeID, reinterpret_cast<const void *>(ExpectedTypeID)); \
99  RMW_SET_ERROR_MSG(__msg); \
100  rmw_free(__msg); \
101  OnFailure; \
102  } \
103 }
104 #endif // RMW_AVOID_MEMORY_ALLOCATION
105 // *INDENT-ON*
106 
107 #endif // RMW__IMPL__CPP__MACROS_HPP_