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 | |
19 | #define FMT_HEADER_ONLY | |
20 | #include <vendor/fmt/core.h> | |
21 | DIAGNOSTIC_POP | |
22 | ||
830bc993 JG |
23 | #include <common/make-unique-wrapper.hpp> |
24 | ||
11bcbf89 JG |
25 | /* |
26 | * Due to a bug in g++ < 7.1, this specialization must be enclosed in the fmt namespace, | |
27 | * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480. | |
28 | */ | |
e2c2bec2 | 29 | namespace fmt { |
5bb4ff54 | 30 | template <> |
e2c2bec2 | 31 | struct formatter<std::type_info> : formatter<std::string> { |
31375c42 JG |
32 | template <typename FormatContextType> |
33 | typename FormatContextType::iterator format(const std::type_info& type_info, | |
34 | FormatContextType& ctx) | |
5bb4ff54 JG |
35 | { |
36 | int status; | |
830bc993 JG |
37 | /* |
38 | * The documentation of __cxa_demangle mentions the returned string is allocated | |
303ac4ed | 39 | * using malloc (not new), hence the use of lttng::memory::free. |
830bc993 | 40 | */ |
303ac4ed | 41 | const auto demangled_name = lttng::make_unique_wrapper<char, lttng::memory::free>( |
830bc993 | 42 | abi::__cxa_demangle(type_info.name(), nullptr, nullptr, &status)); |
5bb4ff54 | 43 | |
830bc993 JG |
44 | auto it = status == 0 ? formatter<std::string>::format(demangled_name.get(), ctx) : |
45 | formatter<std::string>::format(type_info.name(), ctx); | |
5bb4ff54 JG |
46 | return it; |
47 | } | |
48 | }; | |
e2c2bec2 | 49 | } /* namespace fmt */ |
5bb4ff54 | 50 | |
f9a41357 JG |
51 | namespace lttng { |
52 | template <typename... FormattingArguments> | |
53 | std::string format(FormattingArguments&&...args) | |
54 | { | |
55 | try { | |
56 | return fmt::format(std::forward<FormattingArguments>(args)...); | |
57 | } catch (const fmt::format_error& ex) { | |
58 | return std::string("Failed to format string: ") += ex.what(); | |
59 | } | |
60 | } | |
61 | } /* namespace lttng */ | |
62 | ||
05aa7e19 | 63 | #endif /* LTTNG_FORMAT_H */ |