Commit | Line | Data |
---|---|---|
05aa7e19 JG |
1 | /* |
2 | * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: LGPL-2.1-only | |
5 | * | |
6 | */ | |
7 | #ifndef LTTNG_FORMAT_H | |
8 | #define LTTNG_FORMAT_H | |
9 | ||
10 | #include <common/macros.hpp> | |
11 | ||
5bb4ff54 | 12 | #include <cxxabi.h> |
28f23191 | 13 | #include <string> |
f9a41357 | 14 | #include <utility> |
5bb4ff54 | 15 | |
05aa7e19 JG |
16 | DIAGNOSTIC_PUSH |
17 | DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT | |
18 | DIAGNOSTIC_IGNORE_DUPLICATED_BRANCHES | |
05aa7e19 JG |
19 | #include <vendor/fmt/core.h> |
20 | DIAGNOSTIC_POP | |
21 | ||
830bc993 JG |
22 | #include <common/make-unique-wrapper.hpp> |
23 | ||
11bcbf89 JG |
24 | /* |
25 | * Due to a bug in g++ < 7.1, this specialization must be enclosed in the fmt namespace, | |
26 | * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480. | |
27 | */ | |
e2c2bec2 | 28 | namespace fmt { |
5bb4ff54 | 29 | template <> |
e2c2bec2 | 30 | struct formatter<std::type_info> : formatter<std::string> { |
31375c42 JG |
31 | template <typename FormatContextType> |
32 | typename FormatContextType::iterator format(const std::type_info& type_info, | |
bd9231e4 | 33 | FormatContextType& ctx) const |
5bb4ff54 JG |
34 | { |
35 | int status; | |
830bc993 JG |
36 | /* |
37 | * The documentation of __cxa_demangle mentions the returned string is allocated | |
303ac4ed | 38 | * using malloc (not new), hence the use of lttng::memory::free. |
830bc993 | 39 | */ |
303ac4ed | 40 | const auto demangled_name = lttng::make_unique_wrapper<char, lttng::memory::free>( |
830bc993 | 41 | abi::__cxa_demangle(type_info.name(), nullptr, nullptr, &status)); |
5bb4ff54 | 42 | |
830bc993 JG |
43 | auto it = status == 0 ? formatter<std::string>::format(demangled_name.get(), ctx) : |
44 | formatter<std::string>::format(type_info.name(), ctx); | |
5bb4ff54 JG |
45 | return it; |
46 | } | |
47 | }; | |
e2c2bec2 | 48 | } /* namespace fmt */ |
5bb4ff54 | 49 | |
f9a41357 JG |
50 | namespace lttng { |
51 | template <typename... FormattingArguments> | |
52 | std::string format(FormattingArguments&&...args) | |
53 | { | |
54 | try { | |
55 | return fmt::format(std::forward<FormattingArguments>(args)...); | |
56 | } catch (const fmt::format_error& ex) { | |
57 | return std::string("Failed to format string: ") += ex.what(); | |
58 | } | |
59 | } | |
60 | } /* namespace lttng */ | |
61 | ||
05aa7e19 | 62 | #endif /* LTTNG_FORMAT_H */ |