@@ -314,6 +314,93 @@ RCUTILS_PUBLIC
314
314
void
315
315
rcutils_reset_error (void );
316
316
317
+ // Helper macro for nested macro expansion
318
+ #define _RCUTILS_EXPAND (x ) x
319
+
320
+ /// Set the error message, as well as append the current file, line number, and previous error.
321
+ /**
322
+ * If there is no previous error, has same behavior as RCUTILS_SET_ERROR_MSG.
323
+ * \param[in] msg The error message to be set.
324
+ */
325
+ #define RCUTILS_SET_ERROR_MSG_AND_APPEND_PREV_ERROR (msg ) \
326
+ do { \
327
+ if (rcutils_error_is_set()) { \
328
+ rcutils_error_string_t error_string = rcutils_get_error_string(); \
329
+ rcutils_reset_error(); \
330
+ RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \
331
+ _RCUTILS_EXPAND(msg ":\n%s"), error_string.str); \
332
+ } else { \
333
+ RCUTILS_SET_ERROR_MSG(msg); \
334
+ } \
335
+ } while (0)
336
+
337
+ /// Set the error message using a format string, format arguments, and previous error.
338
+ /**
339
+ * This function sets the error message using the given format string, and appends and resets the
340
+ * latest error string.
341
+ * The resulting formatted string is silently truncated at RCUTILS_ERROR_MESSAGE_MAX_LENGTH.
342
+ *
343
+ * If there is no previous error, has same behavior as RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING.
344
+ *
345
+ * \param[in] format_string The string to be used as the format of the error message.
346
+ * \param[in] ... Arguments for the format string.
347
+ */
348
+ #define RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING_AND_APPEND_PREV_ERROR (format_string , ...) \
349
+ do { \
350
+ if (rcutils_error_is_set()) { \
351
+ rcutils_error_string_t error_string = rcutils_get_error_string(); \
352
+ rcutils_reset_error(); \
353
+ RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( \
354
+ _RCUTILS_EXPAND(format_string ":\n%s"), __VA_ARGS__, error_string.str); \
355
+ } else { \
356
+ RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \
357
+ } \
358
+ } while (0)
359
+
360
+ /// Write the given msg out to stderr, limiting the buffer size in the `fwrite`, appending the
361
+ /// previous error.
362
+ /**
363
+ * This will reset the previous error, if it exists.
364
+ * If there is no previous error, has same behavior as RCUTILS_SAFE_FWRITE_TO_STDERR.
365
+ */
366
+ #define RCUTILS_SAFE_FWRITE_TO_STDERR_AND_APPEND_PREV_ERROR (msg ) \
367
+ do { \
368
+ if (rcutils_error_is_set()) { \
369
+ rcutils_error_string_t error_string = rcutils_get_error_string(); \
370
+ rcutils_reset_error(); \
371
+ RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING( \
372
+ _RCUTILS_EXPAND(msg ":\n%s"), error_string.str); \
373
+ } else { \
374
+ RCUTILS_SAFE_FWRITE_TO_STDERR(msg); \
375
+ } \
376
+ } while (0)
377
+
378
+ /// Set the error message to stderr using a format string and format arguments, appending the
379
+ /// previous error.
380
+ /**
381
+ * This function sets the error message to stderr using the given format string, appending and
382
+ * resetting the previous error..
383
+ * The resulting formatted string is silently truncated at RCUTILS_ERROR_MESSAGE_MAX_LENGTH.
384
+ *
385
+ * This will reset the previous error, if it exists.
386
+ * If there is no previous error, has same behavior as
387
+ * RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING.
388
+ *
389
+ * \param[in] format_string The string to be used as the format of the error message.
390
+ * \param[in] ... Arguments for the format string.
391
+ */
392
+ #define RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING_AND_APPEND_PREV_ERROR (format_string , ...) \
393
+ do { \
394
+ if (rcutils_error_is_set()) { \
395
+ rcutils_error_string_t error_string = rcutils_get_error_string(); \
396
+ rcutils_reset_error(); \
397
+ RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING( \
398
+ _RCUTILS_EXPAND(format_string ":\n%s"), __VA_ARGS__, error_string.str); \
399
+ } else { \
400
+ RCUTILS_SAFE_FWRITE_TO_STDERR_WITH_FORMAT_STRING(format_string, __VA_ARGS__); \
401
+ } \
402
+ } while (0)
403
+
317
404
#ifdef __cplusplus
318
405
}
319
406
#endif
0 commit comments