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 #define RMW_TRY_PLACEMENT_NEW(Destination, BufferForNew, FailureAction, Type, ...) \
30  try { \
31  Destination = new(BufferForNew) Type(__VA_ARGS__); \
32  } catch (const std::exception & exception) { \
33  RMW_SET_ERROR_MSG( \
34  ( \
35  std::string("caught C++ exception ") + rmw::impl::cpp::demangle(exception) + \
36  " constructing " #Type ": " + exception.what() \
37  ).c_str()); \
38  FailureAction; \
39  } catch (...) { \
40  RMW_SET_ERROR_MSG("caught unknown C++ exception constructing " #Type); \
41  FailureAction; \
42  }
43 
44 #define RMW_TRY_DESTRUCTOR(Statement, Type, FailureAction) \
45  try { \
46  Statement; \
47  } catch (const std::exception & exception) { \
48  RMW_SET_ERROR_MSG( \
49  ( \
50  std::string("caught C++ exception in destructor of " #Type ": ") + \
51  rmw::impl::cpp::demangle(exception) + ": " + exception.what() \
52  ).c_str()); \
53  FailureAction; \
54  } catch (...) { \
55  RMW_SET_ERROR_MSG("caught unknown C++ exception in destructor of " #Type); \
56  FailureAction; \
57  }
58 
59 #define RMW_TRY_DESTRUCTOR_FROM_WITHIN_FAILURE(Statement, Type) \
60  try { \
61  Statement; \
62  } catch (const std::exception & exception) { \
63  std::stringstream ss; \
64  ss << "caught C++ exception in destructor of " #Type " while handling a failure: " \
65  << rmw::impl::cpp::demangle(exception) << ": " << exception.what() \
66  << ", at: " << __FILE__ << ":" << __LINE__ << '\n'; \
67  (std::cerr << ss.str()).flush(); \
68  } catch (...) { \
69  std::stringstream ss; \
70  ss << "caught unknown C++ exception in destructor of " #Type << \
71  " while handling a failure at: " << __FILE__ << ":" << __LINE__ << '\n'; \
72  (std::cerr << ss.str()).flush(); \
73  }
74 
75 #if RMW_AVOID_MEMORY_ALLOCATION
76 #define RMW_CHECK_TYPE_IDENTIFIERS_MATCH(ElementName, ElementTypeID, ExpectedTypeID, OnFailure) \
77  { \
78  if (ElementTypeID != ExpectedTypeID) { \
79  char __msg[1024]; \
80  rcutils_snprintf( \
81  __msg, 1024, \
82  #ElementName " implementation '%s'(%p) does not match rmw implementation '%s'(%p)", \
83  ElementTypeID, reinterpret_cast<const void *>(ElementTypeID), \
84  ExpectedTypeID, reinterpret_cast<const void *>(ExpectedTypeID)); \
85  RMW_SET_ERROR_MSG(__msg); \
86  OnFailure; \
87  } \
88  }
89 #else // RMW_AVOID_MEMORY_ALLOCATION
90 #define RMW_CHECK_TYPE_IDENTIFIERS_MATCH(ElementName, ElementTypeID, ExpectedTypeID, OnFailure) \
91  { \
92  if (ElementTypeID != ExpectedTypeID) { \
93  size_t __bytes_that_would_have_been_written = rcutils_snprintf( \
94  NULL, 0, \
95  #ElementName " implementation '%s'(%p) does not match rmw implementation '%s'(%p)", \
96  ElementTypeID, reinterpret_cast<const void *>(ElementTypeID), \
97  ExpectedTypeID, reinterpret_cast<const void *>(ExpectedTypeID)); \
98  char * __msg = \
99  reinterpret_cast<char *>(rmw_allocate(__bytes_that_would_have_been_written + 1)); \
100  rcutils_snprintf( \
101  __msg, __bytes_that_would_have_been_written + 1, \
102  #ElementName " implementation '%s'(%p) does not match rmw implementation '%s'(%p)", \
103  ElementTypeID, reinterpret_cast<const void *>(ElementTypeID), \
104  ExpectedTypeID, reinterpret_cast<const void *>(ExpectedTypeID)); \
105  RMW_SET_ERROR_MSG(__msg); \
106  rmw_free(__msg); \
107  OnFailure; \
108  } \
109  }
110 #endif // RMW_AVOID_MEMORY_ALLOCATION
111 
112 #endif // RMW__IMPL__CPP__MACROS_HPP_